Gitweb:
http://git.fedorahosted.org/git/?p=cluster.git;a=commitdiff;h=ede0a6765d5...
Commit: ede0a6765d5c9468d2b10da910c8907ccf9e5ed7
Parent: b9dd9ffc8fd3bf6baf43c2672a795a46557ad292
Author: Benjamin Marzinski <bmarzins(a)redhat.com>
AuthorDate: Fri Jun 6 14:28:02 2014 -0500
Committer: Benjamin Marzinski <bmarzins(a)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);