Change the NFSv4.1 pNFS client so that it returns the DS error in layoutreturn.
When the NFSv4.1 pNFS client gets an error for a DS I/O operation using a Flexible File layout, it returns the layout with an error. This patch changes the code slightly, so that it returns the layout for all errors except EACCES and lets the MDS decide what to do based on the error. It also makes a couple of changes to nfscl_layoutrecall() to ensure that the first layoutreturn(s) will have the error in the reply. Plus, the patch adds a wakeup() so that the "nfscl" thread won't wait 1sec before doing the LayoutReturn. Tested against the pNFS service. This patch should not affect non-pNFS use of the client. The unused "dsp" argument will be used by a future patch that disables the connection to the DS when possible. MFC after: 2 weeks
This commit is contained in:
parent
9d48901e34
commit
2e35b8fe24
@ -601,7 +601,8 @@ int nfscl_layout(struct nfsmount *, vnode_t, u_int8_t *, int, nfsv4stateid_t *,
|
||||
NFSPROC_T *);
|
||||
struct nfscllayout *nfscl_getlayout(struct nfsclclient *, uint8_t *, int,
|
||||
uint64_t, struct nfsclflayout **, int *);
|
||||
void nfscl_dserr(uint32_t, struct nfscldevinfo *, struct nfscllayout *);
|
||||
void nfscl_dserr(uint32_t, uint32_t, struct nfscldevinfo *,
|
||||
struct nfscllayout *, struct nfsclds *);
|
||||
void nfscl_rellayout(struct nfscllayout *, int);
|
||||
struct nfscldevinfo *nfscl_getdevinfo(struct nfsclclient *, uint8_t *,
|
||||
struct nfscldevinfo *);
|
||||
|
@ -6040,10 +6040,11 @@ nfscl_dofflayoutio(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit,
|
||||
*dspp, fhp, dp->nfsdi_vers,
|
||||
dp->nfsdi_minorvers, tcred, p);
|
||||
NFSCL_DEBUG(4, "commitds=%d\n", error);
|
||||
if (nfsds_failerr(error)) {
|
||||
if (error != 0 && error != EACCES) {
|
||||
NFSCL_DEBUG(4,
|
||||
"DS layreterr for commit\n");
|
||||
nfscl_dserr(NFSV4OP_COMMIT, dp, lyp);
|
||||
nfscl_dserr(NFSV4OP_COMMIT, error, dp,
|
||||
lyp, *dspp);
|
||||
}
|
||||
}
|
||||
NFSCL_DEBUG(4, "aft nfsio_commitds=%d\n", error);
|
||||
@ -6064,9 +6065,10 @@ nfscl_dofflayoutio(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit,
|
||||
off, xfer, fhp, 1, dp->nfsdi_vers,
|
||||
dp->nfsdi_minorvers, tcred, p);
|
||||
NFSCL_DEBUG(4, "readds=%d\n", error);
|
||||
if (nfsds_failerr(error)) {
|
||||
if (error != 0 && error != EACCES) {
|
||||
NFSCL_DEBUG(4, "DS layreterr for read\n");
|
||||
nfscl_dserr(NFSV4OP_READ, dp, lyp);
|
||||
nfscl_dserr(NFSV4OP_READ, error, dp, lyp,
|
||||
*dspp);
|
||||
}
|
||||
} else {
|
||||
if (flp->nfsfl_mirrorcnt == 1) {
|
||||
@ -6099,10 +6101,11 @@ nfscl_dofflayoutio(vnode_t vp, struct uio *uiop, int *iomode, int *must_commit,
|
||||
xfer, fhp, m, dp->nfsdi_vers,
|
||||
dp->nfsdi_minorvers, tcred, p);
|
||||
NFSCL_DEBUG(4, "nfsio_writedsmir=%d\n", error);
|
||||
if (nfsds_failerr(error)) {
|
||||
if (error != 0 && error != EACCES) {
|
||||
NFSCL_DEBUG(4,
|
||||
"DS layreterr for write\n");
|
||||
nfscl_dserr(NFSV4OP_WRITE, dp, lyp);
|
||||
nfscl_dserr(NFSV4OP_WRITE, error, dp,
|
||||
lyp, *dspp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4973,11 +4973,13 @@ nfscl_retoncloselayout(vnode_t vp, struct nfsclclient *clp, uint8_t *fhp,
|
||||
* Mark the layout to be recalled and with an error.
|
||||
*/
|
||||
void
|
||||
nfscl_dserr(uint32_t op, struct nfscldevinfo *dp, struct nfscllayout *lyp)
|
||||
nfscl_dserr(uint32_t op, uint32_t stat, struct nfscldevinfo *dp,
|
||||
struct nfscllayout *lyp, __unused struct nfsclds *dsp)
|
||||
{
|
||||
struct nfsclrecalllayout *recallp;
|
||||
uint32_t iomode;
|
||||
|
||||
/* Set up the return of the layout. */
|
||||
recallp = malloc(sizeof(*recallp), M_NFSLAYRECALL, M_WAITOK);
|
||||
iomode = 0;
|
||||
NFSLOCKCLSTATE();
|
||||
@ -4987,10 +4989,10 @@ nfscl_dserr(uint32_t op, struct nfscldevinfo *dp, struct nfscllayout *lyp)
|
||||
if (!LIST_EMPTY(&lyp->nfsly_flayrw))
|
||||
iomode |= NFSLAYOUTIOMODE_RW;
|
||||
(void)nfscl_layoutrecall(NFSLAYOUTRETURN_FILE, lyp, iomode,
|
||||
0, UINT64_MAX, lyp->nfsly_stateid.seqid, NFSERR_IO, op,
|
||||
0, UINT64_MAX, lyp->nfsly_stateid.seqid, stat, op,
|
||||
dp->nfsdi_deviceid, recallp);
|
||||
NFSUNLOCKCLSTATE();
|
||||
NFSCL_DEBUG(4, "retoncls recall iomode=%d\n", iomode);
|
||||
NFSCL_DEBUG(4, "nfscl_dserr recall iomode=%d\n", iomode);
|
||||
} else {
|
||||
NFSUNLOCKCLSTATE();
|
||||
free(recallp, M_NFSLAYRECALL);
|
||||
@ -5247,6 +5249,19 @@ nfscl_layoutrecall(int recalltype, struct nfscllayout *lyp, uint32_t iomode,
|
||||
LIST_INSERT_BEFORE(rp, recallp, nfsrecly_list);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Put any error return on all the file returns that will
|
||||
* preceed this one.
|
||||
*/
|
||||
if (rp->nfsrecly_recalltype == NFSLAYOUTRETURN_FILE &&
|
||||
stat != 0 && rp->nfsrecly_stat == 0) {
|
||||
rp->nfsrecly_stat = stat;
|
||||
rp->nfsrecly_op = op;
|
||||
if (devid != NULL)
|
||||
NFSBCOPY(devid, rp->nfsrecly_devid,
|
||||
NFSX_V4DEVICEID);
|
||||
}
|
||||
}
|
||||
if (rp == NULL) {
|
||||
if (orp == NULL)
|
||||
@ -5256,6 +5271,7 @@ nfscl_layoutrecall(int recalltype, struct nfscllayout *lyp, uint32_t iomode,
|
||||
LIST_INSERT_AFTER(orp, recallp, nfsrecly_list);
|
||||
}
|
||||
lyp->nfsly_flags |= NFSLY_RECALL;
|
||||
wakeup(lyp->nfsly_clp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user