aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/rgrp.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index b6bbf718d6c3..38fe18f2f055 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -1262,7 +1262,9 @@ int gfs2_fitrim(struct file *filp, void __user *argp)
1262 int ret = 0; 1262 int ret = 0;
1263 u64 amt; 1263 u64 amt;
1264 u64 trimmed = 0; 1264 u64 trimmed = 0;
1265 u64 start, end, minlen;
1265 unsigned int x; 1266 unsigned int x;
1267 unsigned bs_shift = sdp->sd_sb.sb_bsize_shift;
1266 1268
1267 if (!capable(CAP_SYS_ADMIN)) 1269 if (!capable(CAP_SYS_ADMIN))
1268 return -EPERM; 1270 return -EPERM;
@@ -1277,8 +1279,18 @@ int gfs2_fitrim(struct file *filp, void __user *argp)
1277 if (ret) 1279 if (ret)
1278 return ret; 1280 return ret;
1279 1281
1280 rgd = gfs2_blk2rgrpd(sdp, r.start, 0); 1282 start = r.start >> bs_shift;
1281 rgd_end = gfs2_blk2rgrpd(sdp, r.start + r.len, 0); 1283 end = start + (r.len >> bs_shift);
1284 minlen = max_t(u64, r.minlen,
1285 q->limits.discard_granularity) >> bs_shift;
1286
1287 rgd = gfs2_blk2rgrpd(sdp, start, 0);
1288 rgd_end = gfs2_blk2rgrpd(sdp, end - 1, 0);
1289
1290 if (end <= start ||
1291 minlen > sdp->sd_max_rg_data ||
1292 start > rgd_end->rd_data0 + rgd_end->rd_data)
1293 return -EINVAL;
1282 1294
1283 while (1) { 1295 while (1) {
1284 1296
@@ -1290,7 +1302,9 @@ int gfs2_fitrim(struct file *filp, void __user *argp)
1290 /* Trim each bitmap in the rgrp */ 1302 /* Trim each bitmap in the rgrp */
1291 for (x = 0; x < rgd->rd_length; x++) { 1303 for (x = 0; x < rgd->rd_length; x++) {
1292 struct gfs2_bitmap *bi = rgd->rd_bits + x; 1304 struct gfs2_bitmap *bi = rgd->rd_bits + x;
1293 ret = gfs2_rgrp_send_discards(sdp, rgd->rd_data0, NULL, bi, r.minlen, &amt); 1305 ret = gfs2_rgrp_send_discards(sdp,
1306 rgd->rd_data0, NULL, bi, minlen,
1307 &amt);
1294 if (ret) { 1308 if (ret) {
1295 gfs2_glock_dq_uninit(&gh); 1309 gfs2_glock_dq_uninit(&gh);
1296 goto out; 1310 goto out;