nfsd: Avoid taking state_lock while holding inode lock in nfsd_break_one_deleg
authorJeff Layton <jlayton@primarydata.com>
Wed, 16 Jul 2014 14:31:57 +0000 (10:31 -0400)
committerJ. Bruce Fields <bfields@redhat.com>
Thu, 17 Jul 2014 01:06:12 +0000 (21:06 -0400)
commit02e1215f9f72ad8c087e21a5701bea0ac18fafd4
tree26b317c316a0d37e04ac1d81116d61cfe7138f3e
parente8051c837bd96ad1eabdd46504363431dc5fddc5
nfsd: Avoid taking state_lock while holding inode lock in nfsd_break_one_deleg

state_lock is a heavily contended global lock. We don't want to grab
that while simultaneously holding the inode->i_lock.

Add a new per-nfs4_file lock that we can use to protect the
per-nfs4_file delegation list. Hold that while walking the list in the
break_deleg callback and queue the workqueue job for each one.

The workqueue job can then take the state_lock and do the list
manipulations without the i_lock being held prior to starting the
rpc call.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
fs/nfsd/nfs4callback.c
fs/nfsd/nfs4state.c
fs/nfsd/state.h