Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+2 -4
+2 -4
fs/nfsd/nfsctl.c
··· 1215 1215 struct nfsdfs_client *ncl = inode->i_private; 1216 1216 1217 1217 inode->i_private = NULL; 1218 - synchronize_rcu(); 1219 1218 kref_put(&ncl->cl_ref, ncl->cl_release); 1220 1219 } 1221 - 1222 1220 1223 1221 static struct nfsdfs_client *__get_nfsdfs_client(struct inode *inode) 1224 1222 { ··· 1231 1233 { 1232 1234 struct nfsdfs_client *nc; 1233 1235 1234 - rcu_read_lock(); 1236 + inode_lock_shared(inode); 1235 1237 nc = __get_nfsdfs_client(inode); 1236 - rcu_read_unlock(); 1238 + inode_unlock_shared(inode); 1237 1239 return nc; 1238 1240 } 1239 1241 /* from __rpc_unlink */