Skip to content

Commit

Permalink
btrfs: add back missing dirty page rate limiting to defrag
Browse files Browse the repository at this point in the history
A defrag operation can dirty a lot of pages, specially if operating on
the entire file or a large file range. Any task dirtying pages should
periodically call balance_dirty_pages_ratelimited(), as stated in that
function's comments, otherwise they can leave too many dirty pages in
the system. This is what we did before the refactoring in 5.16, and
it should have remained, just like in the buffered write path and
relocation. So restore that behaviour.

Fixes: 7b50803 ("btrfs: defrag: use defrag_one_cluster() to implement btrfs_defrag_file()")
CC: stable@vger.kernel.org # 5.16
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
  • Loading branch information
Filipe Manana authored and David Sterba committed Jan 24, 2022
1 parent 0cb5950 commit 3c9d31c
Showing 1 changed file with 5 additions and 0 deletions.
5 changes: 5 additions & 0 deletions fs/btrfs/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1579,6 +1579,7 @@ int btrfs_defrag_file(struct inode *inode, struct file_ra_state *ra,
}

while (cur < last_byte) {
const unsigned long prev_sectors_defragged = sectors_defragged;
u64 cluster_end;

/* The cluster size 256K should always be page aligned */
Expand Down Expand Up @@ -1610,6 +1611,10 @@ int btrfs_defrag_file(struct inode *inode, struct file_ra_state *ra,
cluster_end + 1 - cur, extent_thresh,
newer_than, do_compress,
&sectors_defragged, max_to_defrag);

if (sectors_defragged > prev_sectors_defragged)
balance_dirty_pages_ratelimited(inode->i_mapping);

btrfs_inode_unlock(inode, 0);
if (ret < 0)
break;
Expand Down

0 comments on commit 3c9d31c

Please sign in to comment.