Skip to content

Commit 29464ee

Browse files
author
Andreas Gruenbacher
committed
gfs2: Switch lock order of inode and iopen glock
This patch tries to fix the continual ABBA deadlocks we keep having between the iopen and inode glocks. This switches the lock order in gfs2_inode_lookup and gfs2_create_inode so the iopen glock is always locked first. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: Bob Peterson <rpeterso@redhat.com>
1 parent 1fc05c8 commit 29464ee

1 file changed

Lines changed: 27 additions & 22 deletions

File tree

fs/gfs2/inode.c

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,21 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
131131
struct gfs2_sbd *sdp = GFS2_SB(inode);
132132
struct gfs2_glock *io_gl;
133133

134-
error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE, &ip->i_gl);
134+
error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE,
135+
&ip->i_gl);
136+
if (unlikely(error))
137+
goto fail;
138+
139+
error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE,
140+
&io_gl);
141+
if (unlikely(error))
142+
goto fail;
143+
144+
if (blktype != GFS2_BLKST_UNLINKED)
145+
gfs2_cancel_delete_work(io_gl);
146+
error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT,
147+
&ip->i_iopen_gh);
148+
gfs2_glock_put(io_gl);
135149
if (unlikely(error))
136150
goto fail;
137151

@@ -161,16 +175,6 @@ struct inode *gfs2_inode_lookup(struct super_block *sb, unsigned int type,
161175

162176
set_bit(GLF_INSTANTIATE_NEEDED, &ip->i_gl->gl_flags);
163177

164-
error = gfs2_glock_get(sdp, no_addr, &gfs2_iopen_glops, CREATE, &io_gl);
165-
if (unlikely(error))
166-
goto fail;
167-
if (blktype != GFS2_BLKST_UNLINKED)
168-
gfs2_cancel_delete_work(io_gl);
169-
error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh);
170-
gfs2_glock_put(io_gl);
171-
if (unlikely(error))
172-
goto fail;
173-
174178
/* Lowest possible timestamp; will be overwritten in gfs2_dinode_in. */
175179
inode->i_atime.tv_sec = 1LL << (8 * sizeof(inode->i_atime.tv_sec) - 1);
176180
inode->i_atime.tv_nsec = 0;
@@ -716,13 +720,17 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
716720
error = insert_inode_locked4(inode, ip->i_no_addr, iget_test, &ip->i_no_addr);
717721
BUG_ON(error);
718722

719-
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1);
723+
error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh);
720724
if (error)
721725
goto fail_gunlock2;
722726

727+
error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_SKIP, ghs + 1);
728+
if (error)
729+
goto fail_gunlock3;
730+
723731
error = gfs2_trans_begin(sdp, blocks, 0);
724732
if (error)
725-
goto fail_gunlock2;
733+
goto fail_gunlock3;
726734

727735
if (blocks > 1) {
728736
ip->i_eattr = ip->i_no_addr + 1;
@@ -731,10 +739,6 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
731739
init_dinode(dip, ip, symname);
732740
gfs2_trans_end(sdp);
733741

734-
error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh);
735-
if (error)
736-
goto fail_gunlock2;
737-
738742
glock_set_object(ip->i_gl, ip);
739743
glock_set_object(io_gl, ip);
740744
gfs2_set_iop(inode);
@@ -745,26 +749,26 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
745749
if (default_acl) {
746750
error = __gfs2_set_acl(inode, default_acl, ACL_TYPE_DEFAULT);
747751
if (error)
748-
goto fail_gunlock3;
752+
goto fail_gunlock4;
749753
posix_acl_release(default_acl);
750754
default_acl = NULL;
751755
}
752756
if (acl) {
753757
error = __gfs2_set_acl(inode, acl, ACL_TYPE_ACCESS);
754758
if (error)
755-
goto fail_gunlock3;
759+
goto fail_gunlock4;
756760
posix_acl_release(acl);
757761
acl = NULL;
758762
}
759763

760764
error = security_inode_init_security(&ip->i_inode, &dip->i_inode, name,
761765
&gfs2_initxattrs, NULL);
762766
if (error)
763-
goto fail_gunlock3;
767+
goto fail_gunlock4;
764768

765769
error = link_dinode(dip, name, ip, &da);
766770
if (error)
767-
goto fail_gunlock3;
771+
goto fail_gunlock4;
768772

769773
mark_inode_dirty(inode);
770774
d_instantiate(dentry, inode);
@@ -782,9 +786,10 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
782786
unlock_new_inode(inode);
783787
return error;
784788

785-
fail_gunlock3:
789+
fail_gunlock4:
786790
glock_clear_object(ip->i_gl, ip);
787791
glock_clear_object(io_gl, ip);
792+
fail_gunlock3:
788793
gfs2_glock_dq_uninit(&ip->i_iopen_gh);
789794
fail_gunlock2:
790795
gfs2_glock_put(io_gl);

0 commit comments

Comments
 (0)