From mboxrd@z Thu Jan 1 00:00:00 1970 From: Steven Whitehouse Date: Wed, 01 Oct 2014 14:11:20 +0100 Subject: [Cluster-devel] [GFS2 PATCH] GFS2: Make rename not save dirent location In-Reply-To: <743715787.31193744.1411995124559.JavaMail.zimbra@redhat.com> References: <743715787.31193744.1411995124559.JavaMail.zimbra@redhat.com> Message-ID: <542BFD78.9040108@redhat.com> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Hi, On 29/09/14 13:52, Bob Peterson wrote: > Hi, > > This patch fixes a regression in the patch "GFS2: Remember directory > insert point", commit 2b47dad866d04f14c328f888ba5406057b8c7d33. > The problem had to do with the rename function: The function found > space for the new dirent, and remembered that location. But then the > old dirent was removed, which often moved the eligible location for > the renamed dirent. Putting the new dirent at the saved location > caused file system corruption. > > This patch adds a new "save_loc" variable to struct gfs2_diradd. > If 1, the dirent location is saved. If 0, the dirent location is not > saved and the buffer_head is released as per previous behavior. > > Regards, > > Bob Peterson > Red Hat File Systems Now in the -nmw git tree. Thanks, Steve. > Signed-off-by: Bob Peterson > --- > diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c > index 1a349f9..5d4261f 100644 > --- a/fs/gfs2/dir.c > +++ b/fs/gfs2/dir.c > @@ -2100,8 +2100,13 @@ int gfs2_diradd_alloc_required(struct inode *inode, const struct qstr *name, > } > if (IS_ERR(dent)) > return PTR_ERR(dent); > - da->bh = bh; > - da->dent = dent; > + > + if (da->save_loc) { > + da->bh = bh; > + da->dent = dent; > + } else { > + brelse(bh); > + } > return 0; > } > > diff --git a/fs/gfs2/dir.h b/fs/gfs2/dir.h > index 126c65d..e1b309c 100644 > --- a/fs/gfs2/dir.h > +++ b/fs/gfs2/dir.h > @@ -23,6 +23,7 @@ struct gfs2_diradd { > unsigned nr_blocks; > struct gfs2_dirent *dent; > struct buffer_head *bh; > + int save_loc; > }; > > extern struct inode *gfs2_dir_search(struct inode *dir, > diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c > index 9516f5c..fcf42ea 100644 > --- a/fs/gfs2/inode.c > +++ b/fs/gfs2/inode.c > @@ -600,7 +600,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, > int error, free_vfs_inode = 0; > u32 aflags = 0; > unsigned blocks = 1; > - struct gfs2_diradd da = { .bh = NULL, }; > + struct gfs2_diradd da = { .bh = NULL, .save_loc = 1, }; > > if (!name->len || name->len > GFS2_FNAMESIZE) > return -ENAMETOOLONG; > @@ -900,7 +900,7 @@ static int gfs2_link(struct dentry *old_dentry, struct inode *dir, > struct gfs2_inode *ip = GFS2_I(inode); > struct gfs2_holder ghs[2]; > struct buffer_head *dibh; > - struct gfs2_diradd da = { .bh = NULL, }; > + struct gfs2_diradd da = { .bh = NULL, .save_loc = 1, }; > int error; > > if (S_ISDIR(inode->i_mode)) > @@ -1338,7 +1338,7 @@ static int gfs2_rename(struct inode *odir, struct dentry *odentry, > struct gfs2_rgrpd *nrgd; > unsigned int num_gh; > int dir_rename = 0; > - struct gfs2_diradd da = { .nr_blocks = 0, }; > + struct gfs2_diradd da = { .nr_blocks = 0, .save_loc = 0, }; > unsigned int x; > int error; >