From mboxrd@z Thu Jan 1 00:00:00 1970 From: Steven Whitehouse Date: Tue, 2 Feb 2016 11:40:10 +0000 Subject: [Cluster-devel] [PATCH 1/4] GFS2: Prevent delete work from occurring on glocks used for create In-Reply-To: <1450465350-10060-2-git-send-email-rpeterso@redhat.com> References: <1450465350-10060-1-git-send-email-rpeterso@redhat.com> <1450465350-10060-2-git-send-email-rpeterso@redhat.com> Message-ID: <56B0959A.7000501@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, Acked-by: Steven Whitehouse Steve. On 18/12/15 19:02, Bob Peterson wrote: > This patch tries to prevent delete work (queued via iopen callback) > from executing if the glock is currently being used to create > a new inode. > > Signed-off-by: Bob Peterson > --- > fs/gfs2/glock.c | 7 +++++++ > fs/gfs2/incore.h | 1 + > fs/gfs2/inode.c | 7 ++++++- > 3 files changed, 14 insertions(+), 1 deletion(-) > > diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c > index a4ff7b5..cb5ed3a 100644 > --- a/fs/gfs2/glock.c > +++ b/fs/gfs2/glock.c > @@ -572,6 +572,12 @@ static void delete_work_func(struct work_struct *work) > struct inode *inode; > u64 no_addr = gl->gl_name.ln_number; > > + /* If someone's using this glock to create a new dinode, the block must > + have been freed by another node, then re-used, in which case our > + iopen callback is too late after the fact. Ignore it. */ > + if (test_bit(GLF_INODE_CREATING, &gl->gl_flags)) > + goto out; > + > ip = gl->gl_object; > /* Note: Unsafe to dereference ip as we don't hold right refs/locks */ > > @@ -583,6 +589,7 @@ static void delete_work_func(struct work_struct *work) > d_prune_aliases(inode); > iput(inode); > } > +out: > gfs2_glock_put(gl); > } > > diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h > index 845fb09..a6a3389 100644 > --- a/fs/gfs2/incore.h > +++ b/fs/gfs2/incore.h > @@ -328,6 +328,7 @@ enum { > GLF_LRU = 13, > GLF_OBJECT = 14, /* Used only for tracing */ > GLF_BLOCKING = 15, > + GLF_INODE_CREATING = 16, /* Inode creation occurring */ > }; > > struct gfs2_glock { > diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c > index 009b551..6cdafed 100644 > --- a/fs/gfs2/inode.c > +++ b/fs/gfs2/inode.c > @@ -592,7 +592,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, > struct inode *inode = NULL; > struct gfs2_inode *dip = GFS2_I(dir), *ip; > struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); > - struct gfs2_glock *io_gl; > + struct gfs2_glock *io_gl = NULL; > int error, free_vfs_inode = 1; > u32 aflags = 0; > unsigned blocks = 1; > @@ -729,6 +729,8 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, > if (error) > goto fail_gunlock2; > > + BUG_ON(test_and_set_bit(GLF_INODE_CREATING, &io_gl->gl_flags)); > + > error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh); > if (error) > goto fail_gunlock2; > @@ -771,12 +773,15 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry, > } > gfs2_glock_dq_uninit(ghs); > gfs2_glock_dq_uninit(ghs + 1); > + clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags); > return error; > > fail_gunlock3: > gfs2_glock_dq_uninit(&ip->i_iopen_gh); > gfs2_glock_put(io_gl); > fail_gunlock2: > + if (io_gl) > + clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags); > gfs2_glock_dq_uninit(ghs + 1); > fail_free_inode: > if (ip->i_gl)