diff options
Diffstat (limited to 'fs/nfsd/state.h')
-rw-r--r-- | fs/nfsd/state.h | 87 |
1 files changed, 76 insertions, 11 deletions
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index fefeae27f25e..7731a75971dd 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h | |||
@@ -70,6 +70,16 @@ struct nfsd4_cb_sequence { | |||
70 | struct nfs4_client *cbs_clp; | 70 | struct nfs4_client *cbs_clp; |
71 | }; | 71 | }; |
72 | 72 | ||
73 | struct nfs4_rpc_args { | ||
74 | void *args_op; | ||
75 | struct nfsd4_cb_sequence args_seq; | ||
76 | }; | ||
77 | |||
78 | struct nfsd4_callback { | ||
79 | struct nfs4_rpc_args cb_args; | ||
80 | struct work_struct cb_work; | ||
81 | }; | ||
82 | |||
73 | struct nfs4_delegation { | 83 | struct nfs4_delegation { |
74 | struct list_head dl_perfile; | 84 | struct list_head dl_perfile; |
75 | struct list_head dl_perclnt; | 85 | struct list_head dl_perclnt; |
@@ -78,7 +88,6 @@ struct nfs4_delegation { | |||
78 | struct nfs4_client *dl_client; | 88 | struct nfs4_client *dl_client; |
79 | struct nfs4_file *dl_file; | 89 | struct nfs4_file *dl_file; |
80 | struct file_lock *dl_flock; | 90 | struct file_lock *dl_flock; |
81 | struct file *dl_vfs_file; | ||
82 | u32 dl_type; | 91 | u32 dl_type; |
83 | time_t dl_time; | 92 | time_t dl_time; |
84 | /* For recall: */ | 93 | /* For recall: */ |
@@ -86,6 +95,7 @@ struct nfs4_delegation { | |||
86 | stateid_t dl_stateid; | 95 | stateid_t dl_stateid; |
87 | struct knfsd_fh dl_fh; | 96 | struct knfsd_fh dl_fh; |
88 | int dl_retries; | 97 | int dl_retries; |
98 | struct nfsd4_callback dl_recall; | ||
89 | }; | 99 | }; |
90 | 100 | ||
91 | /* client delegation callback info */ | 101 | /* client delegation callback info */ |
@@ -96,9 +106,7 @@ struct nfs4_cb_conn { | |||
96 | u32 cb_prog; | 106 | u32 cb_prog; |
97 | u32 cb_minorversion; | 107 | u32 cb_minorversion; |
98 | u32 cb_ident; /* minorversion 0 only */ | 108 | u32 cb_ident; /* minorversion 0 only */ |
99 | /* RPC client info */ | 109 | struct svc_xprt *cb_xprt; /* minorversion 1 only */ |
100 | atomic_t cb_set; /* successful CB_NULL call */ | ||
101 | struct rpc_clnt * cb_client; | ||
102 | }; | 110 | }; |
103 | 111 | ||
104 | /* Maximum number of slots per session. 160 is useful for long haul TCP */ | 112 | /* Maximum number of slots per session. 160 is useful for long haul TCP */ |
@@ -157,7 +165,7 @@ struct nfsd4_session { | |||
157 | struct list_head se_hash; /* hash by sessionid */ | 165 | struct list_head se_hash; /* hash by sessionid */ |
158 | struct list_head se_perclnt; | 166 | struct list_head se_perclnt; |
159 | u32 se_flags; | 167 | u32 se_flags; |
160 | struct nfs4_client *se_client; /* for expire_client */ | 168 | struct nfs4_client *se_client; |
161 | struct nfs4_sessionid se_sessionid; | 169 | struct nfs4_sessionid se_sessionid; |
162 | struct nfsd4_channel_attrs se_fchannel; | 170 | struct nfsd4_channel_attrs se_fchannel; |
163 | struct nfsd4_channel_attrs se_bchannel; | 171 | struct nfsd4_channel_attrs se_bchannel; |
@@ -212,25 +220,41 @@ struct nfs4_client { | |||
212 | struct svc_cred cl_cred; /* setclientid principal */ | 220 | struct svc_cred cl_cred; /* setclientid principal */ |
213 | clientid_t cl_clientid; /* generated by server */ | 221 | clientid_t cl_clientid; /* generated by server */ |
214 | nfs4_verifier cl_confirm; /* generated by server */ | 222 | nfs4_verifier cl_confirm; /* generated by server */ |
215 | struct nfs4_cb_conn cl_cb_conn; /* callback info */ | ||
216 | atomic_t cl_count; /* ref count */ | ||
217 | u32 cl_firststate; /* recovery dir creation */ | 223 | u32 cl_firststate; /* recovery dir creation */ |
218 | 224 | ||
225 | /* for v4.0 and v4.1 callbacks: */ | ||
226 | struct nfs4_cb_conn cl_cb_conn; | ||
227 | struct rpc_clnt *cl_cb_client; | ||
228 | atomic_t cl_cb_set; | ||
229 | |||
219 | /* for nfs41 */ | 230 | /* for nfs41 */ |
220 | struct list_head cl_sessions; | 231 | struct list_head cl_sessions; |
221 | struct nfsd4_clid_slot cl_cs_slot; /* create_session slot */ | 232 | struct nfsd4_clid_slot cl_cs_slot; /* create_session slot */ |
222 | u32 cl_exchange_flags; | 233 | u32 cl_exchange_flags; |
223 | struct nfs4_sessionid cl_sessionid; | 234 | struct nfs4_sessionid cl_sessionid; |
235 | /* number of rpc's in progress over an associated session: */ | ||
236 | atomic_t cl_refcount; | ||
224 | 237 | ||
225 | /* for nfs41 callbacks */ | 238 | /* for nfs41 callbacks */ |
226 | /* We currently support a single back channel with a single slot */ | 239 | /* We currently support a single back channel with a single slot */ |
227 | unsigned long cl_cb_slot_busy; | 240 | unsigned long cl_cb_slot_busy; |
228 | u32 cl_cb_seq_nr; | 241 | u32 cl_cb_seq_nr; |
229 | struct svc_xprt *cl_cb_xprt; /* 4.1 callback transport */ | ||
230 | struct rpc_wait_queue cl_cb_waitq; /* backchannel callers may */ | 242 | struct rpc_wait_queue cl_cb_waitq; /* backchannel callers may */ |
231 | /* wait here for slots */ | 243 | /* wait here for slots */ |
232 | }; | 244 | }; |
233 | 245 | ||
246 | static inline void | ||
247 | mark_client_expired(struct nfs4_client *clp) | ||
248 | { | ||
249 | clp->cl_time = 0; | ||
250 | } | ||
251 | |||
252 | static inline bool | ||
253 | is_client_expired(struct nfs4_client *clp) | ||
254 | { | ||
255 | return clp->cl_time == 0; | ||
256 | } | ||
257 | |||
234 | /* struct nfs4_client_reset | 258 | /* struct nfs4_client_reset |
235 | * one per old client. Populates reset_str_hashtbl. Filled from conf_id_hashtbl | 259 | * one per old client. Populates reset_str_hashtbl. Filled from conf_id_hashtbl |
236 | * upon lease reset, or from upcall to state_daemon (to read in state | 260 | * upon lease reset, or from upcall to state_daemon (to read in state |
@@ -317,12 +341,50 @@ struct nfs4_file { | |||
317 | struct list_head fi_hash; /* hash by "struct inode *" */ | 341 | struct list_head fi_hash; /* hash by "struct inode *" */ |
318 | struct list_head fi_stateids; | 342 | struct list_head fi_stateids; |
319 | struct list_head fi_delegations; | 343 | struct list_head fi_delegations; |
344 | /* One each for O_RDONLY, O_WRONLY, O_RDWR: */ | ||
345 | struct file * fi_fds[3]; | ||
346 | /* One each for O_RDONLY, O_WRONLY: */ | ||
347 | atomic_t fi_access[2]; | ||
348 | /* | ||
349 | * Each open stateid contributes 1 to either fi_readers or | ||
350 | * fi_writers, or both, depending on the open mode. A | ||
351 | * delegation also takes an fi_readers reference. Lock | ||
352 | * stateid's take none. | ||
353 | */ | ||
354 | atomic_t fi_readers; | ||
355 | atomic_t fi_writers; | ||
320 | struct inode *fi_inode; | 356 | struct inode *fi_inode; |
321 | u32 fi_id; /* used with stateowner->so_id | 357 | u32 fi_id; /* used with stateowner->so_id |
322 | * for stateid_hashtbl hash */ | 358 | * for stateid_hashtbl hash */ |
323 | bool fi_had_conflict; | 359 | bool fi_had_conflict; |
324 | }; | 360 | }; |
325 | 361 | ||
362 | /* XXX: for first cut may fall back on returning file that doesn't work | ||
363 | * at all? */ | ||
364 | static inline struct file *find_writeable_file(struct nfs4_file *f) | ||
365 | { | ||
366 | if (f->fi_fds[O_RDWR]) | ||
367 | return f->fi_fds[O_RDWR]; | ||
368 | return f->fi_fds[O_WRONLY]; | ||
369 | } | ||
370 | |||
371 | static inline struct file *find_readable_file(struct nfs4_file *f) | ||
372 | { | ||
373 | if (f->fi_fds[O_RDWR]) | ||
374 | return f->fi_fds[O_RDWR]; | ||
375 | return f->fi_fds[O_RDONLY]; | ||
376 | } | ||
377 | |||
378 | static inline struct file *find_any_file(struct nfs4_file *f) | ||
379 | { | ||
380 | if (f->fi_fds[O_RDWR]) | ||
381 | return f->fi_fds[O_RDWR]; | ||
382 | else if (f->fi_fds[O_RDWR]) | ||
383 | return f->fi_fds[O_WRONLY]; | ||
384 | else | ||
385 | return f->fi_fds[O_RDONLY]; | ||
386 | } | ||
387 | |||
326 | /* | 388 | /* |
327 | * nfs4_stateid can either be an open stateid or (eventually) a lock stateid | 389 | * nfs4_stateid can either be an open stateid or (eventually) a lock stateid |
328 | * | 390 | * |
@@ -348,7 +410,6 @@ struct nfs4_stateid { | |||
348 | struct nfs4_stateowner * st_stateowner; | 410 | struct nfs4_stateowner * st_stateowner; |
349 | struct nfs4_file * st_file; | 411 | struct nfs4_file * st_file; |
350 | stateid_t st_stateid; | 412 | stateid_t st_stateid; |
351 | struct file * st_vfs_file; | ||
352 | unsigned long st_access_bmap; | 413 | unsigned long st_access_bmap; |
353 | unsigned long st_deny_bmap; | 414 | unsigned long st_deny_bmap; |
354 | struct nfs4_stateid * st_openstp; | 415 | struct nfs4_stateid * st_openstp; |
@@ -377,11 +438,14 @@ extern void nfs4_lock_state(void); | |||
377 | extern void nfs4_unlock_state(void); | 438 | extern void nfs4_unlock_state(void); |
378 | extern int nfs4_in_grace(void); | 439 | extern int nfs4_in_grace(void); |
379 | extern __be32 nfs4_check_open_reclaim(clientid_t *clid); | 440 | extern __be32 nfs4_check_open_reclaim(clientid_t *clid); |
380 | extern void put_nfs4_client(struct nfs4_client *clp); | ||
381 | extern void nfs4_free_stateowner(struct kref *kref); | 441 | extern void nfs4_free_stateowner(struct kref *kref); |
382 | extern int set_callback_cred(void); | 442 | extern int set_callback_cred(void); |
383 | extern void nfsd4_probe_callback(struct nfs4_client *clp); | 443 | extern void nfsd4_probe_callback(struct nfs4_client *clp, struct nfs4_cb_conn *); |
444 | extern void nfsd4_do_callback_rpc(struct work_struct *); | ||
384 | extern void nfsd4_cb_recall(struct nfs4_delegation *dp); | 445 | extern void nfsd4_cb_recall(struct nfs4_delegation *dp); |
446 | extern int nfsd4_create_callback_queue(void); | ||
447 | extern void nfsd4_destroy_callback_queue(void); | ||
448 | extern void nfsd4_set_callback_client(struct nfs4_client *, struct rpc_clnt *); | ||
385 | extern void nfs4_put_delegation(struct nfs4_delegation *dp); | 449 | extern void nfs4_put_delegation(struct nfs4_delegation *dp); |
386 | extern __be32 nfs4_make_rec_clidname(char *clidname, struct xdr_netobj *clname); | 450 | extern __be32 nfs4_make_rec_clidname(char *clidname, struct xdr_netobj *clname); |
387 | extern void nfsd4_init_recdir(char *recdir_name); | 451 | extern void nfsd4_init_recdir(char *recdir_name); |
@@ -392,6 +456,7 @@ extern int nfs4_has_reclaimed_state(const char *name, bool use_exchange_id); | |||
392 | extern void nfsd4_recdir_purge_old(void); | 456 | extern void nfsd4_recdir_purge_old(void); |
393 | extern int nfsd4_create_clid_dir(struct nfs4_client *clp); | 457 | extern int nfsd4_create_clid_dir(struct nfs4_client *clp); |
394 | extern void nfsd4_remove_clid_dir(struct nfs4_client *clp); | 458 | extern void nfsd4_remove_clid_dir(struct nfs4_client *clp); |
459 | extern void release_session_client(struct nfsd4_session *); | ||
395 | 460 | ||
396 | static inline void | 461 | static inline void |
397 | nfs4_put_stateowner(struct nfs4_stateowner *so) | 462 | nfs4_put_stateowner(struct nfs4_stateowner *so) |