Skip to content

Commit 610b291

Browse files
Christoph HellwigChandan Babu R
authored andcommitted
xfs: fix freeing speculative preallocations for preallocated files
xfs_can_free_eofblocks returns false for files that have persistent preallocations unless the force flag is passed and there are delayed blocks. This means it won't free delalloc reservations for files with persistent preallocations unless the force flag is set, and it will also free the persistent preallocations if the force flag is set and the file happens to have delayed allocations. Both of these are bad, so do away with the force flag and always free only post-EOF delayed allocations for files with the XFS_DIFLAG_PREALLOC or APPEND flags set. Signed-off-by: Christoph Hellwig <[email protected]> Reviewed-by: Darrick J. Wong <[email protected]> Signed-off-by: Chandan Babu R <[email protected]>
1 parent f266106 commit 610b291

File tree

4 files changed

+28
-20
lines changed

4 files changed

+28
-20
lines changed

fs/xfs/xfs_bmap_util.c

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -486,13 +486,11 @@ xfs_bmap_punch_delalloc_range(
486486

487487
/*
488488
* Test whether it is appropriate to check an inode for and free post EOF
489-
* blocks. The 'force' parameter determines whether we should also consider
490-
* regular files that are marked preallocated or append-only.
489+
* blocks.
491490
*/
492491
bool
493492
xfs_can_free_eofblocks(
494-
struct xfs_inode *ip,
495-
bool force)
493+
struct xfs_inode *ip)
496494
{
497495
struct xfs_bmbt_irec imap;
498496
struct xfs_mount *mp = ip->i_mount;
@@ -526,11 +524,11 @@ xfs_can_free_eofblocks(
526524
return false;
527525

528526
/*
529-
* Do not free real preallocated or append-only files unless the file
530-
* has delalloc blocks and we are forced to remove them.
527+
* Only free real extents for inodes with persistent preallocations or
528+
* the append-only flag.
531529
*/
532530
if (ip->i_diflags & (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND))
533-
if (!force || ip->i_delayed_blks == 0)
531+
if (ip->i_delayed_blks == 0)
534532
return false;
535533

536534
/*
@@ -584,6 +582,22 @@ xfs_free_eofblocks(
584582
/* Wait on dio to ensure i_size has settled. */
585583
inode_dio_wait(VFS_I(ip));
586584

585+
/*
586+
* For preallocated files only free delayed allocations.
587+
*
588+
* Note that this means we also leave speculative preallocations in
589+
* place for preallocated files.
590+
*/
591+
if (ip->i_diflags & (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)) {
592+
if (ip->i_delayed_blks) {
593+
xfs_bmap_punch_delalloc_range(ip,
594+
round_up(XFS_ISIZE(ip), mp->m_sb.sb_blocksize),
595+
LLONG_MAX);
596+
}
597+
xfs_inode_clear_eofblocks_tag(ip);
598+
return 0;
599+
}
600+
587601
error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
588602
if (error) {
589603
ASSERT(xfs_is_shutdown(mp));
@@ -891,7 +905,7 @@ xfs_prepare_shift(
891905
* Trim eofblocks to avoid shifting uninitialized post-eof preallocation
892906
* into the accessible region of the file.
893907
*/
894-
if (xfs_can_free_eofblocks(ip, true)) {
908+
if (xfs_can_free_eofblocks(ip)) {
895909
error = xfs_free_eofblocks(ip);
896910
if (error)
897911
return error;

fs/xfs/xfs_bmap_util.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ int xfs_insert_file_space(struct xfs_inode *, xfs_off_t offset,
6363
xfs_off_t len);
6464

6565
/* EOF block manipulation functions */
66-
bool xfs_can_free_eofblocks(struct xfs_inode *ip, bool force);
66+
bool xfs_can_free_eofblocks(struct xfs_inode *ip);
6767
int xfs_free_eofblocks(struct xfs_inode *ip);
6868

6969
int xfs_swap_extents(struct xfs_inode *ip, struct xfs_inode *tip,

fs/xfs/xfs_icache.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1155,7 +1155,7 @@ xfs_inode_free_eofblocks(
11551155
}
11561156
*lockflags |= XFS_IOLOCK_EXCL;
11571157

1158-
if (xfs_can_free_eofblocks(ip, false))
1158+
if (xfs_can_free_eofblocks(ip))
11591159
return xfs_free_eofblocks(ip);
11601160

11611161
/* inode could be preallocated or append-only */

fs/xfs/xfs_inode.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1595,7 +1595,7 @@ xfs_release(
15951595
if (!xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL))
15961596
return 0;
15971597

1598-
if (xfs_can_free_eofblocks(ip, false)) {
1598+
if (xfs_can_free_eofblocks(ip)) {
15991599
/*
16001600
* Check if the inode is being opened, written and closed
16011601
* frequently and we have delayed allocation blocks outstanding
@@ -1856,15 +1856,13 @@ xfs_inode_needs_inactive(
18561856

18571857
/*
18581858
* This file isn't being freed, so check if there are post-eof blocks
1859-
* to free. @force is true because we are evicting an inode from the
1860-
* cache. Post-eof blocks must be freed, lest we end up with broken
1861-
* free space accounting.
1859+
* to free.
18621860
*
18631861
* Note: don't bother with iolock here since lockdep complains about
18641862
* acquiring it in reclaim context. We have the only reference to the
18651863
* inode at this point anyways.
18661864
*/
1867-
return xfs_can_free_eofblocks(ip, true);
1865+
return xfs_can_free_eofblocks(ip);
18681866
}
18691867

18701868
/*
@@ -1947,15 +1945,11 @@ xfs_inactive(
19471945

19481946
if (VFS_I(ip)->i_nlink != 0) {
19491947
/*
1950-
* force is true because we are evicting an inode from the
1951-
* cache. Post-eof blocks must be freed, lest we end up with
1952-
* broken free space accounting.
1953-
*
19541948
* Note: don't bother with iolock here since lockdep complains
19551949
* about acquiring it in reclaim context. We have the only
19561950
* reference to the inode at this point anyways.
19571951
*/
1958-
if (xfs_can_free_eofblocks(ip, true))
1952+
if (xfs_can_free_eofblocks(ip))
19591953
error = xfs_free_eofblocks(ip);
19601954

19611955
goto out;

0 commit comments

Comments
 (0)