lkml.org 
[lkml]   [2022]   [Jan]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.16 0443/1039] ext4: avoid trim error on fs with small groups
    Date
    From: Jan Kara <jack@suse.cz>

    [ Upstream commit 173b6e383d2a204c9921ffc1eca3b87aa2106c33 ]

    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 <lczerner@redhat.com>
    Fixes: 5c2ed62fd447 ("ext4: Adjust minlen with discard_granularity in the FITRIM ioctl")
    Signed-off-by: Jan Kara <jack@suse.cz>
    Link: https://lore.kernel.org/r/20211112152202.26614-1-jack@suse.cz
    Signed-off-by: Theodore Ts'o <tytso@mit.edu>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    fs/ext4/ioctl.c | 2 --
    fs/ext4/mballoc.c | 8 ++++++++
    2 files changed, 8 insertions(+), 2 deletions(-)

    diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
    index 606dee9e08a32..220a4c8178b5e 100644
    --- a/fs/ext4/ioctl.c
    +++ b/fs/ext4/ioctl.c
    @@ -1117,8 +1117,6 @@ resizefs_out:
    sizeof(range)))
    return -EFAULT;

    - range.minlen = max((unsigned int)range.minlen,
    - q->limits.discard_granularity);
    ret = ext4_trim_fs(sb, &range);
    if (ret < 0)
    return ret;
    diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
    index 215b7068f548a..9af83b6242ddf 100644
    --- a/fs/ext4/mballoc.c
    +++ b/fs/ext4/mballoc.c
    @@ -6404,6 +6404,7 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group,
    */
    int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
    {
    + struct request_queue *q = bdev_get_queue(sb->s_bdev);
    struct ext4_group_info *grp;
    ext4_group_t group, first_group, last_group;
    ext4_grpblk_t cnt = 0, first_cluster, last_cluster;
    @@ -6422,6 +6423,13 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range)
    start >= max_blks ||
    range->len < sb->s_blocksize)
    return -EINVAL;
    + /* No point to try to trim less than discard granularity */
    + if (range->minlen < q->limits.discard_granularity) {
    + minlen = EXT4_NUM_B2C(EXT4_SB(sb),
    + q->limits.discard_granularity >> sb->s_blocksize_bits);
    + if (minlen > EXT4_CLUSTERS_PER_GROUP(sb))
    + goto out;
    + }
    if (end >= max_blks)
    end = max_blks - 1;
    if (end <= first_data_blk)
    --
    2.34.1


    \
     
     \ /
      Last update: 2022-01-24 23:10    [W:2.682 / U:0.616 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site