diff options
| -rw-r--r-- | fs/gfs2/rgrp.c | 20 |
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; |
