Skip to content

Commit

Permalink
btrfs: defrag: don't try to defrag extents which are under writeback
Browse files Browse the repository at this point in the history
commit 0d1ffa2 upstream.

Once we start writeback (have called btrfs_run_delalloc_range()), we
allocate an extent, create an extent map point to that extent, with a
generation of (u64)-1, created the ordered extent and then clear the
DELALLOC bit from the range in the inode's io tree.

Such extent map can pass the first call of defrag_collect_targets(), as
its generation is (u64)-1, meets any possible minimal generation check.
And the range will not have DELALLOC bit, also passing the DELALLOC bit
check.

It will only be re-checked in the second call of
defrag_collect_targets(), which will wait for writeback.

But at that stage we have already spent our time waiting for some IO we
may or may not want to defrag.

Let's reject such extents early so we won't waste our time.

CC: stable@vger.kernel.org # 5.16
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
adam900710 authored and gregkh committed Feb 23, 2022
1 parent 685de07 commit 103b772
Showing 1 changed file with 4 additions and 0 deletions.
4 changes: 4 additions & 0 deletions fs/btrfs/ioctl.c
Expand Up @@ -1184,6 +1184,10 @@ static int defrag_collect_targets(struct btrfs_inode *inode,
if (em->generation < newer_than)
goto next;

/* This em is under writeback, no need to defrag */
if (em->generation == (u64)-1)
goto next;

/*
* Our start offset might be in the middle of an existing extent
* map, so take that into account.
Expand Down

0 comments on commit 103b772

Please sign in to comment.