Skip to content

Commit 27cdfde

Browse files
fdmananakdave
authored andcommitted
btrfs: update writeback index when starting defrag
When starting a defrag, we should update the writeback index of the inode's mapping in case it currently has a value beyond the start of the range we are defragging. This can help performance and often result in getting less extents after writeback - for e.g., if the current value of the writeback index sits somewhere in the middle of a range that gets dirty by the defrag, then after writeback we can get two smaller extents instead of a single, larger extent. We used to have this before the refactoring in 5.16, but it was removed without any reason to do so. Originally it was added in kernel 3.1, by commit 2a0f7f5 ("Btrfs: fix recursive auto-defrag"), in order to fix a loop with autodefrag resulting in dirtying and writing pages over and over, but some testing on current code did not show that happening, at least with the test described in that commit. So add back the behaviour, as at the very least it is a nice to have optimization. Fixes: 7b50803 ("btrfs: defrag: use defrag_one_cluster() to implement btrfs_defrag_file()") CC: [email protected] # 5.16 Signed-off-by: Filipe Manana <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 3c9d31c commit 27cdfde

File tree

1 file changed

+9
-0
lines changed

1 file changed

+9
-0
lines changed

fs/btrfs/ioctl.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1537,6 +1537,7 @@ int btrfs_defrag_file(struct inode *inode, struct file_ra_state *ra,
15371537
int compress_type = BTRFS_COMPRESS_ZLIB;
15381538
int ret = 0;
15391539
u32 extent_thresh = range->extent_thresh;
1540+
pgoff_t start_index;
15401541

15411542
if (isize == 0)
15421543
return 0;
@@ -1578,6 +1579,14 @@ int btrfs_defrag_file(struct inode *inode, struct file_ra_state *ra,
15781579
file_ra_state_init(ra, inode->i_mapping);
15791580
}
15801581

1582+
/*
1583+
* Make writeback start from the beginning of the range, so that the
1584+
* defrag range can be written sequentially.
1585+
*/
1586+
start_index = cur >> PAGE_SHIFT;
1587+
if (start_index < inode->i_mapping->writeback_index)
1588+
inode->i_mapping->writeback_index = start_index;
1589+
15811590
while (cur < last_byte) {
15821591
const unsigned long prev_sectors_defragged = sectors_defragged;
15831592
u64 cluster_end;

0 commit comments

Comments
 (0)