mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 20:51:03 +02:00
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: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
@@ -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)
|
|||||||
{
|
{
|
||||||
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 */
|
||||||
|
Reference in New Issue
Block a user