Commit 076f0faa authored by Lukas Czerner's avatar Lukas Czerner Committed by Steven Whitehouse

GFS2: Fix FITRIM argument handling

Currently implementation in gfs2 uses FITRIM arguments as it were in
file system blocks units which is wrong. The FITRIM arguments
(fstrim_range.start, fstrim_range.len and fstrim_range.minlen) are
actually in bytes.

Moreover, check for start argument beyond the end of file system, len
argument being smaller than file system block and minlen argument being
bigger than biggest resource group were missing.

This commit converts the code to convert FITRIM argument to file system
blocks and also adds appropriate checks mentioned above.

All the problems were recognised by xfstests 251 and 260.
Signed-off-by: default avatarLukas Czerner <lczerner@redhat.com>
Signed-off-by: default avatarSteven Whitehouse <swhiteho@redhat.com>
parent 3a238ade
...@@ -1262,7 +1262,9 @@ int gfs2_fitrim(struct file *filp, void __user *argp) ...@@ -1262,7 +1262,9 @@ int gfs2_fitrim(struct file *filp, void __user *argp)
int ret = 0; int ret = 0;
u64 amt; u64 amt;
u64 trimmed = 0; u64 trimmed = 0;
u64 start, end, minlen;
unsigned int x; unsigned int x;
unsigned bs_shift = sdp->sd_sb.sb_bsize_shift;
if (!capable(CAP_SYS_ADMIN)) if (!capable(CAP_SYS_ADMIN))
return -EPERM; return -EPERM;
...@@ -1277,8 +1279,18 @@ int gfs2_fitrim(struct file *filp, void __user *argp) ...@@ -1277,8 +1279,18 @@ int gfs2_fitrim(struct file *filp, void __user *argp)
if (ret) if (ret)
return ret; return ret;
rgd = gfs2_blk2rgrpd(sdp, r.start, 0); start = r.start >> bs_shift;
rgd_end = gfs2_blk2rgrpd(sdp, r.start + r.len, 0); end = start + (r.len >> bs_shift);
minlen = max_t(u64, r.minlen,
q->limits.discard_granularity) >> bs_shift;
rgd = gfs2_blk2rgrpd(sdp, start, 0);
rgd_end = gfs2_blk2rgrpd(sdp, end - 1, 0);
if (end <= start ||
minlen > sdp->sd_max_rg_data ||
start > rgd_end->rd_data0 + rgd_end->rd_data)
return -EINVAL;
while (1) { while (1) {
...@@ -1290,7 +1302,9 @@ int gfs2_fitrim(struct file *filp, void __user *argp) ...@@ -1290,7 +1302,9 @@ int gfs2_fitrim(struct file *filp, void __user *argp)
/* Trim each bitmap in the rgrp */ /* Trim each bitmap in the rgrp */
for (x = 0; x < rgd->rd_length; x++) { for (x = 0; x < rgd->rd_length; x++) {
struct gfs2_bitmap *bi = rgd->rd_bits + x; struct gfs2_bitmap *bi = rgd->rd_bits + x;
ret = gfs2_rgrp_send_discards(sdp, rgd->rd_data0, NULL, bi, r.minlen, &amt); ret = gfs2_rgrp_send_discards(sdp,
rgd->rd_data0, NULL, bi, minlen,
&amt);
if (ret) { if (ret) {
gfs2_glock_dq_uninit(&gh); gfs2_glock_dq_uninit(&gh);
goto out; goto out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment