diff options
author | Alexandros Batsakis <batsakis@netapp.com> | 2009-12-05 13:27:02 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2009-12-05 13:27:02 -0500 |
commit | 31f0960778c78198957cf02cc970d92b72b929e4 (patch) | |
tree | b5d061437c4a952e0fe78006a2ad9186c2e6ecc9 | |
parent | c79571a508801e055a0be583d6dc70bddad7bb64 (diff) |
nfs41: V2 initial support for CB_RECALL_ANY
For now the clients returns _all_ the delegations of the specificed type
it holds
Signed-off-by: Alexandros Batsakis <batsakis@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | fs/nfs/callback.h | 11 | ||||
-rw-r--r-- | fs/nfs/callback_proc.c | 29 | ||||
-rw-r--r-- | fs/nfs/callback_xdr.c | 27 | ||||
-rw-r--r-- | fs/nfs/delegation.c | 2 | ||||
-rw-r--r-- | fs/nfs/delegation.h | 1 |
5 files changed, 68 insertions, 2 deletions
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h index 07baa8254ca1..0ca830984c4b 100644 --- a/fs/nfs/callback.h +++ b/fs/nfs/callback.h | |||
@@ -106,6 +106,17 @@ struct cb_sequenceres { | |||
106 | extern unsigned nfs4_callback_sequence(struct cb_sequenceargs *args, | 106 | extern unsigned nfs4_callback_sequence(struct cb_sequenceargs *args, |
107 | struct cb_sequenceres *res); | 107 | struct cb_sequenceres *res); |
108 | 108 | ||
109 | |||
110 | #define RCA4_TYPE_MASK_RDATA_DLG 0 | ||
111 | #define RCA4_TYPE_MASK_WDATA_DLG 1 | ||
112 | |||
113 | struct cb_recallanyargs { | ||
114 | struct sockaddr *craa_addr; | ||
115 | uint32_t craa_objs_to_keep; | ||
116 | uint32_t craa_type_mask; | ||
117 | }; | ||
118 | |||
119 | extern unsigned nfs4_callback_recallany(struct cb_recallanyargs *args, void *dummy); | ||
109 | #endif /* CONFIG_NFS_V4_1 */ | 120 | #endif /* CONFIG_NFS_V4_1 */ |
110 | 121 | ||
111 | extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res); | 122 | extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args, struct cb_getattrres *res); |
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index b7da1f54da68..61b85306bb25 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c | |||
@@ -227,4 +227,33 @@ out: | |||
227 | return res->csr_status; | 227 | return res->csr_status; |
228 | } | 228 | } |
229 | 229 | ||
230 | unsigned nfs4_callback_recallany(struct cb_recallanyargs *args, void *dummy) | ||
231 | { | ||
232 | struct nfs_client *clp; | ||
233 | int status; | ||
234 | fmode_t flags = 0; | ||
235 | |||
236 | status = htonl(NFS4ERR_OP_NOT_IN_SESSION); | ||
237 | clp = nfs_find_client(args->craa_addr, 4); | ||
238 | if (clp == NULL) | ||
239 | goto out; | ||
240 | |||
241 | dprintk("NFS: RECALL_ANY callback request from %s\n", | ||
242 | rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_ADDR)); | ||
243 | |||
244 | if (test_bit(RCA4_TYPE_MASK_RDATA_DLG, (const unsigned long *) | ||
245 | &args->craa_type_mask)) | ||
246 | flags = FMODE_READ; | ||
247 | if (test_bit(RCA4_TYPE_MASK_WDATA_DLG, (const unsigned long *) | ||
248 | &args->craa_type_mask)) | ||
249 | flags |= FMODE_WRITE; | ||
250 | |||
251 | if (flags) | ||
252 | nfs_expire_all_delegation_types(clp, flags); | ||
253 | status = htonl(NFS4_OK); | ||
254 | out: | ||
255 | dprintk("%s: exit with status = %d\n", __func__, ntohl(status)); | ||
256 | return status; | ||
257 | } | ||
258 | |||
230 | #endif /* CONFIG_NFS_V4_1 */ | 259 | #endif /* CONFIG_NFS_V4_1 */ |
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index 0fda5e66241d..8e1a2511c8be 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #if defined(CONFIG_NFS_V4_1) | 23 | #if defined(CONFIG_NFS_V4_1) |
24 | #define CB_OP_SEQUENCE_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ + \ | 24 | #define CB_OP_SEQUENCE_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ + \ |
25 | 4 + 1 + 3) | 25 | 4 + 1 + 3) |
26 | #define CB_OP_RECALLANY_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) | ||
26 | #endif /* CONFIG_NFS_V4_1 */ | 27 | #endif /* CONFIG_NFS_V4_1 */ |
27 | 28 | ||
28 | #define NFSDBG_FACILITY NFSDBG_CALLBACK | 29 | #define NFSDBG_FACILITY NFSDBG_CALLBACK |
@@ -326,6 +327,25 @@ out_free: | |||
326 | goto out; | 327 | goto out; |
327 | } | 328 | } |
328 | 329 | ||
330 | static unsigned decode_recallany_args(struct svc_rqst *rqstp, | ||
331 | struct xdr_stream *xdr, | ||
332 | struct cb_recallanyargs *args) | ||
333 | { | ||
334 | uint32_t *p; | ||
335 | |||
336 | args->craa_addr = svc_addr(rqstp); | ||
337 | p = read_buf(xdr, 4); | ||
338 | if (unlikely(p == NULL)) | ||
339 | return htonl(NFS4ERR_BADXDR); | ||
340 | args->craa_objs_to_keep = ntohl(*p++); | ||
341 | p = read_buf(xdr, 4); | ||
342 | if (unlikely(p == NULL)) | ||
343 | return htonl(NFS4ERR_BADXDR); | ||
344 | args->craa_type_mask = ntohl(*p); | ||
345 | |||
346 | return 0; | ||
347 | } | ||
348 | |||
329 | #endif /* CONFIG_NFS_V4_1 */ | 349 | #endif /* CONFIG_NFS_V4_1 */ |
330 | 350 | ||
331 | static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char *str) | 351 | static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char *str) |
@@ -533,6 +553,7 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op) | |||
533 | case OP_CB_GETATTR: | 553 | case OP_CB_GETATTR: |
534 | case OP_CB_RECALL: | 554 | case OP_CB_RECALL: |
535 | case OP_CB_SEQUENCE: | 555 | case OP_CB_SEQUENCE: |
556 | case OP_CB_RECALL_ANY: | ||
536 | *op = &callback_ops[op_nr]; | 557 | *op = &callback_ops[op_nr]; |
537 | break; | 558 | break; |
538 | 559 | ||
@@ -540,7 +561,6 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op) | |||
540 | case OP_CB_NOTIFY_DEVICEID: | 561 | case OP_CB_NOTIFY_DEVICEID: |
541 | case OP_CB_NOTIFY: | 562 | case OP_CB_NOTIFY: |
542 | case OP_CB_PUSH_DELEG: | 563 | case OP_CB_PUSH_DELEG: |
543 | case OP_CB_RECALL_ANY: | ||
544 | case OP_CB_RECALLABLE_OBJ_AVAIL: | 564 | case OP_CB_RECALLABLE_OBJ_AVAIL: |
545 | case OP_CB_RECALL_SLOT: | 565 | case OP_CB_RECALL_SLOT: |
546 | case OP_CB_WANTS_CANCELLED: | 566 | case OP_CB_WANTS_CANCELLED: |
@@ -688,6 +708,11 @@ static struct callback_op callback_ops[] = { | |||
688 | .encode_res = (callback_encode_res_t)encode_cb_sequence_res, | 708 | .encode_res = (callback_encode_res_t)encode_cb_sequence_res, |
689 | .res_maxsize = CB_OP_SEQUENCE_RES_MAXSZ, | 709 | .res_maxsize = CB_OP_SEQUENCE_RES_MAXSZ, |
690 | }, | 710 | }, |
711 | [OP_CB_RECALL_ANY] = { | ||
712 | .process_op = (callback_process_op_t)nfs4_callback_recallany, | ||
713 | .decode_args = (callback_decode_arg_t)decode_recallany_args, | ||
714 | .res_maxsize = CB_OP_RECALLANY_RES_MAXSZ, | ||
715 | }, | ||
691 | #endif /* CONFIG_NFS_V4_1 */ | 716 | #endif /* CONFIG_NFS_V4_1 */ |
692 | }; | 717 | }; |
693 | 718 | ||
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 98dbc8f5ced8..f4758ec42138 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
@@ -411,7 +411,7 @@ static void nfs_delegation_run_state_manager(struct nfs_client *clp) | |||
411 | nfs4_schedule_state_manager(clp); | 411 | nfs4_schedule_state_manager(clp); |
412 | } | 412 | } |
413 | 413 | ||
414 | static void nfs_expire_all_delegation_types(struct nfs_client *clp, fmode_t flags) | 414 | void nfs_expire_all_delegation_types(struct nfs_client *clp, fmode_t flags) |
415 | { | 415 | { |
416 | nfs_client_mark_return_all_delegation_types(clp, flags); | 416 | nfs_client_mark_return_all_delegation_types(clp, flags); |
417 | nfs_delegation_run_state_manager(clp); | 417 | nfs_delegation_run_state_manager(clp); |
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h index e225a1290127..f6d0731a8cf5 100644 --- a/fs/nfs/delegation.h +++ b/fs/nfs/delegation.h | |||
@@ -40,6 +40,7 @@ void nfs_inode_return_delegation_noreclaim(struct inode *inode); | |||
40 | struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle); | 40 | struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle); |
41 | void nfs_super_return_all_delegations(struct super_block *sb); | 41 | void nfs_super_return_all_delegations(struct super_block *sb); |
42 | void nfs_expire_all_delegations(struct nfs_client *clp); | 42 | void nfs_expire_all_delegations(struct nfs_client *clp); |
43 | void nfs_expire_all_delegation_types(struct nfs_client *clp, fmode_t flags); | ||
43 | void nfs_expire_unreferenced_delegations(struct nfs_client *clp); | 44 | void nfs_expire_unreferenced_delegations(struct nfs_client *clp); |
44 | void nfs_handle_cb_pathdown(struct nfs_client *clp); | 45 | void nfs_handle_cb_pathdown(struct nfs_client *clp); |
45 | int nfs_client_return_marked_delegations(struct nfs_client *clp); | 46 | int nfs_client_return_marked_delegations(struct nfs_client *clp); |