diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2016-01-23 15:18:18 -0500 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2016-01-25 09:36:21 -0500 |
commit | 810d82e6830100615e7481813a862d26ffcff6bd (patch) | |
tree | 800222904c927e881b0d469f0b2f3de229ba132d /fs/nfs/callback_proc.c | |
parent | 5f83d86cf531d737ba2ca9c3cc500ff331fbd43e (diff) |
NFSv4.x: Allow multiple callbacks in flight
Hook the callback channel into the same session management machinery
as we use for the forward channel.
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs/callback_proc.c')
-rw-r--r-- | fs/nfs/callback_proc.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 79c93b3bbfec..efd079d28946 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -367,7 +367,7 @@ validate_seqid(const struct nfs4_slot_table *tbl, const struct nfs4_slot *slot, if (args->csa_sequenceid == slot->seq_nr) { dprintk("%s seqid %u is a replay\n", __func__, args->csa_sequenceid); - if (tbl->highest_used_slotid != NFS4_NO_SLOT) + if (nfs4_test_locked_slot(tbl, slot->slot_nr)) return htonl(NFS4ERR_DELAY); /* Signal process_op to set this error on next op */ if (args->csa_cachethis == 0) @@ -476,12 +476,18 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args, goto out_unlock; } + status = htonl(NFS4ERR_BADSLOT); + slot = nfs4_lookup_slot(tbl, args->csa_slotid); + if (IS_ERR(slot)) + goto out_unlock; status = validate_seqid(tbl, slot, args); if (status) goto out_unlock; - - cps->slotid = args->csa_slotid; - tbl->highest_used_slotid = args->csa_slotid; + if (!nfs4_try_to_lock_slot(tbl, slot)) { + status = htonl(NFS4ERR_DELAY); + goto out_unlock; + } + cps->slot = slot; memcpy(&res->csr_sessionid, &args->csa_sessionid, sizeof(res->csr_sessionid)); |