diff options
author | jhb <jhb@FreeBSD.org> | 2001-01-23 21:58:44 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2001-01-23 21:58:44 +0000 |
commit | 191c7b388b0a6f9bcb4ef8365e900dccb3ba7fe4 (patch) | |
tree | 39377ccac2a7629ac4a361579291df1c3a27da80 /sys/geom | |
parent | 9f367044139c62bdfb4bddeb900a881ab98bf9a5 (diff) | |
download | FreeBSD-src-191c7b388b0a6f9bcb4ef8365e900dccb3ba7fe4.zip FreeBSD-src-191c7b388b0a6f9bcb4ef8365e900dccb3ba7fe4.tar.gz |
Proc locking in the form of using the proc lock to protect p_ucred while
we obtain another reference to it for vnode operations.
Diffstat (limited to 'sys/geom')
-rw-r--r-- | sys/geom/geom_ccd.c | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/sys/geom/geom_ccd.c b/sys/geom/geom_ccd.c index cdd07ce..69098b9 100644 --- a/sys/geom/geom_ccd.c +++ b/sys/geom/geom_ccd.c @@ -380,6 +380,7 @@ ccdinit(ccd, cpaths, p) size_t size; int ix; struct vnode *vp; + struct ucred *uc; size_t minsize; int maxsecsize; struct partinfo dpart; @@ -406,6 +407,10 @@ ccdinit(ccd, cpaths, p) */ maxsecsize = 0; minsize = 0; + PROC_LOCK(p); + uc = p->p_ucred; + crhold(uc); + PROC_UNLOCK(p); for (ix = 0; ix < cs->sc_nccdisks; ix++) { vp = ccd->ccd_vpp[ix]; ci = &cs->sc_cinfo[ix]; @@ -433,7 +438,7 @@ ccdinit(ccd, cpaths, p) * Get partition information for the component. */ if ((error = VOP_IOCTL(vp, DIOCGPART, (caddr_t)&dpart, - FREAD, p->p_ucred, p)) != 0) { + FREAD, uc, p)) != 0) { #ifdef DEBUG if (ccddebug & (CCDB_FOLLOW|CCDB_INIT)) printf("ccd%d: %s: ioctl failed, error = %d\n", @@ -479,6 +484,7 @@ ccdinit(ccd, cpaths, p) ci->ci_size = size; cs->sc_size += size; } + crfree(uc); /* * Don't allow the interleave to be smaller than @@ -566,6 +572,7 @@ ccdinit(ccd, cpaths, p) cs->sc_unit = ccd->ccd_unit; return (0); fail: + crfree(uc); while (ci > cs->sc_cinfo) { ci--; free(ci->ci_path, M_DEVBUF); @@ -1265,6 +1272,7 @@ ccdioctl(dev, cmd, data, flag, p) struct ccddevice ccd; char **cpp; struct vnode **vpp; + struct ucred *uc; if (unit >= numccd) return (ENXIO); @@ -1336,12 +1344,17 @@ ccdioctl(dev, cmd, data, flag, p) printf("ccdioctl: lookedup = %d\n", lookedup); #endif if ((error = ccdlookup(cpp[i], p, &vpp[i])) != 0) { + PROC_LOCK(p); + uc = p->p_ucred; + crhold(uc); + PROC_UNLOCK(p); for (j = 0; j < lookedup; ++j) (void)vn_close(vpp[j], FREAD|FWRITE, - p->p_ucred, p); + uc, p); free(vpp, M_DEVBUF); free(cpp, M_DEVBUF); ccdunlock(cs); + crfree(uc); return (error); } ++lookedup; @@ -1354,13 +1367,17 @@ ccdioctl(dev, cmd, data, flag, p) * Initialize the ccd. Fills in the softc for us. */ if ((error = ccdinit(&ccd, cpp, p)) != 0) { + PROC_LOCK(p); + uc = p->p_ucred; + crhold(uc); + PROC_UNLOCK(p); for (j = 0; j < lookedup; ++j) - (void)vn_close(vpp[j], FREAD|FWRITE, - p->p_ucred, p); + (void)vn_close(vpp[j], FREAD|FWRITE, uc, p); bzero(&ccd_softc[unit], sizeof(struct ccd_softc)); free(vpp, M_DEVBUF); free(cpp, M_DEVBUF); ccdunlock(cs); + crfree(uc); return (error); } @@ -1400,6 +1417,10 @@ ccdioctl(dev, cmd, data, flag, p) */ /* Close the components and free their pathnames. */ + PROC_LOCK(p); + uc = p->p_ucred; + crhold(uc); + PROC_UNLOCK(p); for (i = 0; i < cs->sc_nccdisks; ++i) { /* * XXX: this close could potentially fail and @@ -1412,9 +1433,10 @@ ccdioctl(dev, cmd, data, flag, p) cs->sc_cinfo[i].ci_vp); #endif (void)vn_close(cs->sc_cinfo[i].ci_vp, FREAD|FWRITE, - p->p_ucred, p); + uc, p); free(cs->sc_cinfo[i].ci_path, M_DEVBUF); } + crfree(uc); /* Free interleave index. */ for (i = 0; cs->sc_itable[i].ii_ndisk; ++i) @@ -1559,6 +1581,7 @@ ccdlookup(path, p, vpp) { struct nameidata nd; struct vnode *vp; + struct ucred *uc; int error, flags; NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, path, p); @@ -1593,7 +1616,12 @@ bad: VOP_UNLOCK(vp, 0, p); NDFREE(&nd, NDF_ONLY_PNBUF); /* vn_close does vrele() for vp */ - (void)vn_close(vp, FREAD|FWRITE, p->p_ucred, p); + PROC_LOCK(p); + uc = p->p_ucred; + crhold(uc); + PROC_UNLOCK(p); + (void)vn_close(vp, FREAD|FWRITE, uc, p); + crfree(uc); return (error); } |