On Tue, Mar 15, 2022 at 07:28:05PM +0800, Qu Wenruo wrote: > [BUG] > There is a report that autodefrag is defragging single sector, which > is completely waste of IO, and no help for defragging: > > btrfs-cleaner-808 defrag_one_locked_range: root=256 ino=651122 start=0 len=4096 > > [CAUSE] > In defrag_collect_targets(), we check if the current range (A) can be merged > with next one (B). > > If mergeable, we will add range A into target for defrag. > > However there is a catch for autodefrag, when checking mergebility against > range B, we intentionally pass 0 as @newer_than, hoping to get a > higher chance to merge with the next extent. > > But in next iteartion, range B will looked up by defrag_lookup_extent(), > with non-zero @newer_than. > > And if range B is not really newer, it will rejected directly, causing > only range A being defragged, while we expect to defrag both range A and > B. > > [FIX] > Since the root cause is the difference in check condition of > defrag_check_next_extent() and defrag_collect_targets(), we fix it by: > > 1. Pass @newer_than to defrag_check_next_extent() > 2. Pass @extent_thresh to defrag_check_next_extent() > > This makes the check between defrag_collect_targets() and > defrag_check_next_extent() more consistent. > > While there is still some minor difference, the remaining checks are > focus on runtime flags like writeback/delalloc, which are mostly > transient and safe to be checked only in defrag_collect_targets(). > > Link: https://github.com/btrfs/linux/issues/423#issuecomment-1066981856 > Cc: stable@xxxxxxxxxxxxxxx # 5.16+ > Signed-off-by: Qu Wenruo <wqu@xxxxxxxx> > --- > Changelog: > v2: > - Add proper CC to stable > - Use Link: tag to replace Issue: tag > As every developer/maintainer has their own btrfs tree, Issue: tag is > really confusing Added to misc-next, thanks.