From 6a98c333edd0ada67e96a5dbd0445808147833f7 Mon Sep 17 00:00:00 2001 From: Abhijith Das Date: Wed, 19 Jun 2013 17:03:29 -0400 Subject: [PATCH] GFS2: Fix fstrim boundary conditions This patch correctly distinguishes two boundary conditions: 1. When the given range is entire within the unaccounted space between two rgrps, and 2. The range begins beyond the end of the filesystem Also fix the unit of the returned value r.len (total trimming) to be in bytes instead of the (incorrect) 512 byte blocks With this patch, GFS2 passes multiple iterations of all the relevant xfstests (251, 260, 288) with different fs block sizes. Signed-off-by: Abhi Das Signed-off-by: Steven Whitehouse --- fs/gfs2/rgrp.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 9809156e3d04..69317435faa7 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -1288,14 +1288,16 @@ int gfs2_fitrim(struct file *filp, void __user *argp) 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) + if (end <= start || minlen > sdp->sd_max_rg_data) return -EINVAL; + rgd = gfs2_blk2rgrpd(sdp, start, 0); + rgd_end = gfs2_blk2rgrpd(sdp, end, 0); + + if ((gfs2_rgrpd_get_first(sdp) == gfs2_rgrpd_get_next(rgd_end)) + && (start > rgd_end->rd_data0 + rgd_end->rd_data)) + return -EINVAL; /* start is beyond the end of the fs */ + while (1) { ret = gfs2_glock_nq_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, &gh); @@ -1336,7 +1338,7 @@ int gfs2_fitrim(struct file *filp, void __user *argp) } out: - r.len = trimmed << 9; + r.len = trimmed << bs_shift; if (copy_to_user(argp, &r, sizeof(r))) return -EFAULT;