Commit 276f03e3 authored by Kinglong Mee's avatar Kinglong Mee Committed by J. Bruce Fields

nfsd: Update callback sequnce id only CB_SEQUENCE success

When testing pnfs layout, nfsd got error NFS4ERR_SEQ_MISORDERED.
It is caused by nfs return NFS4ERR_DELAY before validate_seqid(),
don't update the sequnce id, but nfsd updates the sequnce id !!!

According to RFC5661 20.9.3,
" If CB_SEQUENCE returns an error, then the state of the slot
(sequence ID, cached reply) MUST NOT change. "
Signed-off-by: default avatarKinglong Mee <kinglongmee@gmail.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 4399396e
...@@ -455,6 +455,7 @@ static int decode_cb_sequence4res(struct xdr_stream *xdr, ...@@ -455,6 +455,7 @@ static int decode_cb_sequence4res(struct xdr_stream *xdr,
if (unlikely(status || cb->cb_status)) if (unlikely(status || cb->cb_status))
return status; return status;
cb->cb_update_seq_nr = true;
return decode_cb_sequence4resok(xdr, cb); return decode_cb_sequence4resok(xdr, cb);
} }
...@@ -875,6 +876,7 @@ static void nfsd4_cb_prepare(struct rpc_task *task, void *calldata) ...@@ -875,6 +876,7 @@ static void nfsd4_cb_prepare(struct rpc_task *task, void *calldata)
u32 minorversion = clp->cl_minorversion; u32 minorversion = clp->cl_minorversion;
cb->cb_minorversion = minorversion; cb->cb_minorversion = minorversion;
cb->cb_update_seq_nr = false;
cb->cb_status = 0; cb->cb_status = 0;
if (minorversion) { if (minorversion) {
if (!nfsd41_cb_get_slot(clp, task)) if (!nfsd41_cb_get_slot(clp, task))
...@@ -892,9 +894,16 @@ static void nfsd4_cb_done(struct rpc_task *task, void *calldata) ...@@ -892,9 +894,16 @@ static void nfsd4_cb_done(struct rpc_task *task, void *calldata)
clp->cl_minorversion); clp->cl_minorversion);
if (clp->cl_minorversion) { if (clp->cl_minorversion) {
/* No need for lock, access serialized in nfsd4_cb_prepare */ /*
if (!task->tk_status) * No need for lock, access serialized in nfsd4_cb_prepare
*
* RFC5661 20.9.3
* If CB_SEQUENCE returns an error, then the state of the slot
* (sequence ID, cached reply) MUST NOT change.
*/
if (cb->cb_update_seq_nr)
++clp->cl_cb_session->se_cb_seq_nr; ++clp->cl_cb_session->se_cb_seq_nr;
clear_bit(0, &clp->cl_cb_slot_busy); clear_bit(0, &clp->cl_cb_slot_busy);
rpc_wake_up_next(&clp->cl_cb_waitq); rpc_wake_up_next(&clp->cl_cb_waitq);
dprintk("%s: freed slot, new seqid=%d\n", __func__, dprintk("%s: freed slot, new seqid=%d\n", __func__,
...@@ -1091,6 +1100,7 @@ void nfsd4_init_cb(struct nfsd4_callback *cb, struct nfs4_client *clp, ...@@ -1091,6 +1100,7 @@ void nfsd4_init_cb(struct nfsd4_callback *cb, struct nfs4_client *clp,
cb->cb_ops = ops; cb->cb_ops = ops;
INIT_WORK(&cb->cb_work, nfsd4_run_cb_work); INIT_WORK(&cb->cb_work, nfsd4_run_cb_work);
cb->cb_status = 0; cb->cb_status = 0;
cb->cb_update_seq_nr = false;
cb->cb_need_restart = false; cb->cb_need_restart = false;
} }
......
...@@ -68,6 +68,7 @@ struct nfsd4_callback { ...@@ -68,6 +68,7 @@ struct nfsd4_callback {
struct nfsd4_callback_ops *cb_ops; struct nfsd4_callback_ops *cb_ops;
struct work_struct cb_work; struct work_struct cb_work;
int cb_status; int cb_status;
bool cb_update_seq_nr;
bool cb_need_restart; bool cb_need_restart;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment