mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-07 09:00:28 +00:00
nfscl: Acquire a refcount on "cred" for mirrored pNFS RPCs
When the NFSv4.1/4.2 client is doing a pnfs mount to mirrored DS(s), asynchronous threads are used to do the RPCs against the DS(s) concurrently. If a DS is slow to reply, it is possible for the "cred" to be free'd before the asynchronous thread is done with it, causing a panic/crash. This patch fixes the problem by acquiring a refcount on the "cred" while it is being used by the asynchronous thread for a DS RPC. This bug was found during a recent IETF NFSv4 testing event. This bug only affects "pnfs" mounts to mirrored pNFS servers. MFC after: 2 weeks
This commit is contained in:
parent
450b4ac23c
commit
70910e4b55
|
@ -7010,6 +7010,7 @@ start_writedsmir(void *arg, int pending)
|
|||
drpc->fhp, drpc->m, drpc->vers, drpc->minorvers, drpc->cred,
|
||||
drpc->p);
|
||||
drpc->done = 1;
|
||||
crfree(drpc->cred);
|
||||
NFSCL_DEBUG(4, "start_writedsmir: err=%d\n", drpc->err);
|
||||
}
|
||||
|
||||
|
@ -7037,7 +7038,7 @@ nfsio_writedsmir(vnode_t vp, int *iomode, int *must_commit,
|
|||
drpc->m = m;
|
||||
drpc->vers = vers;
|
||||
drpc->minorvers = minorvers;
|
||||
drpc->cred = cred;
|
||||
drpc->cred = crhold(cred);
|
||||
drpc->p = p;
|
||||
drpc->inprog = 0;
|
||||
ret = EIO;
|
||||
|
@ -7045,9 +7046,11 @@ nfsio_writedsmir(vnode_t vp, int *iomode, int *must_commit,
|
|||
ret = nfs_pnfsio(start_writedsmir, drpc);
|
||||
NFSCL_DEBUG(4, "nfsio_writedsmir: nfs_pnfsio=%d\n", ret);
|
||||
}
|
||||
if (ret != 0)
|
||||
if (ret != 0) {
|
||||
error = nfsrpc_writedsmir(vp, iomode, &drpc->must_commit,
|
||||
stateidp, dsp, off, len, fhp, m, vers, minorvers, cred, p);
|
||||
crfree(drpc->cred);
|
||||
}
|
||||
NFSCL_DEBUG(4, "nfsio_writedsmir: error=%d\n", error);
|
||||
return (error);
|
||||
}
|
||||
|
@ -7195,6 +7198,7 @@ start_commitds(void *arg, int pending)
|
|||
drpc->dsp, drpc->fhp, drpc->vers, drpc->minorvers, drpc->cred,
|
||||
drpc->p);
|
||||
drpc->done = 1;
|
||||
crfree(drpc->cred);
|
||||
NFSCL_DEBUG(4, "start_commitds: err=%d\n", drpc->err);
|
||||
}
|
||||
|
||||
|
@ -7217,7 +7221,7 @@ nfsio_commitds(vnode_t vp, uint64_t offset, int cnt, struct nfsclds *dsp,
|
|||
drpc->fhp = fhp;
|
||||
drpc->vers = vers;
|
||||
drpc->minorvers = minorvers;
|
||||
drpc->cred = cred;
|
||||
drpc->cred = crhold(cred);
|
||||
drpc->p = p;
|
||||
drpc->inprog = 0;
|
||||
ret = EIO;
|
||||
|
@ -7225,9 +7229,11 @@ nfsio_commitds(vnode_t vp, uint64_t offset, int cnt, struct nfsclds *dsp,
|
|||
ret = nfs_pnfsio(start_commitds, drpc);
|
||||
NFSCL_DEBUG(4, "nfsio_commitds: nfs_pnfsio=%d\n", ret);
|
||||
}
|
||||
if (ret != 0)
|
||||
if (ret != 0) {
|
||||
error = nfsrpc_commitds(vp, offset, cnt, dsp, fhp, vers,
|
||||
minorvers, cred, p);
|
||||
crfree(drpc->cred);
|
||||
}
|
||||
NFSCL_DEBUG(4, "nfsio_commitds: error=%d\n", error);
|
||||
return (error);
|
||||
}
|
||||
|
@ -7334,11 +7340,12 @@ start_adviseds(void *arg, int pending)
|
|||
drpc->advise, drpc->dsp, drpc->fhp, drpc->vers, drpc->minorvers,
|
||||
drpc->cred, drpc->p);
|
||||
drpc->done = 1;
|
||||
crfree(drpc->cred);
|
||||
NFSCL_DEBUG(4, "start_adviseds: err=%d\n", drpc->err);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the commit DS mirror call for the pNFS I/O thread.
|
||||
* Set up the advise DS mirror call for the pNFS I/O thread.
|
||||
*/
|
||||
static int
|
||||
nfsio_adviseds(vnode_t vp, uint64_t offset, int cnt, int advise,
|
||||
|
@ -7357,7 +7364,7 @@ nfsio_adviseds(vnode_t vp, uint64_t offset, int cnt, int advise,
|
|||
drpc->fhp = fhp;
|
||||
drpc->vers = vers;
|
||||
drpc->minorvers = minorvers;
|
||||
drpc->cred = cred;
|
||||
drpc->cred = crhold(cred);
|
||||
drpc->p = p;
|
||||
drpc->inprog = 0;
|
||||
ret = EIO;
|
||||
|
@ -7365,9 +7372,11 @@ nfsio_adviseds(vnode_t vp, uint64_t offset, int cnt, int advise,
|
|||
ret = nfs_pnfsio(start_adviseds, drpc);
|
||||
NFSCL_DEBUG(4, "nfsio_adviseds: nfs_pnfsio=%d\n", ret);
|
||||
}
|
||||
if (ret != 0)
|
||||
if (ret != 0) {
|
||||
error = nfsrpc_adviseds(vp, offset, cnt, advise, dsp, fhp, vers,
|
||||
minorvers, cred, p);
|
||||
crfree(drpc->cred);
|
||||
}
|
||||
NFSCL_DEBUG(4, "nfsio_adviseds: error=%d\n", error);
|
||||
return (error);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue