Message ID | 20231216010919.1995851-1-yebin10@huawei.com |
---|---|
State | Awaiting Upstream |
Headers | show |
Series | [v2] ext4: fix inconsistent between segment fstrim and full fstrim | expand |
On Sat, 16 Dec 2023 09:09:19 +0800, Ye Bin wrote: > Suppose we issue two FITRIM ioctls for ranges [0,15] and [16,31] with > mininum length of trimmed range set to 8 blocks. If we have say a range of > blocks 10-22 free, this range will not be trimmed because it straddles the > boundary of the two FITRIM ranges and neither part is big enough. This is a > bit surprising to some users that call FITRIM on smaller ranges of blocks > to limit impact on the system. Also XFS trims all free space extents that > overlap with the specified range so we are inconsistent among filesystems. > Let's change ext4_try_to_trim_range() to consider for trimming the whole > free space extent that straddles the end of specified range, not just the > part of it within the range. > > [...] Applied, thanks! [1/1] ext4: fix inconsistent between segment fstrim and full fstrim commit: 3d1aa1169c45aba9d589be1eb4b131f26f0a663c Best regards,
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index d72b5e3c92ec..d195461123d8 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -6753,13 +6753,15 @@ static int ext4_try_to_trim_range(struct super_block *sb, __acquires(ext4_group_lock_ptr(sb, e4b->bd_group)) __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) { - ext4_grpblk_t next, count, free_count; + ext4_grpblk_t next, count, free_count, last, origin_start; bool set_trimmed = false; void *bitmap; + last = ext4_last_grp_cluster(sb, e4b->bd_group); bitmap = e4b->bd_bitmap; - if (start == 0 && max >= ext4_last_grp_cluster(sb, e4b->bd_group)) + if (start == 0 && max >= last) set_trimmed = true; + origin_start = start; start = max(e4b->bd_info->bb_first_free, start); count = 0; free_count = 0; @@ -6768,7 +6770,10 @@ __releases(ext4_group_lock_ptr(sb, e4b->bd_group)) start = mb_find_next_zero_bit(bitmap, max + 1, start); if (start > max) break; - next = mb_find_next_bit(bitmap, max + 1, start); + + next = mb_find_next_bit(bitmap, last + 1, start); + if (origin_start == 0 && next >= last) + set_trimmed = true; if ((next - start) >= minblocks) { int ret = ext4_trim_extent(sb, start, next - start, e4b);