summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjohn stultz <johnstul@us.ibm.com>2010-06-04 15:32:19 -0700
committerThomas Gleixner <tglx@linutronix.de>2010-06-08 20:02:30 +0200
commitbdeadaf2f7daf6c098e83506d4d99142ca3912f8 (patch)
tree9f7f69d68375190321eb340573fc996c8fa5eac1
parent697684652c217b241a07d9e261c7a20e9b072d43 (diff)
downloadlwn-bdeadaf2f7daf6c098e83506d4d99142ca3912f8.tar.gz
lwn-bdeadaf2f7daf6c098e83506d4d99142ca3912f8.zip
nfs: Avoid igrab deadlock.
On Fri, 2010-05-21 at 11:04 -0400, Jan Kansky wrote: > It's crashing when I try to login as a user that has a nfs4 mounted home > directory. See attached. > > I saw the discussion here: > > http://kerneltrap.org/mailarchive/linux-kernel/2010/5/7/4566886/thread > > That patch you mentioned there is already included in 2.6.33.4, and yet > I still see: > > kernel BUG at kernel/rtmutex.c:808! So the issue is nfs4_get_open_state() is calling igrab() while holding the inode->i_lock. With the vfs scalability patches, igrab() takes that lock as well, so we deadlock. I believe the following resolves the issue, however I'm not sure if its totally correct or not, since I'm not totally sure if the __iget() rules. With this patch, Jan Kansky (the original reporter) still had booting issues, but was unable to provide details. However, this patch has been tested by John Kacur and resolves the hang for him, however we still see MNT_MOUNTED WARN_ONs that I'm still trying to decide how to fix, but are otherwise harmless. Signed-off-by: John Stultz <johnstul@us.ibm.com> Cc: "Luis Claudio R. Goncalves" <lclaudio@uudg.org> Cc: Nick Piggin <npiggin@suse.de> Cc: Jan Kansky <kansky@ll.mit.edu> Cc: John Kacur <jkacur@redhat.com> Cc: Clark Williams <williams@redhat.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--fs/nfs/nfs4state.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index c1e2733f4fa4..7ae43df98d04 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -501,7 +501,8 @@ nfs4_get_open_state(struct inode *inode, struct nfs4_state_owner *owner)
state->owner = owner;
atomic_inc(&owner->so_count);
list_add(&state->inode_states, &nfsi->open_states);
- state->inode = igrab(inode);
+ __iget(inode);
+ state->inode = inode;
spin_unlock(&inode->i_lock);
/* Note: The reclaim code dictates that we add stateless
* and read-only stateids to the end of the list */