Commit dc46bba7 authored by J. Bruce Fields's avatar J. Bruce Fields

nfsd: use i_wrlock instead of rcu for nfsdfs i_private

synchronize_rcu() gets called multiple times each time a client is
destroyed.  If the laundromat thread has a lot of clients to destroy,
the delay can be noticeable.  This was causing pynfs test RENEW3 to
fail.

We could embed an rcu_head in each inode and do the kref_put in an rcu
callback.  But simplest is just to take a lock here.

(I also wonder if the laundromat thread would be better replaced by a
bunch of scheduled work or timers or something.)
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent d6846bfb
...@@ -1215,11 +1215,9 @@ static void clear_ncl(struct inode *inode) ...@@ -1215,11 +1215,9 @@ static void clear_ncl(struct inode *inode)
struct nfsdfs_client *ncl = inode->i_private; struct nfsdfs_client *ncl = inode->i_private;
inode->i_private = NULL; inode->i_private = NULL;
synchronize_rcu();
kref_put(&ncl->cl_ref, ncl->cl_release); kref_put(&ncl->cl_ref, ncl->cl_release);
} }
static struct nfsdfs_client *__get_nfsdfs_client(struct inode *inode) static struct nfsdfs_client *__get_nfsdfs_client(struct inode *inode)
{ {
struct nfsdfs_client *nc = inode->i_private; struct nfsdfs_client *nc = inode->i_private;
...@@ -1233,9 +1231,9 @@ struct nfsdfs_client *get_nfsdfs_client(struct inode *inode) ...@@ -1233,9 +1231,9 @@ struct nfsdfs_client *get_nfsdfs_client(struct inode *inode)
{ {
struct nfsdfs_client *nc; struct nfsdfs_client *nc;
rcu_read_lock(); inode_lock_shared(inode);
nc = __get_nfsdfs_client(inode); nc = __get_nfsdfs_client(inode);
rcu_read_unlock(); inode_unlock_shared(inode);
return nc; return nc;
} }
/* from __rpc_unlink */ /* from __rpc_unlink */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment