diff options
author | Jeff Layton <jlayton@primarydata.com> | 2014-07-16 16:31:57 +0200 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2014-07-17 03:06:12 +0200 |
commit | 02e1215f9f72ad8c087e21a5701bea0ac18fafd4 (patch) | |
tree | 26b317c316a0d37e04ac1d81116d61cfe7138f3e /fs/nfsd/state.h | |
parent | nfsd: eliminate nfsd4_init_callback (diff) | |
download | linux-02e1215f9f72ad8c087e21a5701bea0ac18fafd4.tar.xz linux-02e1215f9f72ad8c087e21a5701bea0ac18fafd4.zip |
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>
Diffstat (limited to 'fs/nfsd/state.h')
-rw-r--r-- | fs/nfsd/state.h | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 20857142773f..81b7522e3f67 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -436,7 +436,8 @@ extern struct nfs4_client_reclaim *nfsd4_find_reclaim_client(const char *recdir, extern __be32 nfs4_check_open_reclaim(clientid_t *clid, struct nfsd4_compound_state *cstate, struct nfsd_net *nn); extern int set_callback_cred(void); -void nfsd4_do_callback_rpc(struct work_struct *w); +void nfsd4_run_cb_null(struct work_struct *w); +void nfsd4_run_cb_recall(struct work_struct *w); extern void nfsd4_probe_callback(struct nfs4_client *clp); extern void nfsd4_probe_callback_sync(struct nfs4_client *clp); extern void nfsd4_change_callback(struct nfs4_client *clp, struct nfs4_cb_conn *); @@ -444,6 +445,7 @@ extern void nfsd4_cb_recall(struct nfs4_delegation *dp); extern int nfsd4_create_callback_queue(void); extern void nfsd4_destroy_callback_queue(void); extern void nfsd4_shutdown_callback(struct nfs4_client *); +extern void nfsd4_prepare_cb_recall(struct nfs4_delegation *dp); extern void nfs4_put_delegation(struct nfs4_delegation *dp); extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(const char *name, struct nfsd_net *nn); |