* [PATCH] nfs41: implement cb_recall_slot @ 2010-01-08 20:23 andros 2010-01-08 20:23 ` [PATCH 6/6] " andros 0 siblings, 1 reply; 4+ messages in thread From: andros @ 2010-01-08 20:23 UTC (permalink / raw) To: trond.myklebust; +Cc: linux-nfs This patch applies on 2.6.33-rc3 Tronds nfs-for-next tree, on top of the last patch series I sent. [last patch series] 0001-nfs41-fix-wrong-error-on-callback-decode-hdr-overflo.patch 0002-nfs41-directly-encode-back-channel-error.patch 0003-nfs41-remove-uneeded-checks-in-callback-processing.patch 0004-nfs41-prepare-for-back-channel-drc.patch 0005-nfs41-back-channel-drc-minimal-implementation.patch 0006-nfs41-implement-cb_recall_slot.patch The fore channel session is drained, then the new highest_slot is set. Tested with a new pyNFS server CB_RECALL_SLOT call and the Connectathon basic big file test which uses all available slots. -->Andy ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 6/6] nfs41: implement cb_recall_slot 2010-01-08 20:23 [PATCH] nfs41: implement cb_recall_slot andros @ 2010-01-08 20:23 ` andros 0 siblings, 0 replies; 4+ messages in thread From: andros @ 2010-01-08 20:23 UTC (permalink / raw) To: trond.myklebust; +Cc: linux-nfs, Andy Adamson From: Andy Adamson <andros@netapp.com> Drain the fore channel and reset the max_slots to the new value. Signed-off-by: Andy Adamson <andros@netapp.com> --- fs/nfs/callback.h | 8 ++++++++ fs/nfs/callback_proc.c | 32 ++++++++++++++++++++++++++++++++ fs/nfs/callback_xdr.c | 22 +++++++++++++++++++++- fs/nfs/nfs4_fs.h | 2 ++ fs/nfs/nfs4state.c | 23 +++++++++++++++++++++++ include/linux/nfs_fs_sb.h | 2 ++ 6 files changed, 88 insertions(+), 1 deletions(-) diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h index d4036be..85a7cfd 100644 --- a/fs/nfs/callback.h +++ b/fs/nfs/callback.h @@ -119,6 +119,14 @@ struct cb_recallanyargs { }; extern unsigned nfs4_callback_recallany(struct cb_recallanyargs *args, void *dummy); + +struct cb_recallslotargs { + struct sockaddr *crsa_addr; + uint32_t crsa_target_max_slots; +}; +extern unsigned nfs4_callback_recallslot(struct cb_recallslotargs *args, + void *dummy); + #endif /* CONFIG_NFS_V4_1 */ 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 3cc2333..e81e1ea 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -297,4 +297,36 @@ out: dprintk("%s: exit with status = %d\n", __func__, ntohl(status)); return status; } + +/* Reduce the fore channel's max_slots to the target value */ +unsigned nfs4_callback_recallslot(struct cb_recallslotargs *args, void *dummy) +{ + struct nfs_client *clp; + struct nfs4_slot_table *fc_stbl; + int status; + + status = htonl(NFS4ERR_OP_NOT_IN_SESSION); + clp = nfs_find_client(args->crsa_addr, 4); + if (clp == NULL) + goto out; + + dprintk("NFS: RECALL_SLOT callback request from %s " + " with target max slots: %d\n", + rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_ADDR), + args->crsa_target_max_slots); + + fc_stbl = &clp->cl_session->fc_slot_table; + + status = htonl(NFS4ERR_BAD_HIGH_SLOT); + if (args->crsa_target_max_slots >= fc_stbl->max_slots || + args->crsa_target_max_slots < 1) + goto out; + + fc_stbl->target_max_slots = args->crsa_target_max_slots; + nfs41_handle_recall_slot(clp); + status = htonl(NFS4_OK); +out: + dprintk("%s: exit with status = %d\n", __func__, ntohl(status)); + return status; +} #endif /* CONFIG_NFS_V4_1 */ diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index 76d082e..241321b 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c @@ -24,6 +24,7 @@ #define CB_OP_SEQUENCE_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ + \ 4 + 1 + 3) #define CB_OP_RECALLANY_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) +#define CB_OP_RECALLSLOT_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) #endif /* CONFIG_NFS_V4_1 */ #define NFSDBG_FACILITY NFSDBG_CALLBACK @@ -346,6 +347,20 @@ static unsigned decode_recallany_args(struct svc_rqst *rqstp, return 0; } +static unsigned decode_recallslot_args(struct svc_rqst *rqstp, + struct xdr_stream *xdr, + struct cb_recallslotargs *args) +{ + __be32 *p; + + args->crsa_addr = svc_addr(rqstp); + p = read_buf(xdr, 4); + if (unlikely(p == NULL)) + return htonl(NFS4ERR_BADXDR); + args->crsa_target_max_slots = ntohl(*p++); + return 0; +} + #endif /* CONFIG_NFS_V4_1 */ static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char *str) @@ -554,6 +569,7 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op) case OP_CB_RECALL: case OP_CB_SEQUENCE: case OP_CB_RECALL_ANY: + case OP_CB_RECALL_SLOT: *op = &callback_ops[op_nr]; break; @@ -562,7 +578,6 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op) case OP_CB_NOTIFY: case OP_CB_PUSH_DELEG: case OP_CB_RECALLABLE_OBJ_AVAIL: - case OP_CB_RECALL_SLOT: case OP_CB_WANTS_CANCELLED: case OP_CB_NOTIFY_LOCK: return htonl(NFS4ERR_NOTSUPP); @@ -724,6 +739,11 @@ static struct callback_op callback_ops[] = { .decode_args = (callback_decode_arg_t)decode_recallany_args, .res_maxsize = CB_OP_RECALLANY_RES_MAXSZ, }, + [OP_CB_RECALL_SLOT] = { + .process_op = (callback_process_op_t)nfs4_callback_recallslot, + .decode_args = (callback_decode_arg_t)decode_recallslot_args, + .res_maxsize = CB_OP_RECALLSLOT_RES_MAXSZ, + }, #endif /* CONFIG_NFS_V4_1 */ }; diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 865265b..cd93dfc 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -46,6 +46,7 @@ enum nfs4_client_state { NFS4CLNT_DELEGRETURN, NFS4CLNT_SESSION_RESET, NFS4CLNT_SESSION_DRAINING, + NFS4CLNT_RECALL_SLOT, }; /* @@ -278,6 +279,7 @@ extern void nfs4_schedule_state_recovery(struct nfs_client *); extern void nfs4_schedule_state_manager(struct nfs_client *); extern int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state); extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags); +extern void nfs41_handle_recall_slot(struct nfs_client *clp); extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl); extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t); diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 6d263ed..4f71bb1 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -1249,6 +1249,12 @@ static int nfs4_reclaim_lease(struct nfs_client *clp) } #ifdef CONFIG_NFS_V4_1 +void nfs41_handle_recall_slot(struct nfs_client *clp) +{ + set_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state); + nfs4_schedule_state_recovery(clp); +} + void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags) { if (!flags) @@ -1299,6 +1305,16 @@ out: return status; } +static void nfs4_recall_slot(struct nfs_client *clp) +{ + struct nfs4_slot_table *fc_stbl = &clp->cl_session->fc_slot_table; + + nfs4_begin_drain_session(clp); + fc_stbl->max_slots = fc_stbl->target_max_slots; + fc_stbl->target_max_slots = 0; + nfs4_end_drain_session(clp); +} + #else /* CONFIG_NFS_V4_1 */ static int nfs4_reset_session(struct nfs_client *clp) { return 0; } static int nfs4_end_drain_session(struct nfs_client *clp) { return 0; } @@ -1397,6 +1413,13 @@ static void nfs4_state_manager(struct nfs_client *clp) nfs_client_return_marked_delegations(clp); continue; } + /* Recall session slots */ + if (test_and_clear_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state) + && nfs4_has_session(clp)) { + nfs4_recall_slot(clp); + continue; + } + nfs4_clear_state_manager_bit(clp); /* Did we race with an attempt to give us more work? */ diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 34fc6be..ecd9e6c 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -193,6 +193,8 @@ struct nfs4_slot_table { int max_slots; /* # slots in table */ int highest_used_slotid; /* sent to server on each SEQ. * op for dynamic resizing */ + int target_max_slots; /* Set by CB_RECALL_SLOT as + * the new max_slots */ }; static inline int slot_idx(struct nfs4_slot_table *tbl, struct nfs4_slot *sp) -- 1.6.5.2 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 0/6] nfs41: return correct errors on callback replays version 2 @ 2010-01-12 21:48 andros 2010-01-12 21:48 ` [PATCH 1/6] nfs41: fix wrong error on callback header xdr overflow andros 0 siblings, 1 reply; 4+ messages in thread From: andros @ 2010-01-12 21:48 UTC (permalink / raw) To: trond.myklebust; +Cc: linux-nfs Responded to Tronds comments. The first three patches clean up callback processing 0001-nfs41-fix-wrong-error-on-callback-hdr-xdr-overflow.patch 0002-nfs41-directly-encode-back-channel-error.patch 0003-nfs41-remove-uneeded-checks-in-callback-processing.patch These next two implement correct error returns for v4.1 callback replays. Since our back channel has a ca_maxrequestsize_cached = 0, a replay with cachethis set to true results in a NFS4ERR_TOO_BIG_TO_CACHE error. This code is set up to do a real DRC. A replay with cachethis set to false returns a NFS4ERR_RETRY_UNCACHED_REP error. 0004-nfs41-prepare-for-back-channel-drc.patch 0005-nfs41-back-channel-drc-minimal-implementation.patch ADDED: 0006 nfs41:-implement-cb_recall_slot.patch The fore channel session is drained, then the new highest_slot is set. TODO: The callback code currently returns NFS4ERR_RESOURCE on all xdr overflows. This is correct for v4.0, incorrect for v4.1. Testing: Modified nfsv4.1 pynfs server tested cb_recall replays with the cb_sequence cachethis set to False and to True. Modified nfs4.1 pyNFS server sends CB_RECALL_SLOT call during the Connectathon basic big file test which uses all available slots. Connectathon tests pass. -->Andy ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/6] nfs41: fix wrong error on callback header xdr overflow 2010-01-12 21:48 [PATCH 0/6] nfs41: return correct errors on callback replays version 2 andros @ 2010-01-12 21:48 ` andros 2010-01-12 21:48 ` [PATCH 2/6] nfs41: directly encode back channel error andros 0 siblings, 1 reply; 4+ messages in thread From: andros @ 2010-01-12 21:48 UTC (permalink / raw) To: trond.myklebust; +Cc: linux-nfs, Andy Adamson From: Andy Adamson <andros@netapp.com> Set NFS4ERR_RESOURCE as CB_COMPOUND status and do not return an op on decode_op_hdr or encode_op_hdr buffer overflow. NFS4ERR_RESOURCE is correct for v4.0. Will fix the return for v4.1 along with all the other NFS4ERR_RESOURCE errors in a later patch. Signed-off-by: Andy Adamson <andros@netapp.com> --- fs/nfs/callback_xdr.c | 28 ++++++++++++++++++---------- 1 files changed, 18 insertions(+), 10 deletions(-) diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index 8e1a251..6ae3278 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c @@ -28,6 +28,9 @@ #define NFSDBG_FACILITY NFSDBG_CALLBACK +/* Internal error code */ +#define NFS4ERR_RESOURCE_HDR 11050 + typedef __be32 (*callback_process_op_t)(void *, void *); typedef __be32 (*callback_decode_arg_t)(struct svc_rqst *, struct xdr_stream *, void *); typedef __be32 (*callback_encode_res_t)(struct svc_rqst *, struct xdr_stream *, void *); @@ -173,7 +176,7 @@ static __be32 decode_op_hdr(struct xdr_stream *xdr, unsigned int *op) __be32 *p; p = read_buf(xdr, 4); if (unlikely(p == NULL)) - return htonl(NFS4ERR_RESOURCE); + return htonl(NFS4ERR_RESOURCE_HDR); *op = ntohl(*p); return 0; } @@ -465,7 +468,7 @@ static __be32 encode_op_hdr(struct xdr_stream *xdr, uint32_t op, __be32 res) p = xdr_reserve_space(xdr, 8); if (unlikely(p == NULL)) - return htonl(NFS4ERR_RESOURCE); + return htonl(NFS4ERR_RESOURCE_HDR); *p++ = htonl(op); *p = res; return 0; @@ -605,17 +608,15 @@ static __be32 process_op(uint32_t minorversion, int nop, struct xdr_stream *xdr_out, void *resp) { struct callback_op *op = &callback_ops[0]; - unsigned int op_nr = OP_CB_ILLEGAL; + unsigned int op_nr; __be32 status; long maxlen; __be32 res; dprintk("%s: start\n", __func__); status = decode_op_hdr(xdr_in, &op_nr); - if (unlikely(status)) { - status = htonl(NFS4ERR_OP_ILLEGAL); - goto out; - } + if (unlikely(status)) + return status; dprintk("%s: minorversion=%d nop=%d op_nr=%u\n", __func__, minorversion, nop, op_nr); @@ -624,7 +625,7 @@ static __be32 process_op(uint32_t minorversion, int nop, preprocess_nfs4_op(op_nr, &op); if (status == htonl(NFS4ERR_OP_ILLEGAL)) op_nr = OP_CB_ILLEGAL; -out: + maxlen = xdr_out->end - xdr_out->p; if (maxlen > 0 && maxlen < PAGE_SIZE) { if (likely(status == 0 && op->decode_args != NULL)) @@ -635,8 +636,8 @@ out: status = htonl(NFS4ERR_RESOURCE); res = encode_op_hdr(xdr_out, op_nr, status); - if (status == 0) - status = res; + if (unlikely(res)) + return res; if (op->encode_res != NULL && status == 0) status = op->encode_res(rqstp, xdr_out, resp); dprintk("%s: done, status = %d\n", __func__, ntohl(status)); @@ -677,6 +678,13 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r nops++; } + /* Buffer overflow in decode_ops_hdr or encode_ops_hdr. Return + * resource error in cb_compound status without returning op */ + if (unlikely(status == htonl(NFS4ERR_RESOURCE_HDR))) { + status = htonl(NFS4ERR_RESOURCE); + nops--; + } + *hdr_res.status = status; *hdr_res.nops = htonl(nops); dprintk("%s: done, status = %u\n", __func__, ntohl(status)); -- 1.6.5.2 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/6] nfs41: directly encode back channel error 2010-01-12 21:48 ` [PATCH 1/6] nfs41: fix wrong error on callback header xdr overflow andros @ 2010-01-12 21:48 ` andros 2010-01-12 21:48 ` [PATCH 3/6] nfs41: remove uneeded checks in callback processing andros 0 siblings, 1 reply; 4+ messages in thread From: andros @ 2010-01-12 21:48 UTC (permalink / raw) To: trond.myklebust; +Cc: linux-nfs, Andy Adamson From: Andy Adamson <andros@netapp.com> Skip all other processing when error is encountered. Signed-off-by: Andy Adamson <andros@netapp.com> --- fs/nfs/callback_xdr.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index 6ae3278..d3e07f4 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c @@ -625,16 +625,19 @@ static __be32 process_op(uint32_t minorversion, int nop, preprocess_nfs4_op(op_nr, &op); if (status == htonl(NFS4ERR_OP_ILLEGAL)) op_nr = OP_CB_ILLEGAL; + if (status) + goto encode_hdr; maxlen = xdr_out->end - xdr_out->p; if (maxlen > 0 && maxlen < PAGE_SIZE) { - if (likely(status == 0 && op->decode_args != NULL)) + if (likely(op->decode_args != NULL)) status = op->decode_args(rqstp, xdr_in, argp); if (likely(status == 0 && op->process_op != NULL)) status = op->process_op(argp, resp); } else status = htonl(NFS4ERR_RESOURCE); +encode_hdr: res = encode_op_hdr(xdr_out, op_nr, status); if (unlikely(res)) return res; -- 1.6.5.2 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 3/6] nfs41: remove uneeded checks in callback processing 2010-01-12 21:48 ` [PATCH 2/6] nfs41: directly encode back channel error andros @ 2010-01-12 21:48 ` andros 2010-01-12 21:48 ` [PATCH 4/6] nfs41: prepare for back channel drc andros 0 siblings, 1 reply; 4+ messages in thread From: andros @ 2010-01-12 21:48 UTC (permalink / raw) To: trond.myklebust; +Cc: linux-nfs, Andy Adamson From: Andy Adamson <andros@netapp.com> All callback operations have arguments to decode and require processing. The preprocess_nfs4X_op functions catch unsupported or illegal ops so decode_args and process_op pointers are always non NULL. Signed-off-by: Andy Adamson <andros@netapp.com> --- fs/nfs/callback_xdr.c | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index d3e07f4..a6f2ded 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c @@ -630,9 +630,8 @@ static __be32 process_op(uint32_t minorversion, int nop, maxlen = xdr_out->end - xdr_out->p; if (maxlen > 0 && maxlen < PAGE_SIZE) { - if (likely(op->decode_args != NULL)) - status = op->decode_args(rqstp, xdr_in, argp); - if (likely(status == 0 && op->process_op != NULL)) + status = op->decode_args(rqstp, xdr_in, argp); + if (likely(status == 0)) status = op->process_op(argp, resp); } else status = htonl(NFS4ERR_RESOURCE); -- 1.6.5.2 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 4/6] nfs41: prepare for back channel drc 2010-01-12 21:48 ` [PATCH 3/6] nfs41: remove uneeded checks in callback processing andros @ 2010-01-12 21:48 ` andros 2010-01-12 21:48 ` [PATCH 5/6] nfs41: back channel drc minimal implementation andros 0 siblings, 1 reply; 4+ messages in thread From: andros @ 2010-01-12 21:48 UTC (permalink / raw) To: trond.myklebust; +Cc: linux-nfs, Andy Adamson From: Andy Adamson <andros@netapp.com> Make all cb_sequence arguments available to verify_seqid which will make replay decisions. Signed-off-by: Andy Adamson <andros@netapp.com> --- fs/nfs/callback_proc.c | 19 +++++++++---------- 1 files changed, 9 insertions(+), 10 deletions(-) diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index defa9b4..7f92b6d 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -153,34 +153,34 @@ int nfs41_validate_delegation_stateid(struct nfs_delegation *delegation, const n * a single outstanding callback request at a time. */ static int -validate_seqid(struct nfs4_slot_table *tbl, u32 slotid, u32 seqid) +validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args) { struct nfs4_slot *slot; dprintk("%s enter. slotid %d seqid %d\n", - __func__, slotid, seqid); + __func__, args->csa_slotid, args->csa_sequenceid); - if (slotid > NFS41_BC_MAX_CALLBACKS) + if (args->csa_slotid > NFS41_BC_MAX_CALLBACKS) return htonl(NFS4ERR_BADSLOT); - slot = tbl->slots + slotid; + slot = tbl->slots + args->csa_slotid; dprintk("%s slot table seqid: %d\n", __func__, slot->seq_nr); /* Normal */ - if (likely(seqid == slot->seq_nr + 1)) { + if (likely(args->csa_sequenceid == slot->seq_nr + 1)) { slot->seq_nr++; return htonl(NFS4_OK); } /* Replay */ - if (seqid == slot->seq_nr) { + if (args->csa_sequenceid == slot->seq_nr) { dprintk("%s seqid %d is a replay - no DRC available\n", - __func__, seqid); + __func__, args->csa_sequenceid); return htonl(NFS4_OK); } /* Wraparound */ - if (seqid == 1 && (slot->seq_nr + 1) == 0) { + if (args->csa_sequenceid == 1 && (slot->seq_nr + 1) == 0) { slot->seq_nr = 1; return htonl(NFS4_OK); } @@ -241,8 +241,7 @@ unsigned nfs4_callback_sequence(struct cb_sequenceargs *args, if (clp == NULL) goto out; - status = validate_seqid(&clp->cl_session->bc_slot_table, - args->csa_slotid, args->csa_sequenceid); + status = validate_seqid(&clp->cl_session->bc_slot_table, args); if (status) goto out_putclient; -- 1.6.5.2 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 5/6] nfs41: back channel drc minimal implementation 2010-01-12 21:48 ` [PATCH 4/6] nfs41: prepare for back channel drc andros @ 2010-01-12 21:48 ` andros 2010-01-12 21:48 ` [PATCH 6/6] nfs41: implement cb_recall_slot andros 0 siblings, 1 reply; 4+ messages in thread From: andros @ 2010-01-12 21:48 UTC (permalink / raw) To: trond.myklebust; +Cc: linux-nfs, Andy Adamson From: Andy Adamson <andros@netapp.com> For now the back channel ca_maxresponsesize_cached is 0 and there is no backchannel DRC. Return NFS4ERR_REP_TOO_BIG_TO_CACHE when a cb_sequence cachethis is true. When it is false, return NFS4ERR_RETRY_UNCACHED_REP as the next operation error. Remember the replay error accross compound operation processing. Signed-off-by: Andy Adamson <andros@netapp.com> --- fs/nfs/callback_proc.c | 25 +++++++++++++++++-------- fs/nfs/callback_xdr.c | 19 +++++++++++++++---- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 7f92b6d..3cc2333 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -143,9 +143,8 @@ int nfs41_validate_delegation_stateid(struct nfs_delegation *delegation, const n * Return success if the sequenceID is one more than what we last saw on * this slot, accounting for wraparound. Increments the slot's sequence. * - * We don't yet implement a duplicate request cache, so at this time - * we will log replays, and process them as if we had not seen them before, - * but we don't bump the sequence in the slot. Not too worried about it, + * We don't yet implement a duplicate request cache, instead we set the + * back channel ca_maxresponsesize_cached to zero. This is OK for now * since we only currently implement idempotent callbacks anyway. * * We have a single slot backchannel at this time, so we don't bother @@ -174,9 +173,15 @@ validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args) /* Replay */ if (args->csa_sequenceid == slot->seq_nr) { - dprintk("%s seqid %d is a replay - no DRC available\n", + dprintk("%s seqid %d is a replay\n", __func__, args->csa_sequenceid); - return htonl(NFS4_OK); + /* Signal process_op to set this error on next op */ + if (args->csa_cachethis == 0) + return htonl(NFS4ERR_RETRY_UNCACHED_REP); + + /* The ca_maxresponsesize_cached is 0 with no DRC */ + else if (args->csa_cachethis == 1) + return htonl(NFS4ERR_REP_TOO_BIG_TO_CACHE); } /* Wraparound */ @@ -255,9 +260,13 @@ unsigned nfs4_callback_sequence(struct cb_sequenceargs *args, out_putclient: nfs_put_client(clp); out: - dprintk("%s: exit with status = %d\n", __func__, ntohl(status)); - res->csr_status = status; - return res->csr_status; + if (status == htonl(NFS4ERR_RETRY_UNCACHED_REP)) + res->csr_status = 0; + else + res->csr_status = status; + dprintk("%s: exit with status = %d res->csr_status %d\n", __func__, + ntohl(status), ntohl(res->csr_status)); + return status; } unsigned nfs4_callback_recallany(struct cb_recallanyargs *args, void *dummy) diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index a6f2ded..08b430d 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c @@ -605,7 +605,7 @@ preprocess_nfs4_op(unsigned int op_nr, struct callback_op **op) static __be32 process_op(uint32_t minorversion, int nop, struct svc_rqst *rqstp, struct xdr_stream *xdr_in, void *argp, - struct xdr_stream *xdr_out, void *resp) + struct xdr_stream *xdr_out, void *resp, int* drc_status) { struct callback_op *op = &callback_ops[0]; unsigned int op_nr; @@ -628,6 +628,11 @@ static __be32 process_op(uint32_t minorversion, int nop, if (status) goto encode_hdr; + if (*drc_status) { + status = *drc_status; + goto encode_hdr; + } + maxlen = xdr_out->end - xdr_out->p; if (maxlen > 0 && maxlen < PAGE_SIZE) { status = op->decode_args(rqstp, xdr_in, argp); @@ -636,6 +641,12 @@ static __be32 process_op(uint32_t minorversion, int nop, } else status = htonl(NFS4ERR_RESOURCE); + /* Only set by OP_CB_SEQUENCE processing */ + if (status == htonl(NFS4ERR_RETRY_UNCACHED_REP)) { + *drc_status = status; + status = 0; + } + encode_hdr: res = encode_op_hdr(xdr_out, op_nr, status); if (unlikely(res)) @@ -655,7 +666,7 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r struct cb_compound_hdr_res hdr_res = { NULL }; struct xdr_stream xdr_in, xdr_out; __be32 *p; - __be32 status; + __be32 status, drc_status = 0; unsigned int nops = 0; dprintk("%s: start\n", __func__); @@ -675,8 +686,8 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r return rpc_system_err; while (status == 0 && nops != hdr_arg.nops) { - status = process_op(hdr_arg.minorversion, nops, - rqstp, &xdr_in, argp, &xdr_out, resp); + status = process_op(hdr_arg.minorversion, nops, rqstp, + &xdr_in, argp, &xdr_out, resp, &drc_status); nops++; } -- 1.6.5.2 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 6/6] nfs41: implement cb_recall_slot 2010-01-12 21:48 ` [PATCH 5/6] nfs41: back channel drc minimal implementation andros @ 2010-01-12 21:48 ` andros 2010-01-13 20:58 ` Andy Adamson 0 siblings, 1 reply; 4+ messages in thread From: andros @ 2010-01-12 21:48 UTC (permalink / raw) To: trond.myklebust; +Cc: linux-nfs, Andy Adamson From: Andy Adamson <andros@netapp.com> Drain the fore channel and reset the max_slots to the new value. Signed-off-by: Andy Adamson <andros@netapp.com> --- fs/nfs/callback.h | 8 ++++++++ fs/nfs/callback_proc.c | 32 ++++++++++++++++++++++++++++++++ fs/nfs/callback_xdr.c | 22 +++++++++++++++++++++- fs/nfs/nfs4_fs.h | 2 ++ fs/nfs/nfs4state.c | 23 +++++++++++++++++++++++ include/linux/nfs_fs_sb.h | 2 ++ 6 files changed, 88 insertions(+), 1 deletions(-) diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h index d4036be..85a7cfd 100644 --- a/fs/nfs/callback.h +++ b/fs/nfs/callback.h @@ -119,6 +119,14 @@ struct cb_recallanyargs { }; extern unsigned nfs4_callback_recallany(struct cb_recallanyargs *args, void *dummy); + +struct cb_recallslotargs { + struct sockaddr *crsa_addr; + uint32_t crsa_target_max_slots; +}; +extern unsigned nfs4_callback_recallslot(struct cb_recallslotargs *args, + void *dummy); + #endif /* CONFIG_NFS_V4_1 */ 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 3cc2333..e81e1ea 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -297,4 +297,36 @@ out: dprintk("%s: exit with status = %d\n", __func__, ntohl(status)); return status; } + +/* Reduce the fore channel's max_slots to the target value */ +unsigned nfs4_callback_recallslot(struct cb_recallslotargs *args, void *dummy) +{ + struct nfs_client *clp; + struct nfs4_slot_table *fc_stbl; + int status; + + status = htonl(NFS4ERR_OP_NOT_IN_SESSION); + clp = nfs_find_client(args->crsa_addr, 4); + if (clp == NULL) + goto out; + + dprintk("NFS: RECALL_SLOT callback request from %s " + " with target max slots: %d\n", + rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_ADDR), + args->crsa_target_max_slots); + + fc_stbl = &clp->cl_session->fc_slot_table; + + status = htonl(NFS4ERR_BAD_HIGH_SLOT); + if (args->crsa_target_max_slots >= fc_stbl->max_slots || + args->crsa_target_max_slots < 1) + goto out; + + fc_stbl->target_max_slots = args->crsa_target_max_slots; + nfs41_handle_recall_slot(clp); + status = htonl(NFS4_OK); +out: + dprintk("%s: exit with status = %d\n", __func__, ntohl(status)); + return status; +} #endif /* CONFIG_NFS_V4_1 */ diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index 08b430d..8e66e20 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c @@ -24,6 +24,7 @@ #define CB_OP_SEQUENCE_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ + \ 4 + 1 + 3) #define CB_OP_RECALLANY_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) +#define CB_OP_RECALLSLOT_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) #endif /* CONFIG_NFS_V4_1 */ #define NFSDBG_FACILITY NFSDBG_CALLBACK @@ -349,6 +350,20 @@ static unsigned decode_recallany_args(struct svc_rqst *rqstp, return 0; } +static unsigned decode_recallslot_args(struct svc_rqst *rqstp, + struct xdr_stream *xdr, + struct cb_recallslotargs *args) +{ + __be32 *p; + + args->crsa_addr = svc_addr(rqstp); + p = read_buf(xdr, 4); + if (unlikely(p == NULL)) + return htonl(NFS4ERR_BADXDR); + args->crsa_target_max_slots = ntohl(*p++); + return 0; +} + #endif /* CONFIG_NFS_V4_1 */ static __be32 encode_string(struct xdr_stream *xdr, unsigned int len, const char *str) @@ -557,6 +572,7 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op) case OP_CB_RECALL: case OP_CB_SEQUENCE: case OP_CB_RECALL_ANY: + case OP_CB_RECALL_SLOT: *op = &callback_ops[op_nr]; break; @@ -565,7 +581,6 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, struct callback_op **op) case OP_CB_NOTIFY: case OP_CB_PUSH_DELEG: case OP_CB_RECALLABLE_OBJ_AVAIL: - case OP_CB_RECALL_SLOT: case OP_CB_WANTS_CANCELLED: case OP_CB_NOTIFY_LOCK: return htonl(NFS4ERR_NOTSUPP); @@ -734,6 +749,11 @@ static struct callback_op callback_ops[] = { .decode_args = (callback_decode_arg_t)decode_recallany_args, .res_maxsize = CB_OP_RECALLANY_RES_MAXSZ, }, + [OP_CB_RECALL_SLOT] = { + .process_op = (callback_process_op_t)nfs4_callback_recallslot, + .decode_args = (callback_decode_arg_t)decode_recallslot_args, + .res_maxsize = CB_OP_RECALLSLOT_RES_MAXSZ, + }, #endif /* CONFIG_NFS_V4_1 */ }; diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 865265b..cd93dfc 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -46,6 +46,7 @@ enum nfs4_client_state { NFS4CLNT_DELEGRETURN, NFS4CLNT_SESSION_RESET, NFS4CLNT_SESSION_DRAINING, + NFS4CLNT_RECALL_SLOT, }; /* @@ -278,6 +279,7 @@ extern void nfs4_schedule_state_recovery(struct nfs_client *); extern void nfs4_schedule_state_manager(struct nfs_client *); extern int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, struct nfs4_state *state); extern void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags); +extern void nfs41_handle_recall_slot(struct nfs_client *clp); extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); extern int nfs4_set_lock_state(struct nfs4_state *state, struct file_lock *fl); extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, fl_owner_t); diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 6d263ed..4f71bb1 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c @@ -1249,6 +1249,12 @@ static int nfs4_reclaim_lease(struct nfs_client *clp) } #ifdef CONFIG_NFS_V4_1 +void nfs41_handle_recall_slot(struct nfs_client *clp) +{ + set_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state); + nfs4_schedule_state_recovery(clp); +} + void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 flags) { if (!flags) @@ -1299,6 +1305,16 @@ out: return status; } +static void nfs4_recall_slot(struct nfs_client *clp) +{ + struct nfs4_slot_table *fc_stbl = &clp->cl_session->fc_slot_table; + + nfs4_begin_drain_session(clp); + fc_stbl->max_slots = fc_stbl->target_max_slots; + fc_stbl->target_max_slots = 0; + nfs4_end_drain_session(clp); +} + #else /* CONFIG_NFS_V4_1 */ static int nfs4_reset_session(struct nfs_client *clp) { return 0; } static int nfs4_end_drain_session(struct nfs_client *clp) { return 0; } @@ -1397,6 +1413,13 @@ static void nfs4_state_manager(struct nfs_client *clp) nfs_client_return_marked_delegations(clp); continue; } + /* Recall session slots */ + if (test_and_clear_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state) + && nfs4_has_session(clp)) { + nfs4_recall_slot(clp); + continue; + } + nfs4_clear_state_manager_bit(clp); /* Did we race with an attempt to give us more work? */ diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 34fc6be..ecd9e6c 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -193,6 +193,8 @@ struct nfs4_slot_table { int max_slots; /* # slots in table */ int highest_used_slotid; /* sent to server on each SEQ. * op for dynamic resizing */ + int target_max_slots; /* Set by CB_RECALL_SLOT as + * the new max_slots */ }; static inline int slot_idx(struct nfs4_slot_table *tbl, struct nfs4_slot *sp) -- 1.6.5.2 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 6/6] nfs41: implement cb_recall_slot 2010-01-12 21:48 ` [PATCH 6/6] nfs41: implement cb_recall_slot andros @ 2010-01-13 20:58 ` Andy Adamson 0 siblings, 0 replies; 4+ messages in thread From: Andy Adamson @ 2010-01-13 20:58 UTC (permalink / raw) To: andros; +Cc: trond.myklebust, linux-nfs Please disregard this version of this patch. I've found problems and will resend. Thanks. -->Andy On Jan 12, 2010, at 4:48 PM, andros@netapp.com wrote: > From: Andy Adamson <andros@netapp.com> > > Drain the fore channel and reset the max_slots to the new value. > > Signed-off-by: Andy Adamson <andros@netapp.com> > --- > fs/nfs/callback.h | 8 ++++++++ > fs/nfs/callback_proc.c | 32 ++++++++++++++++++++++++++++++++ > fs/nfs/callback_xdr.c | 22 +++++++++++++++++++++- > fs/nfs/nfs4_fs.h | 2 ++ > fs/nfs/nfs4state.c | 23 +++++++++++++++++++++++ > include/linux/nfs_fs_sb.h | 2 ++ > 6 files changed, 88 insertions(+), 1 deletions(-) > > diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h > index d4036be..85a7cfd 100644 > --- a/fs/nfs/callback.h > +++ b/fs/nfs/callback.h > @@ -119,6 +119,14 @@ struct cb_recallanyargs { > }; > > extern unsigned nfs4_callback_recallany(struct cb_recallanyargs > *args, void *dummy); > + > +struct cb_recallslotargs { > + struct sockaddr *crsa_addr; > + uint32_t crsa_target_max_slots; > +}; > +extern unsigned nfs4_callback_recallslot(struct cb_recallslotargs > *args, > + void *dummy); > + > #endif /* CONFIG_NFS_V4_1 */ > > 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 3cc2333..e81e1ea 100644 > --- a/fs/nfs/callback_proc.c > +++ b/fs/nfs/callback_proc.c > @@ -297,4 +297,36 @@ out: > dprintk("%s: exit with status = %d\n", __func__, ntohl(status)); > return status; > } > + > +/* Reduce the fore channel's max_slots to the target value */ > +unsigned nfs4_callback_recallslot(struct cb_recallslotargs *args, > void *dummy) > +{ > + struct nfs_client *clp; > + struct nfs4_slot_table *fc_stbl; > + int status; > + > + status = htonl(NFS4ERR_OP_NOT_IN_SESSION); > + clp = nfs_find_client(args->crsa_addr, 4); > + if (clp == NULL) > + goto out; > + > + dprintk("NFS: RECALL_SLOT callback request from %s " > + " with target max slots: %d\n", > + rpc_peeraddr2str(clp->cl_rpcclient, RPC_DISPLAY_ADDR), > + args->crsa_target_max_slots); > + > + fc_stbl = &clp->cl_session->fc_slot_table; > + > + status = htonl(NFS4ERR_BAD_HIGH_SLOT); > + if (args->crsa_target_max_slots >= fc_stbl->max_slots || > + args->crsa_target_max_slots < 1) > + goto out; > + > + fc_stbl->target_max_slots = args->crsa_target_max_slots; > + nfs41_handle_recall_slot(clp); > + status = htonl(NFS4_OK); > +out: > + dprintk("%s: exit with status = %d\n", __func__, ntohl(status)); > + return status; > +} > #endif /* CONFIG_NFS_V4_1 */ > diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c > index 08b430d..8e66e20 100644 > --- a/fs/nfs/callback_xdr.c > +++ b/fs/nfs/callback_xdr.c > @@ -24,6 +24,7 @@ > #define CB_OP_SEQUENCE_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ + \ > 4 + 1 + 3) > #define CB_OP_RECALLANY_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) > +#define CB_OP_RECALLSLOT_RES_MAXSZ (CB_OP_HDR_RES_MAXSZ) > #endif /* CONFIG_NFS_V4_1 */ > > #define NFSDBG_FACILITY NFSDBG_CALLBACK > @@ -349,6 +350,20 @@ static unsigned decode_recallany_args(struct > svc_rqst *rqstp, > return 0; > } > > +static unsigned decode_recallslot_args(struct svc_rqst *rqstp, > + struct xdr_stream *xdr, > + struct cb_recallslotargs *args) > +{ > + __be32 *p; > + > + args->crsa_addr = svc_addr(rqstp); > + p = read_buf(xdr, 4); > + if (unlikely(p == NULL)) > + return htonl(NFS4ERR_BADXDR); > + args->crsa_target_max_slots = ntohl(*p++); > + return 0; > +} > + > #endif /* CONFIG_NFS_V4_1 */ > > static __be32 encode_string(struct xdr_stream *xdr, unsigned int > len, const char *str) > @@ -557,6 +572,7 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, > struct callback_op **op) > case OP_CB_RECALL: > case OP_CB_SEQUENCE: > case OP_CB_RECALL_ANY: > + case OP_CB_RECALL_SLOT: > *op = &callback_ops[op_nr]; > break; > > @@ -565,7 +581,6 @@ preprocess_nfs41_op(int nop, unsigned int op_nr, > struct callback_op **op) > case OP_CB_NOTIFY: > case OP_CB_PUSH_DELEG: > case OP_CB_RECALLABLE_OBJ_AVAIL: > - case OP_CB_RECALL_SLOT: > case OP_CB_WANTS_CANCELLED: > case OP_CB_NOTIFY_LOCK: > return htonl(NFS4ERR_NOTSUPP); > @@ -734,6 +749,11 @@ static struct callback_op callback_ops[] = { > .decode_args = (callback_decode_arg_t)decode_recallany_args, > .res_maxsize = CB_OP_RECALLANY_RES_MAXSZ, > }, > + [OP_CB_RECALL_SLOT] = { > + .process_op = (callback_process_op_t)nfs4_callback_recallslot, > + .decode_args = (callback_decode_arg_t)decode_recallslot_args, > + .res_maxsize = CB_OP_RECALLSLOT_RES_MAXSZ, > + }, > #endif /* CONFIG_NFS_V4_1 */ > }; > > diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h > index 865265b..cd93dfc 100644 > --- a/fs/nfs/nfs4_fs.h > +++ b/fs/nfs/nfs4_fs.h > @@ -46,6 +46,7 @@ enum nfs4_client_state { > NFS4CLNT_DELEGRETURN, > NFS4CLNT_SESSION_RESET, > NFS4CLNT_SESSION_DRAINING, > + NFS4CLNT_RECALL_SLOT, > }; > > /* > @@ -278,6 +279,7 @@ extern void nfs4_schedule_state_recovery(struct > nfs_client *); > extern void nfs4_schedule_state_manager(struct nfs_client *); > extern int nfs4_state_mark_reclaim_nograce(struct nfs_client *clp, > struct nfs4_state *state); > extern void nfs41_handle_sequence_flag_errors(struct nfs_client > *clp, u32 flags); > +extern void nfs41_handle_recall_slot(struct nfs_client *clp); > extern void nfs4_put_lock_state(struct nfs4_lock_state *lsp); > extern int nfs4_set_lock_state(struct nfs4_state *state, struct > file_lock *fl); > extern void nfs4_copy_stateid(nfs4_stateid *, struct nfs4_state *, > fl_owner_t); > diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c > index 6d263ed..4f71bb1 100644 > --- a/fs/nfs/nfs4state.c > +++ b/fs/nfs/nfs4state.c > @@ -1249,6 +1249,12 @@ static int nfs4_reclaim_lease(struct > nfs_client *clp) > } > > #ifdef CONFIG_NFS_V4_1 > +void nfs41_handle_recall_slot(struct nfs_client *clp) > +{ > + set_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state); > + nfs4_schedule_state_recovery(clp); > +} > + > void nfs41_handle_sequence_flag_errors(struct nfs_client *clp, u32 > flags) > { > if (!flags) > @@ -1299,6 +1305,16 @@ out: > return status; > } > > +static void nfs4_recall_slot(struct nfs_client *clp) > +{ > + struct nfs4_slot_table *fc_stbl = &clp->cl_session->fc_slot_table; > + > + nfs4_begin_drain_session(clp); > + fc_stbl->max_slots = fc_stbl->target_max_slots; > + fc_stbl->target_max_slots = 0; > + nfs4_end_drain_session(clp); > +} > + > #else /* CONFIG_NFS_V4_1 */ > static int nfs4_reset_session(struct nfs_client *clp) { return 0; } > static int nfs4_end_drain_session(struct nfs_client *clp) { return > 0; } > @@ -1397,6 +1413,13 @@ static void nfs4_state_manager(struct > nfs_client *clp) > nfs_client_return_marked_delegations(clp); > continue; > } > + /* Recall session slots */ > + if (test_and_clear_bit(NFS4CLNT_RECALL_SLOT, &clp->cl_state) > + && nfs4_has_session(clp)) { > + nfs4_recall_slot(clp); > + continue; > + } > + > > nfs4_clear_state_manager_bit(clp); > /* Did we race with an attempt to give us more work? */ > diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h > index 34fc6be..ecd9e6c 100644 > --- a/include/linux/nfs_fs_sb.h > +++ b/include/linux/nfs_fs_sb.h > @@ -193,6 +193,8 @@ struct nfs4_slot_table { > int max_slots; /* # slots in table */ > int highest_used_slotid; /* sent to server on each SEQ. > * op for dynamic resizing */ > + int target_max_slots; /* Set by CB_RECALL_SLOT as > + * the new max_slots */ > }; > > static inline int slot_idx(struct nfs4_slot_table *tbl, struct > nfs4_slot *sp) > -- > 1.6.5.2 > ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2010-01-13 20:58 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2010-01-08 20:23 [PATCH] nfs41: implement cb_recall_slot andros 2010-01-08 20:23 ` [PATCH 6/6] " andros 2010-01-12 21:48 [PATCH 0/6] nfs41: return correct errors on callback replays version 2 andros 2010-01-12 21:48 ` [PATCH 1/6] nfs41: fix wrong error on callback header xdr overflow andros 2010-01-12 21:48 ` [PATCH 2/6] nfs41: directly encode back channel error andros 2010-01-12 21:48 ` [PATCH 3/6] nfs41: remove uneeded checks in callback processing andros 2010-01-12 21:48 ` [PATCH 4/6] nfs41: prepare for back channel drc andros 2010-01-12 21:48 ` [PATCH 5/6] nfs41: back channel drc minimal implementation andros 2010-01-12 21:48 ` [PATCH 6/6] nfs41: implement cb_recall_slot andros 2010-01-13 20:58 ` Andy Adamson
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.