nfsv4 pnfs client: fix updating of the layout stateid.seqid

During a recent NFSv4 testing event a test server was replying
NFSERR_OLDSTATEID for layout stateids presented to the server
for LayoutReturn operations.  Upon rereading RFC5661, it was
apparent that the FreeBSD NFSv4.1/4.2 pNFS client did not
maintain the seqid field of the layout stateid correctly.

This patch is believed to correct the problem.  Tested against
a FreeBSD pNFS server with diagnostics added to check the stateid's
seqid did not indicate problems.  Unfortunately, testing aginst
this server will not happen in the near future, so the fix may
not be correct yet.

MFC after:	2 weeks
This commit is contained in:
Rick Macklem 2021-03-18 12:20:25 -07:00
parent 3b57ddb029
commit fd232a21bb

View File

@ -3495,11 +3495,18 @@ nfscl_docb(struct nfsrv_descript *nd, NFSPROC_T *p)
len, stateid.seqid,
0, 0, NULL,
recallp);
if (error == 0 &&
stateid.seqid >
lyp->nfsly_stateid.seqid)
lyp->nfsly_stateid.seqid =
stateid.seqid;
recallp = NULL;
wakeup(clp);
NFSCL_DEBUG(4,
"aft layrcal=%d\n",
error);
"aft layrcal=%d "
"layseqid=%d\n",
error,
lyp->nfsly_stateid.seqid);
} else
error =
NFSERR_NOMATCHLAYOUT;
@ -4881,6 +4888,8 @@ nfscl_layout(struct nfsmount *nmp, vnode_t vp, u_int8_t *fhp, int fhlen,
} else {
if (retonclose != 0)
lyp->nfsly_flags |= NFSLY_RETONCLOSE;
if (stateidp->seqid > lyp->nfsly_stateid.seqid)
lyp->nfsly_stateid.seqid = stateidp->seqid;
TAILQ_REMOVE(&clp->nfsc_layout, lyp, nfsly_list);
TAILQ_INSERT_HEAD(&clp->nfsc_layout, lyp, nfsly_list);
lyp->nfsly_timestamp = NFSD_MONOSEC + 120;
@ -4893,7 +4902,7 @@ nfscl_layout(struct nfsmount *nmp, vnode_t vp, u_int8_t *fhp, int fhlen,
return (EPERM);
}
*lypp = lyp;
} else
} else if (stateidp->seqid > lyp->nfsly_stateid.seqid)
lyp->nfsly_stateid.seqid = stateidp->seqid;
/* Merge the new list of File Layouts into the list. */