From mboxrd@z Thu Jan 1 00:00:00 1970 From: Steven Whitehouse Date: Tue, 26 Apr 2011 10:31:12 +0100 Subject: [Cluster-devel] [PATCH] GFS2: make sure fallocate bytes is a multiple of blksize In-Reply-To: <20110426061324.GG23657@ether.msp.redhat.com> References: <20110426061324.GG23657@ether.msp.redhat.com> Message-ID: <1303810272.2648.3.camel@dolmen> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Hi, Now in the -nmw GFS2 git tree. Thanks, Steve. On Tue, 2011-04-26 at 01:13 -0500, Benjamin Marzinski wrote: > The GFS2 fallocate code chooses a target size to for allocating chunks of > space. Whenever it can't find any resource groups with enough space free, it > halves its target. Since this target is in bytes, eventually it will no longer > be a multiple of blksize. As long as there is more space available in the > resource group than the target, this isn't a problem, since gfs2 will use the > actual space available, which is always a multiple of blksize. However, > when gfs couldn't fallocate a bigger chunk than the target, it was using the > non-blksize aligned number. This caused a BUG in later code that required > blksize aligned offsets. GFS2 now ensures that bytes is always a multiple of > blksize > > Signed-off-by: Benjamin Marzinski > --- > fs/gfs2/file.c | 10 ++++++++-- > 1 file changed, 8 insertions(+), 2 deletions(-) > > Index: gfs2-2.6-nmw/fs/gfs2/file.c > =================================================================== > --- gfs2-2.6-nmw.orig/fs/gfs2/file.c > +++ gfs2-2.6-nmw/fs/gfs2/file.c > @@ -816,6 +816,7 @@ static long gfs2_fallocate(struct file * > loff_t bytes, max_bytes; > struct gfs2_alloc *al; > int error; > + loff_t bsize_mask = ~((loff_t)sdp->sd_sb.sb_bsize - 1); > loff_t next = (offset + len - 1) >> sdp->sd_sb.sb_bsize_shift; > next = (next + 1) << sdp->sd_sb.sb_bsize_shift; > > @@ -823,13 +824,15 @@ static long gfs2_fallocate(struct file * > if (mode & ~FALLOC_FL_KEEP_SIZE) > return -EOPNOTSUPP; > > - offset = (offset >> sdp->sd_sb.sb_bsize_shift) << > - sdp->sd_sb.sb_bsize_shift; > + offset &= bsize_mask; > > len = next - offset; > bytes = sdp->sd_max_rg_data * sdp->sd_sb.sb_bsize / 2; > if (!bytes) > bytes = UINT_MAX; > + bytes &= bsize_mask; > + if (bytes == 0) > + bytes = sdp->sd_sb.sb_bsize; > > gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &ip->i_gh); > error = gfs2_glock_nq(&ip->i_gh); > @@ -860,6 +863,9 @@ retry: > if (error) { > if (error == -ENOSPC && bytes > sdp->sd_sb.sb_bsize) { > bytes >>= 1; > + bytes &= bsize_mask; > + if (bytes == 0) > + bytes = sdp->sd_sb.sb_bsize; > goto retry; > } > goto out_qunlock; >