|
@@ -348,7 +348,7 @@ validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args)
|
|
|
/* Normal */
|
|
/* Normal */
|
|
|
if (likely(args->csa_sequenceid == slot->seq_nr + 1)) {
|
|
if (likely(args->csa_sequenceid == slot->seq_nr + 1)) {
|
|
|
slot->seq_nr++;
|
|
slot->seq_nr++;
|
|
|
- return htonl(NFS4_OK);
|
|
|
|
|
|
|
+ goto out_ok;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* Replay */
|
|
/* Replay */
|
|
@@ -367,11 +367,14 @@ validate_seqid(struct nfs4_slot_table *tbl, struct cb_sequenceargs * args)
|
|
|
/* Wraparound */
|
|
/* Wraparound */
|
|
|
if (args->csa_sequenceid == 1 && (slot->seq_nr + 1) == 0) {
|
|
if (args->csa_sequenceid == 1 && (slot->seq_nr + 1) == 0) {
|
|
|
slot->seq_nr = 1;
|
|
slot->seq_nr = 1;
|
|
|
- return htonl(NFS4_OK);
|
|
|
|
|
|
|
+ goto out_ok;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* Misordered request */
|
|
/* Misordered request */
|
|
|
return htonl(NFS4ERR_SEQ_MISORDERED);
|
|
return htonl(NFS4ERR_SEQ_MISORDERED);
|
|
|
|
|
+out_ok:
|
|
|
|
|
+ tbl->highest_used_slotid = args->csa_slotid;
|
|
|
|
|
+ return htonl(NFS4_OK);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -433,26 +436,32 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args,
|
|
|
struct cb_sequenceres *res,
|
|
struct cb_sequenceres *res,
|
|
|
struct cb_process_state *cps)
|
|
struct cb_process_state *cps)
|
|
|
{
|
|
{
|
|
|
|
|
+ struct nfs4_slot_table *tbl;
|
|
|
struct nfs_client *clp;
|
|
struct nfs_client *clp;
|
|
|
int i;
|
|
int i;
|
|
|
__be32 status = htonl(NFS4ERR_BADSESSION);
|
|
__be32 status = htonl(NFS4ERR_BADSESSION);
|
|
|
|
|
|
|
|
- cps->clp = NULL;
|
|
|
|
|
-
|
|
|
|
|
clp = nfs4_find_client_sessionid(args->csa_addr, &args->csa_sessionid);
|
|
clp = nfs4_find_client_sessionid(args->csa_addr, &args->csa_sessionid);
|
|
|
if (clp == NULL)
|
|
if (clp == NULL)
|
|
|
goto out;
|
|
goto out;
|
|
|
|
|
|
|
|
|
|
+ tbl = &clp->cl_session->bc_slot_table;
|
|
|
|
|
+
|
|
|
|
|
+ spin_lock(&tbl->slot_tbl_lock);
|
|
|
/* state manager is resetting the session */
|
|
/* state manager is resetting the session */
|
|
|
if (test_bit(NFS4_SESSION_DRAINING, &clp->cl_session->session_state)) {
|
|
if (test_bit(NFS4_SESSION_DRAINING, &clp->cl_session->session_state)) {
|
|
|
- status = NFS4ERR_DELAY;
|
|
|
|
|
|
|
+ spin_unlock(&tbl->slot_tbl_lock);
|
|
|
|
|
+ status = htonl(NFS4ERR_DELAY);
|
|
|
goto out;
|
|
goto out;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
status = validate_seqid(&clp->cl_session->bc_slot_table, args);
|
|
status = validate_seqid(&clp->cl_session->bc_slot_table, args);
|
|
|
|
|
+ spin_unlock(&tbl->slot_tbl_lock);
|
|
|
if (status)
|
|
if (status)
|
|
|
goto out;
|
|
goto out;
|
|
|
|
|
|
|
|
|
|
+ cps->slotid = args->csa_slotid;
|
|
|
|
|
+
|
|
|
/*
|
|
/*
|
|
|
* Check for pending referring calls. If a match is found, a
|
|
* Check for pending referring calls. If a match is found, a
|
|
|
* related callback was received before the response to the original
|
|
* related callback was received before the response to the original
|
|
@@ -469,7 +478,6 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args,
|
|
|
res->csr_slotid = args->csa_slotid;
|
|
res->csr_slotid = args->csa_slotid;
|
|
|
res->csr_highestslotid = NFS41_BC_MAX_CALLBACKS - 1;
|
|
res->csr_highestslotid = NFS41_BC_MAX_CALLBACKS - 1;
|
|
|
res->csr_target_highestslotid = NFS41_BC_MAX_CALLBACKS - 1;
|
|
res->csr_target_highestslotid = NFS41_BC_MAX_CALLBACKS - 1;
|
|
|
- nfs4_cb_take_slot(clp);
|
|
|
|
|
|
|
|
|
|
out:
|
|
out:
|
|
|
cps->clp = clp; /* put in nfs4_callback_compound */
|
|
cps->clp = clp; /* put in nfs4_callback_compound */
|