cluster: RHEL511 - Remove locking from gfs_write_inode

Benjamin Marzinski bmarzins at fedoraproject.org
Fri Jun 6 19:39:17 UTC 2014


Gitweb:        http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=ede0a6765d5c9468d2b10da910c8907ccf9e5ed7
Commit:        ede0a6765d5c9468d2b10da910c8907ccf9e5ed7
Parent:        b9dd9ffc8fd3bf6baf43c2672a795a46557ad292
Author:        Benjamin Marzinski <bmarzins at redhat.com>
AuthorDate:    Fri Jun 6 14:28:02 2014 -0500
Committer:     Benjamin Marzinski <bmarzins at redhat.com>
CommitterDate: Fri Jun 6 14:37:27 2014 -0500

Remove locking from gfs_write_inode

gfs_write_inode is always called with the inode locked.  When it locked
the the inode glock, it was grabbing locks in the wrong order.  This could
gfs to deadlock.  Now, gfs_write_inode never grabs a glock itself.  Instead,
it only writes the inode out to disk if it was called with the glock already
held.  Unfortunately, this means that it does not write out the inode in
many of the cases where it should.
---
 gfs-kernel/src/gfs/ops_super.c |   18 +++---------------
 1 files changed, 3 insertions(+), 15 deletions(-)

diff --git a/gfs-kernel/src/gfs/ops_super.c b/gfs-kernel/src/gfs/ops_super.c
index 10dbff7..bfb236b 100644
--- a/gfs-kernel/src/gfs/ops_super.c
+++ b/gfs-kernel/src/gfs/ops_super.c
@@ -56,29 +56,20 @@ gfs_write_inode(struct inode *inode, int sync)
 	struct gfs_inode *ip = get_v2ip(inode);
 	struct buffer_head *dibh;
 	struct gfs_holder i_gh;
-	int need_unlock = 0;
 
 	if (!ip)
 		return 0;
 
 	atomic_inc(&ip->i_sbd->sd_ops_super);
 
-	if (current->flags & PF_MEMALLOC || get_transaction)
-		goto do_flush;
-
-	if (!gfs_glock_is_locked_by_me(ip->i_gl)) {
-		ret = gfs_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &i_gh);
-		if (ret)
-			goto do_flush;
-		need_unlock = 1;
-	}
-	else if (!gfs_glock_is_held_excl(ip->i_gl))
+	if (current->flags & PF_MEMALLOC || get_transaction ||
+	    !gfs_glock_is_locked_by_me(ip->i_gl) || !gfs_glock_is_held_excl(ip->i_gl))
 		goto do_flush;
 	/* Trans may require:
 	   one dinode block. */
 	ret = gfs_trans_begin(ip->i_sbd, 1, 0);
 	if (ret)
-		goto do_unlock;
+		goto do_flush;
 
 	ret = gfs_get_inode_buffer(ip, &dibh);
 	if (ret == 0) {
@@ -90,9 +81,6 @@ gfs_write_inode(struct inode *inode, int sync)
 
 	gfs_trans_end(ip->i_sbd);
 
-do_unlock:
-	if (need_unlock)
-		gfs_glock_dq_uninit(&i_gh);
 do_flush:
 	if (sync)
 		gfs_log_flush_glock(ip->i_gl, 0);


More information about the cluster-commits mailing list