Skip to content

Commit 173b6e3

Browse files
jankaratytso
authored andcommitted
ext4: avoid trim error on fs with small groups
A user reported FITRIM ioctl failing for him on ext4 on some devices without apparent reason. After some debugging we've found out that these devices (being LVM volumes) report rather large discard granularity of 42MB and the filesystem had 1k blocksize and thus group size of 8MB. Because ext4 FITRIM implementation puts discard granularity into minlen, ext4_trim_fs() declared the trim request as invalid. However just silently doing nothing seems to be a more appropriate reaction to such combination of parameters since user did not specify anything wrong. CC: Lukas Czerner <[email protected]> Fixes: 5c2ed62 ("ext4: Adjust minlen with discard_granularity in the FITRIM ioctl") Signed-off-by: Jan Kara <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Theodore Ts'o <[email protected]>
1 parent 5c48a7d commit 173b6e3

File tree

2 files changed

+8
-2
lines changed

2 files changed

+8
-2
lines changed

fs/ext4/ioctl.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,8 +1114,6 @@ static long __ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
11141114
sizeof(range)))
11151115
return -EFAULT;
11161116

1117-
range.minlen = max((unsigned int)range.minlen,
1118-
q->limits.discard_granularity);
11191117
ret = ext4_trim_fs(sb, &range);
11201118
if (ret < 0)
11211119
return ret;

fs/ext4/mballoc.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6400,6 +6400,7 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group,
64006400
*/
64016401
int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
64026402
{
6403+
struct request_queue *q = bdev_get_queue(sb->s_bdev);
64036404
struct ext4_group_info *grp;
64046405
ext4_group_t group, first_group, last_group;
64056406
ext4_grpblk_t cnt = 0, first_cluster, last_cluster;
@@ -6418,6 +6419,13 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
64186419
start >= max_blks ||
64196420
range->len < sb->s_blocksize)
64206421
return -EINVAL;
6422+
/* No point to try to trim less than discard granularity */
6423+
if (range->minlen < q->limits.discard_granularity) {
6424+
minlen = EXT4_NUM_B2C(EXT4_SB(sb),
6425+
q->limits.discard_granularity >> sb->s_blocksize_bits);
6426+
if (minlen > EXT4_CLUSTERS_PER_GROUP(sb))
6427+
goto out;
6428+
}
64216429
if (end >= max_blks)
64226430
end = max_blks - 1;
64236431
if (end <= first_data_blk)

0 commit comments

Comments
 (0)