aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/rgrp.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/rgrp.c')
-rw-r--r--fs/gfs2/rgrp.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 0c5a575b513e..69317435faa7 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -638,8 +638,10 @@ void gfs2_rs_deltree(struct gfs2_blkreserv *rs)
638 */ 638 */
639void gfs2_rs_delete(struct gfs2_inode *ip) 639void gfs2_rs_delete(struct gfs2_inode *ip)
640{ 640{
641 struct inode *inode = &ip->i_inode;
642
641 down_write(&ip->i_rw_mutex); 643 down_write(&ip->i_rw_mutex);
642 if (ip->i_res) { 644 if (ip->i_res && atomic_read(&inode->i_writecount) <= 1) {
643 gfs2_rs_deltree(ip->i_res); 645 gfs2_rs_deltree(ip->i_res);
644 BUG_ON(ip->i_res->rs_free); 646 BUG_ON(ip->i_res->rs_free);
645 kmem_cache_free(gfs2_rsrv_cachep, ip->i_res); 647 kmem_cache_free(gfs2_rsrv_cachep, ip->i_res);
@@ -1286,13 +1288,15 @@ int gfs2_fitrim(struct file *filp, void __user *argp)
1286 minlen = max_t(u64, r.minlen, 1288 minlen = max_t(u64, r.minlen,
1287 q->limits.discard_granularity) >> bs_shift; 1289 q->limits.discard_granularity) >> bs_shift;
1288 1290
1291 if (end <= start || minlen > sdp->sd_max_rg_data)
1292 return -EINVAL;
1293
1289 rgd = gfs2_blk2rgrpd(sdp, start, 0); 1294 rgd = gfs2_blk2rgrpd(sdp, start, 0);
1290 rgd_end = gfs2_blk2rgrpd(sdp, end - 1, 0); 1295 rgd_end = gfs2_blk2rgrpd(sdp, end, 0);
1291 1296
1292 if (end <= start || 1297 if ((gfs2_rgrpd_get_first(sdp) == gfs2_rgrpd_get_next(rgd_end))
1293 minlen > sdp->sd_max_rg_data || 1298 && (start > rgd_end->rd_data0 + rgd_end->rd_data))
1294 start > rgd_end->rd_data0 + rgd_end->rd_data) 1299 return -EINVAL; /* start is beyond the end of the fs */
1295 return -EINVAL;
1296 1300
1297 while (1) { 1301 while (1) {
1298 1302
@@ -1334,7 +1338,7 @@ int gfs2_fitrim(struct file *filp, void __user *argp)
1334 } 1338 }
1335 1339
1336out: 1340out:
1337 r.len = trimmed << 9; 1341 r.len = trimmed << bs_shift;
1338 if (copy_to_user(argp, &r, sizeof(r))) 1342 if (copy_to_user(argp, &r, sizeof(r)))
1339 return -EFAULT; 1343 return -EFAULT;
1340 1344
@@ -1401,9 +1405,14 @@ static void rg_mblk_search(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip,
1401 u32 extlen; 1405 u32 extlen;
1402 u32 free_blocks = rgd->rd_free_clone - rgd->rd_reserved; 1406 u32 free_blocks = rgd->rd_free_clone - rgd->rd_reserved;
1403 int ret; 1407 int ret;
1408 struct inode *inode = &ip->i_inode;
1404 1409
1405 extlen = max_t(u32, atomic_read(&rs->rs_sizehint), requested); 1410 if (S_ISDIR(inode->i_mode))
1406 extlen = clamp(extlen, RGRP_RSRV_MINBLKS, free_blocks); 1411 extlen = 1;
1412 else {
1413 extlen = max_t(u32, atomic_read(&rs->rs_sizehint), requested);
1414 extlen = clamp(extlen, RGRP_RSRV_MINBLKS, free_blocks);
1415 }
1407 if ((rgd->rd_free_clone < rgd->rd_reserved) || (free_blocks < extlen)) 1416 if ((rgd->rd_free_clone < rgd->rd_reserved) || (free_blocks < extlen))
1408 return; 1417 return;
1409 1418