nfsd: don't hold i_mutex over userspace upcalls
authorNeilBrown <neilb@suse.de>
Thu, 7 Jan 2016 21:08:20 +0000 (16:08 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Sat, 9 Jan 2016 08:07:52 +0000 (03:07 -0500)
commitbbddca8e8fac07ece3938e03526b5d00fa791a4c
tree5fbe9fe5251f1040bb001377260c56f7330e0459
parentdb39c16724d019029d7533561754d92bef1b389a
nfsd: don't hold i_mutex over userspace upcalls

We need information about exports when crossing mountpoints during
lookup or NFSv4 readdir.  If we don't already have that information
cached, we may have to ask (and wait for) rpc.mountd.

In both cases we currently hold the i_mutex on the parent of the
directory we're asking rpc.mountd about.  We've seen situations where
rpc.mountd performs some operation on that directory that tries to take
the i_mutex again, resulting in deadlock.

With some care, we may be able to avoid that in rpc.mountd.  But it
seems better just to avoid holding a mutex while waiting on userspace.

It appears that lookup_one_len is pretty much the only operation that
needs the i_mutex.  So we could just drop the i_mutex elsewhere and do
something like

mutex_lock()
lookup_one_len()
mutex_unlock()

In many cases though the lookup would have been cached and not required
the i_mutex, so it's more efficient to create a lookup_one_len() variant
that only takes the i_mutex when necessary.

Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/namei.c
fs/nfsd/nfs3xdr.c
fs/nfsd/nfs4xdr.c
fs/nfsd/vfs.c
include/linux/namei.h