Skip to content

Commit 816e359

Browse files
dgchinnerChandan Babu R
authored andcommitted
xfs: don't free post-EOF blocks on read close
When we have a workload that does open/read/close in parallel with other allocation, the file becomes rapidly fragmented. This is due to close() calling xfs_file_release() and removing the speculative preallocation beyond EOF. Add a check for a writable context to xfs_file_release to skip the post-EOF block freeing (an the similarly pointless flushing on truncate down). Before: Test 1: sync write fragmentation counts /mnt/scratch/file.0: 919 /mnt/scratch/file.1: 916 /mnt/scratch/file.2: 919 /mnt/scratch/file.3: 920 /mnt/scratch/file.4: 920 /mnt/scratch/file.5: 921 /mnt/scratch/file.6: 916 /mnt/scratch/file.7: 918 After: Test 1: sync write fragmentation counts /mnt/scratch/file.0: 24 /mnt/scratch/file.1: 24 /mnt/scratch/file.2: 11 /mnt/scratch/file.3: 24 /mnt/scratch/file.4: 3 /mnt/scratch/file.5: 24 /mnt/scratch/file.6: 24 /mnt/scratch/file.7: 23 Signed-off-by: Dave Chinner <dchinner@redhat.com> [darrick: wordsmithing, fix commit message] Signed-off-by: Darrick J. Wong <djwong@kernel.org> [hch: ported to the new ->release code structure] Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>
1 parent c741d79 commit 816e359

1 file changed

Lines changed: 7 additions & 1 deletion

File tree

fs/xfs/xfs_file.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1217,12 +1217,18 @@ xfs_file_release(
12171217
* There is no point in freeing blocks here for open but unlinked files
12181218
* as they will be taken care of by the inactivation path soon.
12191219
*
1220+
* When releasing a read-only context, don't flush data or trim post-EOF
1221+
* blocks. This avoids open/read/close workloads from removing EOF
1222+
* blocks that other writers depend upon to reduce fragmentation.
1223+
*
12201224
* If we can't get the iolock just skip truncating the blocks past EOF
12211225
* because we could deadlock with the mmap_lock otherwise. We'll get
12221226
* another chance to drop them once the last reference to the inode is
12231227
* dropped, so we'll never leak blocks permanently.
12241228
*/
1225-
if (inode->i_nlink && xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) {
1229+
if (inode->i_nlink &&
1230+
(file->f_mode & FMODE_WRITE) &&
1231+
xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) {
12261232
if (xfs_can_free_eofblocks(ip) &&
12271233
!xfs_iflags_test(ip, XFS_IDIRTY_RELEASE)) {
12281234
/*

0 commit comments

Comments
 (0)