nfsd4: Move callback setup to callback queue
Instead of creating the new rpc client from a regular server thread, set a flag, kick off a null call, and allow the null call to do the work of setting up the client on the callback workqueue. Use a spinlock to ensure the callback work gets a consistent view of the callback parameters. This allows, for example, changing the callback from contexts where sleeping is not allowed. I hope it will also keep the locking simple as we add more session and trunking features, by serializing most of the callback-specific work. This also closes a small race where the the new cb_ident could be used with an old connection (or vice-versa). Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
This commit is contained in:
committed by
J. Bruce Fields
parent
fb00392326
commit
6ff8da0887
@ -84,7 +84,6 @@ struct nfs4_delegation {
|
||||
u32 dl_type;
|
||||
time_t dl_time;
|
||||
/* For recall: */
|
||||
u32 dl_ident;
|
||||
stateid_t dl_stateid;
|
||||
struct knfsd_fh dl_fh;
|
||||
int dl_retries;
|
||||
@ -217,10 +216,17 @@ struct nfs4_client {
|
||||
|
||||
/* for v4.0 and v4.1 callbacks: */
|
||||
struct nfs4_cb_conn cl_cb_conn;
|
||||
#define NFSD4_CLIENT_CB_UPDATE 1
|
||||
#define NFSD4_CLIENT_KILL 2
|
||||
unsigned long cl_cb_flags;
|
||||
struct rpc_clnt *cl_cb_client;
|
||||
u32 cl_cb_ident;
|
||||
atomic_t cl_cb_set;
|
||||
struct nfsd4_callback cl_cb_null;
|
||||
|
||||
/* for all client information that callback code might need: */
|
||||
spinlock_t cl_lock;
|
||||
|
||||
/* for nfs41 */
|
||||
struct list_head cl_sessions;
|
||||
struct nfsd4_clid_slot cl_cs_slot; /* create_session slot */
|
||||
@ -439,7 +445,7 @@ extern void nfsd4_do_callback_rpc(struct work_struct *);
|
||||
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_set_callback_client(struct nfs4_client *, struct rpc_clnt *);
|
||||
extern void nfsd4_shutdown_callback(struct nfs4_client *);
|
||||
extern void nfs4_put_delegation(struct nfs4_delegation *dp);
|
||||
extern __be32 nfs4_make_rec_clidname(char *clidname, struct xdr_netobj *clname);
|
||||
extern void nfsd4_init_recdir(char *recdir_name);
|
||||
|
Reference in New Issue
Block a user