Skip to content

Commit 65a3cac

Browse files
biger410Brian Maly
authored andcommitted
xfs: refactor the predicate part of xfs_free_eofblocks
Refactor the part of _free_eofblocks that decides if it's really going to truncate post-EOF blocks into a separate helper function. The upcoming deferred inode inactivation patch requires us to be able to decide this prior to actual inactivation. No functionality changes. Signed-off-by: Darrick J. Wong <[email protected]> (cherry picked from commit 5dab4f336f751de084ec2e915d2244086fec3559) cherry-pick-repo=kernel/git/djwong/xfs-linux.git Orabug: 30944736 Signed-off-by: Junxiao Bi <[email protected]> Reviewed-by: Darrick J. Wong <[email protected]> Signed-off-by: Brian Maly <[email protected]>
1 parent 1bd34ad commit 65a3cac

File tree

3 files changed

+92
-70
lines changed

3 files changed

+92
-70
lines changed

fs/xfs/xfs_bmap_util.c

Lines changed: 55 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -863,91 +863,76 @@ xfs_free_eofblocks(
863863
bool need_iolock)
864864
{
865865
xfs_trans_t *tp;
866+
bool has;
866867
int error;
867-
xfs_fileoff_t end_fsb;
868-
xfs_fileoff_t last_fsb;
869-
xfs_filblks_t map_len;
870-
int nimaps;
871-
xfs_bmbt_irec_t imap;
872868

873869
/*
874-
* Figure out if there are any blocks beyond the end
875-
* of the file. If not, then there is nothing to do.
870+
* If there are blocks after the end of file, truncate the file to its
871+
* current size to free them up.
876872
*/
877-
end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_ISIZE(ip));
878-
last_fsb = XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes);
879-
if (last_fsb <= end_fsb)
880-
return 0;
881-
map_len = last_fsb - end_fsb;
882-
883-
nimaps = 1;
884-
xfs_ilock(ip, XFS_ILOCK_SHARED);
885-
error = xfs_bmapi_read(ip, end_fsb, map_len, &imap, &nimaps, 0);
886-
xfs_iunlock(ip, XFS_ILOCK_SHARED);
887-
888-
if (!error && (nimaps != 0) &&
889-
(imap.br_startblock != HOLESTARTBLOCK ||
890-
ip->i_delayed_blks)) {
891-
/*
892-
* Attach the dquots to the inode up front.
893-
*/
894-
error = xfs_qm_dqattach(ip, 0);
895-
if (error)
896-
return error;
873+
error = xfs_has_eofblocks(ip, &has);
874+
if (error || !has)
875+
return error;
897876

898-
/* wait on dio to ensure i_size has settled */
899-
inode_dio_wait(VFS_I(ip));
877+
/*
878+
* Attach the dquots to the inode up front.
879+
*/
880+
error = xfs_qm_dqattach(ip, 0);
881+
if (error)
882+
return error;
900883

901-
/*
902-
* There are blocks after the end of file.
903-
* Free them up now by truncating the file to
904-
* its current size.
905-
*/
906-
tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE);
884+
/* wait on dio to ensure i_size has settled */
885+
inode_dio_wait(VFS_I(ip));
907886

908-
if (need_iolock) {
909-
if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) {
910-
xfs_trans_cancel(tp);
911-
return -EAGAIN;
912-
}
913-
}
887+
/*
888+
* There are blocks after the end of file.
889+
* Free them up now by truncating the file to
890+
* its current size.
891+
*/
892+
tp = xfs_trans_alloc(mp, XFS_TRANS_INACTIVE);
914893

915-
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0);
916-
if (error) {
917-
ASSERT(XFS_FORCED_SHUTDOWN(mp));
894+
if (need_iolock) {
895+
if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) {
918896
xfs_trans_cancel(tp);
919-
if (need_iolock)
920-
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
921-
return error;
897+
return -EAGAIN;
922898
}
899+
}
923900

