* [PATCH] gfs2: Fix deadlock between gfs2_create_inode and delete_work_func
@ 2020-11-30 19:44 ` Andreas Gruenbacher
0 siblings, 0 replies; 4+ messages in thread
From: Andreas Gruenbacher @ 2020-11-30 19:44 UTC (permalink / raw)
To: cluster-devel; +Cc: Andreas Gruenbacher, Alexander Aring, stable
In gfs2_create_inode, make sure to cancel any pending delete work before
locking the inode glock. Otherwise, gfs2_cancel_delete_work may block
waiting for delete_work_func to complete, and delete_work_func may block
trying to acquire the inode glock in gfs2_inode_lookup.
Reported-by: Alexander Aring <aahringo@redhat.com>
Fixes: a0e3cc65fa29 ("gfs2: Turn gl_delete into a delayed work")
Cc: stable@vger.kernel.org # v5.8+
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
fs/gfs2/inode.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index eed1a1bac6f6..3b9e8c99293c 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -725,13 +725,19 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
flush_delayed_work(&ip->i_gl->gl_work);
glock_set_object(ip->i_gl, ip);
- error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1);
+ error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
if (error)
goto fail_free_inode;
+ gfs2_cancel_delete_work(io_gl);
+ glock_set_object(io_gl, ip);
+
+ error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1);
+ if (error)
+ goto fail_gunlock2;
error = gfs2_trans_begin(sdp, blocks, 0);
if (error)
- goto fail_free_inode;
+ goto fail_gunlock2;
if (blocks > 1) {
ip->i_eattr = ip->i_no_addr + 1;
@@ -740,18 +746,12 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
init_dinode(dip, ip, symname);
gfs2_trans_end(sdp);
- error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
- if (error)
- goto fail_free_inode;
-
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;
- gfs2_cancel_delete_work(ip->i_iopen_gh.gh_gl);
- glock_set_object(ip->i_iopen_gh.gh_gl, ip);
gfs2_set_iop(inode);
insert_inode_hash(inode);
@@ -803,6 +803,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
gfs2_glock_dq_uninit(&ip->i_iopen_gh);
fail_gunlock2:
clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags);
+ glock_clear_object(io_gl, ip);
gfs2_glock_put(io_gl);
fail_free_inode:
if (ip->i_gl) {
--
2.26.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [Cluster-devel] [PATCH] gfs2: Fix deadlock between gfs2_create_inode and delete_work_func
@ 2020-11-30 19:44 ` Andreas Gruenbacher
0 siblings, 0 replies; 4+ messages in thread
From: Andreas Gruenbacher @ 2020-11-30 19:44 UTC (permalink / raw)
To: cluster-devel.redhat.com
In gfs2_create_inode, make sure to cancel any pending delete work before
locking the inode glock. Otherwise, gfs2_cancel_delete_work may block
waiting for delete_work_func to complete, and delete_work_func may block
trying to acquire the inode glock in gfs2_inode_lookup.
Reported-by: Alexander Aring <aahringo@redhat.com>
Fixes: a0e3cc65fa29 ("gfs2: Turn gl_delete into a delayed work")
Cc: stable at vger.kernel.org # v5.8+
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
---
fs/gfs2/inode.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index eed1a1bac6f6..3b9e8c99293c 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -725,13 +725,19 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
flush_delayed_work(&ip->i_gl->gl_work);
glock_set_object(ip->i_gl, ip);
- error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1);
+ error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
if (error)
goto fail_free_inode;
+ gfs2_cancel_delete_work(io_gl);
+ glock_set_object(io_gl, ip);
+
+ error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1);
+ if (error)
+ goto fail_gunlock2;
error = gfs2_trans_begin(sdp, blocks, 0);
if (error)
- goto fail_free_inode;
+ goto fail_gunlock2;
if (blocks > 1) {
ip->i_eattr = ip->i_no_addr + 1;
@@ -740,18 +746,12 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
init_dinode(dip, ip, symname);
gfs2_trans_end(sdp);
- error = gfs2_glock_get(sdp, ip->i_no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
- if (error)
- goto fail_free_inode;
-
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;
- gfs2_cancel_delete_work(ip->i_iopen_gh.gh_gl);
- glock_set_object(ip->i_iopen_gh.gh_gl, ip);
gfs2_set_iop(inode);
insert_inode_hash(inode);
@@ -803,6 +803,7 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
gfs2_glock_dq_uninit(&ip->i_iopen_gh);
fail_gunlock2:
clear_bit(GLF_INODE_CREATING, &io_gl->gl_flags);
+ glock_clear_object(io_gl, ip);
gfs2_glock_put(io_gl);
fail_free_inode:
if (ip->i_gl) {
--
2.26.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] gfs2: Fix deadlock between gfs2_create_inode and delete_work_func
2020-11-30 19:44 ` [Cluster-devel] " Andreas Gruenbacher
@ 2020-11-30 23:28 ` Andreas Gruenbacher
-1 siblings, 0 replies; 4+ messages in thread
From: Andreas Gruenbacher @ 2020-11-30 23:28 UTC (permalink / raw)
To: cluster-devel; +Cc: Alexander Aring, stable
On Mon, Nov 30, 2020 at 8:44 PM Andreas Gruenbacher <agruenba@redhat.com> wrote:
> In gfs2_create_inode, make sure to cancel any pending delete work before
> locking the inode glock. Otherwise, gfs2_cancel_delete_work may block
> waiting for delete_work_func to complete, and delete_work_func may block
> trying to acquire the inode glock in gfs2_inode_lookup.
(Please see version 2 of this patch.)
Thanks,
Andreas
^ permalink raw reply [flat|nested] 4+ messages in thread
* [Cluster-devel] [PATCH] gfs2: Fix deadlock between gfs2_create_inode and delete_work_func
@ 2020-11-30 23:28 ` Andreas Gruenbacher
0 siblings, 0 replies; 4+ messages in thread
From: Andreas Gruenbacher @ 2020-11-30 23:28 UTC (permalink / raw)
To: cluster-devel.redhat.com
On Mon, Nov 30, 2020 at 8:44 PM Andreas Gruenbacher <agruenba@redhat.com> wrote:
> In gfs2_create_inode, make sure to cancel any pending delete work before
> locking the inode glock. Otherwise, gfs2_cancel_delete_work may block
> waiting for delete_work_func to complete, and delete_work_func may block
> trying to acquire the inode glock in gfs2_inode_lookup.
(Please see version 2 of this patch.)
Thanks,
Andreas
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2020-11-30 23:30 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-30 19:44 [PATCH] gfs2: Fix deadlock between gfs2_create_inode and delete_work_func Andreas Gruenbacher
2020-11-30 19:44 ` [Cluster-devel] " Andreas Gruenbacher
2020-11-30 23:28 ` Andreas Gruenbacher
2020-11-30 23:28 ` [Cluster-devel] " Andreas Gruenbacher
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.