From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andrew Price Date: Tue, 22 Mar 2022 20:08:24 +0000 Subject: [Cluster-devel] [PATCH] gfs2: Make sure FITRIM minlen is rounded up to fs block size In-Reply-To: <20220322190551.357960-1-anprice@redhat.com> References: <20220322190551.357960-1-anprice@redhat.com> Message-ID: List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit On 22/03/2022 19:05, Andrew Price wrote: > Per fstrim(8) we must round up the minlen argument to the fs block size. > The current calculation doesn't take into account devices that have a > discard granularity and requested minlen less than 1 fs block, so the > value can get shifted away to zero in the translation to fs blocks. > > The zero minlen passed to gfs2_rgrp_send_discards() then allows > sb_issue_discard() to be called with nr_sects == 0 which returns -EINVAL > and results in gfs2_rgrp_send_discards() returning -EIO. Adding test results. xfstests interprets fstrim failures as "FITRIM not supported" and doesn't run them, so I got these results: 5.17: Ran: generic/260 generic/288 generic/537 Not run: generic/260 generic/288 generic/537 Passed all 3 tests 5.17 + patch: Ran: generic/260 generic/288 generic/537 Passed all 3 tests (Those 3 tests are in the ones in the 'quick' and 'trim' groups) Andy > Make sure minlen is never < 1 fs block by taking the max of the > requested minlen and the fs block size before comparing to the device's > discard granularity and shifting to fs blocks. > > Fixes: 076f0faa764ab ("GFS2: Fix FITRIM argument handling") > Signed-off-by: Andrew Price > --- > fs/gfs2/rgrp.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c > index 0fb3c01bc557..a34945cbf32a 100644 > --- a/fs/gfs2/rgrp.c > +++ b/fs/gfs2/rgrp.c > @@ -1415,7 +1415,8 @@ int gfs2_fitrim(struct file *filp, void __user *argp) > > start = r.start >> bs_shift; > end = start + (r.len >> bs_shift); > - minlen = max_t(u64, r.minlen, > + minlen = max_t(u64, r.minlen, sdp->sd_sb.sb_bsize); > + minlen = max_t(u64, minlen, > q->limits.discard_granularity) >> bs_shift; > > if (end <= start || minlen > sdp->sd_max_rg_data)