Skip to content

Commit 3c941eb

Browse files
djwongSomasundaram Krishnasamy
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: 30898008 Signed-off-by: Junxiao Bi <[email protected]> Reviewed-by: Darrick J. Wong <[email protected]> Signed-off-by: Somasundaram Krishnasamy <[email protected]>
1 parent e804ce4 commit 3c941eb

File tree

3 files changed

+83
-60
lines changed

3 files changed

+83
-60
lines changed

fs/xfs/xfs_bmap_util.c

Lines changed: 46 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -815,78 +815,64 @@ xfs_free_eofblocks(
815815
struct xfs_inode *ip)
816816
{
817817
struct xfs_trans *tp;
818-
int error;
819-
xfs_fileoff_t end_fsb;
820-
xfs_fileoff_t last_fsb;
821-
xfs_filblks_t map_len;
822-
int nimaps;
823-
struct xfs_bmbt_irec imap;
824818
struct xfs_mount *mp = ip->i_mount;
819+
bool has;
820+
int error;
825821

826822
/*
827-
* Figure out if there are any blocks beyond the end
828-
* of the file. If not, then there is nothing to do.
823+
* If there are blocks after the end of file, truncate the file to its
824+
* current size to free them up.
829825
*/
830-
end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_ISIZE(ip));
831-
last_fsb = XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes);
832-
if (last_fsb <= end_fsb)
833-
return 0;
834-
map_len = last_fsb - end_fsb;
835-
836-
nimaps = 1;
837-
xfs_ilock(ip, XFS_ILOCK_SHARED);
838-
error = xfs_bmapi_read(ip, end_fsb, map_len, &imap, &nimaps, 0);
839-
xfs_iunlock(ip, XFS_ILOCK_SHARED);
826+
error = xfs_has_eofblocks(ip, &has);
827+
if (error || !has)
828+
return error;
840829

841830
/*
842-
* If there are blocks after the end of file, truncate the file to its
843-
* current size to free them up.
831+
* Attach the dquots to the inode up front.
844832
*/
845-
if (!error && (nimaps != 0) &&
846-
(imap.br_startblock != HOLESTARTBLOCK ||
847-
ip->i_delayed_blks)) {
848-
/*
849-
* Attach the dquots to the inode up front.
850-
*/
851-
error = xfs_qm_dqattach(ip, 0);
852-
if (error)
853-
return error;
833+
error = xfs_qm_dqattach(ip, 0);
834+
if (error)
835+
return error;
854836

855-
/* wait on dio to ensure i_size has settled */
856-
inode_dio_wait(VFS_I(ip));
837+
/* wait on dio to ensure i_size has settled */
838+
inode_dio_wait(VFS_I(ip));
857839

858-
error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0,
859-
&tp);
860-
if (error) {
861-
ASSERT(XFS_FORCED_SHUTDOWN(mp));
862-
return error;
863-
}
840+
error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0,
841+
&tp);
842+
if (error) {
843+
ASSERT(XFS_FORCED_SHUTDOWN(mp));
844+
return error;
845+
}
864846

865-
xfs_ilock(ip, XFS_ILOCK_EXCL);
866-
xfs_trans_ijoin(tp, ip, 0);
847+
xfs_ilock(ip, XFS_ILOCK_EXCL);
848+
xfs_trans_ijoin(tp, ip, 0);
867849

868-
/*
869-
* Do not update the on-disk file size. If we update the
870-
* on-disk file size and then the system crashes before the
871-
* contents of the file are flushed to disk then the files
872-
* may be full of holes (ie NULL files bug).
873-
*/
874-
error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK,
875-
XFS_ISIZE(ip));
876-
if (error) {
877-
/*
878-
* If we get an error at this point we simply don't
879-
* bother truncating the file.
880-
*/
881-
xfs_trans_cancel(tp);
882-
} else {
883-
error = xfs_trans_commit(tp);
884-
if (!error)
885-
xfs_inode_clear_eofblocks_tag(ip);
886-
}
850+
/*
851+
* Do not update the on-disk file size. If we update the
852+
* on-disk file size and then the system crashes before the
853+
* contents of the file are flushed to disk then the files
854+
* may be full of holes (ie NULL files bug).
855+
*/
856+
error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK,
857+
XFS_ISIZE(ip));
858+
if (error)
859+
goto err_cancel;
887860

888-
xfs_iunlock(ip, XFS_ILOCK_EXCL);
889-
}
861+
error = xfs_trans_commit(tp);
862+
if (error)
863+
goto out_unlock;
864+
865+
xfs_inode_clear_eofblocks_tag(ip);
866+
goto out_unlock;
867+
868+
err_cancel:
869+
/*
870+
* If we get an error at this point we simply don't
871+
* bother truncating the file.
872+
*/
873+
xfs_trans_cancel(tp);
874+
out_unlock:
875+
xfs_iunlock(ip, XFS_ILOCK_EXCL);
890876
return error;
891877
}
892878

fs/xfs/xfs_inode.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3673,3 +3673,39 @@ xfs_iflush_int(
36733673
corrupt_out:
36743674
return -EFSCORRUPTED;
36753675
}
3676+
3677+
/*
3678+
* Decide if this inode have post-EOF blocks. The caller is responsible
3679+
* for knowing / caring about the PREALLOC/APPEND flags.
3680+
*/
3681+
int
3682+
xfs_has_eofblocks(
3683+
struct xfs_inode *ip,
3684+
bool *has)
3685+
{
3686+
struct xfs_bmbt_irec imap;
3687+
struct xfs_mount *mp = ip->i_mount;
3688+
xfs_fileoff_t end_fsb;
3689+
xfs_fileoff_t last_fsb;
3690+
xfs_filblks_t map_len;
3691+
int nimaps;
3692+
int error;
3693+
3694+
*has = false;
3695+
end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_ISIZE(ip));
3696+
last_fsb = XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes);
3697+
if (last_fsb <= end_fsb)
3698+
return 0;
3699+
map_len = last_fsb - end_fsb;
3700+
3701+
nimaps = 1;
3702+
xfs_ilock(ip, XFS_ILOCK_SHARED);
3703+
error = xfs_bmapi_read(ip, end_fsb, map_len, &imap, &nimaps, 0);
3704+
xfs_iunlock(ip, XFS_ILOCK_SHARED);
3705+
3706+
if (error || nimaps == 0)
3707+
return error;
3708+
3709+
*has = imap.br_startblock != HOLESTARTBLOCK || ip->i_delayed_blks;
3710+
return 0;
3711+
}

fs/xfs/xfs_inode.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,5 +509,6 @@ extern struct kmem_zone *xfs_inode_zone;
509509
#define XFS_DEFAULT_COWEXTSZ_HINT 32
510510

511511
bool xfs_inode_verify_forks(struct xfs_inode *ip);
512+
int xfs_has_eofblocks(struct xfs_inode *ip, bool *has);
512513

513514
#endif /* __XFS_INODE_H__ */

0 commit comments

Comments
 (0)