Skip to content

Commit

Permalink
ext4: mark group as trimmed only if it was fully scanned
Browse files Browse the repository at this point in the history
commit d63c00e upstream.

Otherwise nonaligned fstrim calls will works inconveniently for iterative
scanners, for example:

// trim [0,16MB] for group-1, but mark full group as trimmed
fstrim  -o $((1024*1024*128)) -l $((1024*1024*16)) ./m
// handle [16MB,16MB] for group-1, do nothing because group already has the flag.
fstrim  -o $((1024*1024*144)) -l $((1024*1024*16)) ./m

[ Update function documentation for ext4_trim_all_free -- TYT ]

Signed-off-by: Dmitry Monakhov <dmtrmonakhov@yandex-team.ru>
Link: https://lore.kernel.org/r/1650214995-860245-1-git-send-email-dmtrmonakhov@yandex-team.ru
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Cc: stable@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Dmitry Monakhov authored and gregkh committed Jun 9, 2022
1 parent 97bd6c5 commit be28c00
Showing 1 changed file with 12 additions and 6 deletions.
18 changes: 12 additions & 6 deletions fs/ext4/mballoc.c
Expand Up @@ -6377,6 +6377,7 @@ __releases(ext4_group_lock_ptr(sb, e4b->bd_group))
* @start: first group block to examine
* @max: last group block to examine
* @minblocks: minimum extent block count
* @set_trimmed: set the trimmed flag if at least one block is trimmed
*
* ext4_trim_all_free walks through group's block bitmap searching for free
* extents. When the free extent is found, mark it as used in group buddy
Expand All @@ -6386,7 +6387,7 @@ __releases(ext4_group_lock_ptr(sb, e4b->bd_group))
static ext4_grpblk_t
ext4_trim_all_free(struct super_block *sb, ext4_group_t group,
ext4_grpblk_t start, ext4_grpblk_t max,
ext4_grpblk_t minblocks)
ext4_grpblk_t minblocks, bool set_trimmed)
{
struct ext4_buddy e4b;
int ret;
Expand All @@ -6405,7 +6406,7 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group,
if (!EXT4_MB_GRP_WAS_TRIMMED(e4b.bd_info) ||
minblocks < EXT4_SB(sb)->s_last_trim_minblks) {
ret = ext4_try_to_trim_range(sb, &e4b, start, max, minblocks);
if (ret >= 0)
if (ret >= 0 && set_trimmed)
EXT4_MB_GRP_SET_TRIMMED(e4b.bd_info);
} else {
ret = 0;
Expand Down Expand Up @@ -6442,6 +6443,7 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
ext4_fsblk_t first_data_blk =
le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block);
ext4_fsblk_t max_blks = ext4_blocks_count(EXT4_SB(sb)->s_es);
bool whole_group, eof = false;
int ret = 0;

start = range->start >> sb->s_blocksize_bits;
Expand All @@ -6460,8 +6462,10 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
if (minlen > EXT4_CLUSTERS_PER_GROUP(sb))
goto out;
}
if (end >= max_blks)
if (end >= max_blks - 1) {
end = max_blks - 1;
eof = true;
}
if (end <= first_data_blk)
goto out;
if (start < first_data_blk)
Expand All @@ -6475,6 +6479,7 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)

/* end now represents the last cluster to discard in this group */
end = EXT4_CLUSTERS_PER_GROUP(sb) - 1;
whole_group = true;

for (group = first_group; group <= last_group; group++) {
grp = ext4_get_group_info(sb, group);
Expand All @@ -6491,12 +6496,13 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
* change it for the last group, note that last_cluster is
* already computed earlier by ext4_get_group_no_and_offset()
*/
if (group == last_group)
if (group == last_group) {
end = last_cluster;

whole_group = eof ? true : end == EXT4_CLUSTERS_PER_GROUP(sb) - 1;
}
if (grp->bb_free >= minlen) {
cnt = ext4_trim_all_free(sb, group, first_cluster,
end, minlen);
end, minlen, whole_group);
if (cnt < 0) {
ret = cnt;
break;
Expand Down

0 comments on commit be28c00

Please sign in to comment.