924-
xfs_ilock(ip, XFS_ILOCK_EXCL);
925-
xfs_trans_ijoin(tp, ip, 0);
901+
error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0);
902+
if (error) {
903+
ASSERT(XFS_FORCED_SHUTDOWN(mp));
904+
xfs_trans_cancel(tp);
905+
if (need_iolock)
906+
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
907+
return error;
908+
}
909+
910+
xfs_ilock(ip, XFS_ILOCK_EXCL);
911+
xfs_trans_ijoin(tp, ip, 0);
926912

913+
/*
914+
* Do not update the on-disk file size. If we update the
915+
* on-disk file size and then the system crashes before the
916+
* contents of the file are flushed to disk then the files
917+
* may be full of holes (ie NULL files bug).
918+
*/
919+
error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK,
920+
XFS_ISIZE(ip));
921+
if (error) {
927922
/*
928-
* Do not update the on-disk file size. If we update the
929-
* on-disk file size and then the system crashes before the
930-
* contents of the file are flushed to disk then the files
931-
* may be full of holes (ie NULL files bug).
923+
* If we get an error at this point we simply don't
924+
* bother truncating the file.
932925
*/
933-
error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK,
934-
XFS_ISIZE(ip));
935-
if (error) {
936-
/*
937-
* If we get an error at this point we simply don't
938-
* bother truncating the file.
939-
*/
940-
xfs_trans_cancel(tp);
941-
} else {
942-
error = xfs_trans_commit(tp);
943-
if (!error)
944-
xfs_inode_clear_eofblocks_tag(ip);
945-
}
946-
947-
xfs_iunlock(ip, XFS_ILOCK_EXCL);
948-
if (need_iolock)
949-
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
926+
xfs_trans_cancel(tp);
927+
} else {
928+
error = xfs_trans_commit(tp);
929+
if (!error)
930+
xfs_inode_clear_eofblocks_tag(ip);
950931
}
932+
933+
xfs_iunlock(ip, XFS_ILOCK_EXCL);
934+
if (need_iolock)
935+
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
951936
return error;
952937
}
953938

fs/xfs/xfs_inode.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3511,3 +3511,39 @@ xfs_iflush_int(
35113511
corrupt_out:
35123512
return -EFSCORRUPTED;
35133513
}
3514+
3515+
/*
3516+
* Decide if this inode have post-EOF blocks. The caller is responsible
3517+
* for knowing / caring about the PREALLOC/APPEND flags.
3518+
*/
3519+
int
3520+
xfs_has_eofblocks(
3521+
struct xfs_inode *ip,
3522+
bool *has)
3523+
{
3524+
struct xfs_bmbt_irec imap;
3525+
struct xfs_mount *mp = ip->i_mount;
3526+
xfs_fileoff_t end_fsb;
3527+
xfs_fileoff_t last_fsb;
3528+
xfs_filblks_t map_len;
3529+
int nimaps;
3530+
int error;
3531+
3532+
*has = false;
3533+
end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_ISIZE(ip));
3534+
last_fsb = XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes);
3535+
if (last_fsb <= end_fsb)
3536+
return 0;
3537+
map_len = last_fsb - end_fsb;
3538+
3539+
nimaps = 1;
3540+
xfs_ilock(ip, XFS_ILOCK_SHARED);
3541+
error = xfs_bmapi_read(ip, end_fsb, map_len, &imap, &nimaps, 0);
3542+
xfs_iunlock(ip, XFS_ILOCK_SHARED);
3543+
3544+
if (error || nimaps == 0)
3545+
return error;
3546+
3547+
*has = imap.br_startblock != HOLESTARTBLOCK || ip->i_delayed_blks;
3548+
return 0;
3549+
}

fs/xfs/xfs_inode.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@ int xfs_update_prealloc_flags(struct xfs_inode *ip,
404404
int xfs_zero_eof(struct xfs_inode *ip, xfs_off_t offset,
405405
xfs_fsize_t isize, bool *did_zeroing);
406406
int xfs_iozero(struct xfs_inode *ip, loff_t pos, size_t count);
407+
int xfs_has_eofblocks(struct xfs_inode *ip, bool *has);
407408

408409

409410
/* from xfs_iops.c */

0 commit comments

Comments
 (0)