* [Cluster-devel] [GFS2 PATCH] GFS2: Check if iopen is held when deleting inode [not found] <747868619.36036602.1450463887728.JavaMail.zimbra@redhat.com> @ 2015-12-18 18:38 ` Bob Peterson 2016-01-12 15:25 ` [Cluster-devel] [GFS2 PATCH v2] " Bob Peterson 2016-02-02 11:56 ` [Cluster-devel] [GFS2 PATCH] " Steven Whitehouse 0 siblings, 2 replies; 4+ messages in thread From: Bob Peterson @ 2015-12-18 18:38 UTC (permalink / raw) To: cluster-devel.redhat.com Hi, This patch fixes an error condition in which an inode is partially created in gfs2_create_inode() but then some error is discovered, which causes it to fail and call iput() before the iopen glock is created or held. In that case, gfs2_delete_inode would try to unlock an iopen glock that doesn't yet exist. Therefore, we test its holder (which must exist) for the HIF_HOLDER bit before trying to dq it. Signed-off-by: Bob Peterson <rpeterso@redhat.com> diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 8f960a5..d354e72 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -1551,12 +1551,15 @@ static void gfs2_evict_inode(struct inode *inode) goto out_truncate; } - ip->i_iopen_gh.gh_flags |= GL_NOCACHE; - gfs2_glock_dq_wait(&ip->i_iopen_gh); - gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh); - error = gfs2_glock_nq(&ip->i_iopen_gh); - if (error) - goto out_truncate; + if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) { + ip->i_iopen_gh.gh_flags |= GL_NOCACHE; + gfs2_glock_dq_wait(&ip->i_iopen_gh); + gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, + &ip->i_iopen_gh); + error = gfs2_glock_nq(&ip->i_iopen_gh); + if (error) + goto out_truncate; + } /* Case 1 starts here */ ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [Cluster-devel] [GFS2 PATCH v2] GFS2: Check if iopen is held when deleting inode 2015-12-18 18:38 ` [Cluster-devel] [GFS2 PATCH] GFS2: Check if iopen is held when deleting inode Bob Peterson @ 2016-01-12 15:25 ` Bob Peterson 2016-01-12 15:27 ` Steven Whitehouse 2016-02-02 11:56 ` [Cluster-devel] [GFS2 PATCH] " Steven Whitehouse 1 sibling, 1 reply; 4+ messages in thread From: Bob Peterson @ 2016-01-12 15:25 UTC (permalink / raw) To: cluster-devel.redhat.com Hi, On 18 December 2015, I posted this upstream GFS2 patch. Since that time, I discovered a bug that warrants expanding the scope of the patch. This is the revised patch. Patch description: GFS2: Check if iopen is held when deleting inode This patch fixes an error condition in which an inode is partially created in gfs2_create_inode() but then some error is discovered, which causes it to fail and call iput() before the iopen glock is created or held. In that case, gfs2_delete_inode would try to unlock an iopen glock that doesn't yet exist. Therefore, we test its holder (which must exist) for the HIF_HOLDER bit before trying to dq it. Signed-off-by: Bob Peterson <rpeterso@redhat.com> diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 795c2f3..8dedece 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -1015,6 +1015,7 @@ void gfs2_glock_dq(struct gfs2_holder *gh) handle_callback(gl, LM_ST_UNLOCKED, 0, false); list_del_init(&gh->gh_list); + clear_bit(HIF_HOLDER, &gh->gh_iflags); if (find_first_holder(gl) == NULL) { if (glops->go_unlock) { GLOCK_BUG_ON(gl, test_and_set_bit(GLF_LOCK, &gl->gl_flags)); diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 8f960a5..f8a0cd8 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -1551,12 +1551,16 @@ static void gfs2_evict_inode(struct inode *inode) goto out_truncate; } - ip->i_iopen_gh.gh_flags |= GL_NOCACHE; - gfs2_glock_dq_wait(&ip->i_iopen_gh); - gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh); - error = gfs2_glock_nq(&ip->i_iopen_gh); - if (error) - goto out_truncate; + if (ip->i_iopen_gh.gh_gl && + test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) { + ip->i_iopen_gh.gh_flags |= GL_NOCACHE; + gfs2_glock_dq_wait(&ip->i_iopen_gh); + gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, + &ip->i_iopen_gh); + error = gfs2_glock_nq(&ip->i_iopen_gh); + if (error) + goto out_truncate; + } /* Case 1 starts here */ @@ -1606,11 +1610,13 @@ out_unlock: if (gfs2_rs_active(&ip->i_res)) gfs2_rs_deltree(&ip->i_res); - if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) { - ip->i_iopen_gh.gh_flags |= GL_NOCACHE; - gfs2_glock_dq_wait(&ip->i_iopen_gh); + if (ip->i_iopen_gh.gh_gl) { + if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) { + ip->i_iopen_gh.gh_flags |= GL_NOCACHE; + gfs2_glock_dq_wait(&ip->i_iopen_gh); + } + gfs2_holder_uninit(&ip->i_iopen_gh); } - gfs2_holder_uninit(&ip->i_iopen_gh); gfs2_glock_dq_uninit(&gh); if (error && error != GLR_TRYFAILED && error != -EROFS) fs_warn(sdp, "gfs2_evict_inode: %d\n", error); ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [Cluster-devel] [GFS2 PATCH v2] GFS2: Check if iopen is held when deleting inode 2016-01-12 15:25 ` [Cluster-devel] [GFS2 PATCH v2] " Bob Peterson @ 2016-01-12 15:27 ` Steven Whitehouse 0 siblings, 0 replies; 4+ messages in thread From: Steven Whitehouse @ 2016-01-12 15:27 UTC (permalink / raw) To: cluster-devel.redhat.com Hi, Acked-by: Steven Whitehouse <swhiteho@redhat.com> Steve. On 12/01/16 15:25, Bob Peterson wrote: > Hi, > > On 18 December 2015, I posted this upstream GFS2 patch. Since that time, > I discovered a bug that warrants expanding the scope of the patch. > This is the revised patch. > > Patch description: > > GFS2: Check if iopen is held when deleting inode > > This patch fixes an error condition in which an inode is partially > created in gfs2_create_inode() but then some error is discovered, > which causes it to fail and call iput() before the iopen glock is > created or held. In that case, gfs2_delete_inode would try to > unlock an iopen glock that doesn't yet exist. Therefore, we test > its holder (which must exist) for the HIF_HOLDER bit before trying > to dq it. > > Signed-off-by: Bob Peterson <rpeterso@redhat.com> > > diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c > index 795c2f3..8dedece 100644 > --- a/fs/gfs2/glock.c > +++ b/fs/gfs2/glock.c > @@ -1015,6 +1015,7 @@ void gfs2_glock_dq(struct gfs2_holder *gh) > handle_callback(gl, LM_ST_UNLOCKED, 0, false); > > list_del_init(&gh->gh_list); > + clear_bit(HIF_HOLDER, &gh->gh_iflags); > if (find_first_holder(gl) == NULL) { > if (glops->go_unlock) { > GLOCK_BUG_ON(gl, test_and_set_bit(GLF_LOCK, &gl->gl_flags)); > diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c > index 8f960a5..f8a0cd8 100644 > --- a/fs/gfs2/super.c > +++ b/fs/gfs2/super.c > @@ -1551,12 +1551,16 @@ static void gfs2_evict_inode(struct inode *inode) > goto out_truncate; > } > > - ip->i_iopen_gh.gh_flags |= GL_NOCACHE; > - gfs2_glock_dq_wait(&ip->i_iopen_gh); > - gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh); > - error = gfs2_glock_nq(&ip->i_iopen_gh); > - if (error) > - goto out_truncate; > + if (ip->i_iopen_gh.gh_gl && > + test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) { > + ip->i_iopen_gh.gh_flags |= GL_NOCACHE; > + gfs2_glock_dq_wait(&ip->i_iopen_gh); > + gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, > + &ip->i_iopen_gh); > + error = gfs2_glock_nq(&ip->i_iopen_gh); > + if (error) > + goto out_truncate; > + } > > /* Case 1 starts here */ > > @@ -1606,11 +1610,13 @@ out_unlock: > if (gfs2_rs_active(&ip->i_res)) > gfs2_rs_deltree(&ip->i_res); > > - if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) { > - ip->i_iopen_gh.gh_flags |= GL_NOCACHE; > - gfs2_glock_dq_wait(&ip->i_iopen_gh); > + if (ip->i_iopen_gh.gh_gl) { > + if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) { > + ip->i_iopen_gh.gh_flags |= GL_NOCACHE; > + gfs2_glock_dq_wait(&ip->i_iopen_gh); > + } > + gfs2_holder_uninit(&ip->i_iopen_gh); > } > - gfs2_holder_uninit(&ip->i_iopen_gh); > gfs2_glock_dq_uninit(&gh); > if (error && error != GLR_TRYFAILED && error != -EROFS) > fs_warn(sdp, "gfs2_evict_inode: %d\n", error); > ^ permalink raw reply [flat|nested] 4+ messages in thread
* [Cluster-devel] [GFS2 PATCH] GFS2: Check if iopen is held when deleting inode 2015-12-18 18:38 ` [Cluster-devel] [GFS2 PATCH] GFS2: Check if iopen is held when deleting inode Bob Peterson 2016-01-12 15:25 ` [Cluster-devel] [GFS2 PATCH v2] " Bob Peterson @ 2016-02-02 11:56 ` Steven Whitehouse 1 sibling, 0 replies; 4+ messages in thread From: Steven Whitehouse @ 2016-02-02 11:56 UTC (permalink / raw) To: cluster-devel.redhat.com Hi, Acked-by: Steven Whitehouse <swhiteho@redhat.com> Steve. On 18/12/15 18:38, Bob Peterson wrote: > Hi, > > This patch fixes an error condition in which an inode is partially > created in gfs2_create_inode() but then some error is discovered, > which causes it to fail and call iput() before the iopen glock is > created or held. In that case, gfs2_delete_inode would try to > unlock an iopen glock that doesn't yet exist. Therefore, we test > its holder (which must exist) for the HIF_HOLDER bit before trying > to dq it. > > Signed-off-by: Bob Peterson <rpeterso@redhat.com> > > diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c > index 8f960a5..d354e72 100644 > --- a/fs/gfs2/super.c > +++ b/fs/gfs2/super.c > @@ -1551,12 +1551,15 @@ static void gfs2_evict_inode(struct inode *inode) > goto out_truncate; > } > > - ip->i_iopen_gh.gh_flags |= GL_NOCACHE; > - gfs2_glock_dq_wait(&ip->i_iopen_gh); > - gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, &ip->i_iopen_gh); > - error = gfs2_glock_nq(&ip->i_iopen_gh); > - if (error) > - goto out_truncate; > + if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) { > + ip->i_iopen_gh.gh_flags |= GL_NOCACHE; > + gfs2_glock_dq_wait(&ip->i_iopen_gh); > + gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | GL_NOCACHE, > + &ip->i_iopen_gh); > + error = gfs2_glock_nq(&ip->i_iopen_gh); > + if (error) > + goto out_truncate; > + } > > /* Case 1 starts here */ > > ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2016-02-02 11:56 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <747868619.36036602.1450463887728.JavaMail.zimbra@redhat.com>
2015-12-18 18:38 ` [Cluster-devel] [GFS2 PATCH] GFS2: Check if iopen is held when deleting inode Bob Peterson
2016-01-12 15:25 ` [Cluster-devel] [GFS2 PATCH v2] " Bob Peterson
2016-01-12 15:27 ` Steven Whitehouse
2016-02-02 11:56 ` [Cluster-devel] [GFS2 PATCH] " Steven Whitehouse
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).