diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-12-14 06:19:04 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-12-14 06:19:04 +0000 |
commit | c462c4eb01aa7245bd19013b320ce17707d5e8d4 (patch) | |
tree | 633653b7711a6160a2854e229e68430ee391a532 /sys | |
parent | 5e4fa22c30fbce856024f594901926e7f692b5b8 (diff) |
from netbsd:
Fix a race condition where if a process is asleep waiting on an
exclusive lock of a ccd device while another process is unconfiguring
that same device, the first process would never awaken (unless interrupted).
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/ccd.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/sys/dev/ccd.c b/sys/dev/ccd.c index df29bcf529f..c8d33a4b867 100644 --- a/sys/dev/ccd.c +++ b/sys/dev/ccd.c @@ -1,4 +1,4 @@ -/* $NetBSD: ccd.c,v 1.18.2.2 1995/11/03 02:40:33 thorpej Exp $ */ +/* $NetBSD: ccd.c,v 1.22 1995/12/08 19:13:26 thorpej Exp $ */ /* * Copyright (c) 1995 Jason R. Thorpe. @@ -945,7 +945,7 @@ ccdioctl(dev, cmd, data, flag, p) { int unit = ccdunit(dev); int i, j, lookedup = 0, error = 0; - int part, pmask; + int part, pmask, s; struct ccd_softc *cs; struct ccd_ioctl *ccio = (struct ccd_ioctl *)data; struct ccddevice ccd; @@ -1093,6 +1093,8 @@ ccdioctl(dev, cmd, data, flag, p) /* * Free ccd_softc information and clear entry. */ + + /* Close the components and free their pathnames. */ for (i = 0; i < cs->sc_nccdisks; ++i) { /* * XXX: this close could potentially fail and @@ -1108,11 +1110,15 @@ ccdioctl(dev, cmd, data, flag, p) p->p_ucred, p); free(cs->sc_cinfo[i].ci_path, M_DEVBUF); } + + /* Free interleave index. */ for (i = 0; cs->sc_itable[i].ii_ndisk; ++i) free(cs->sc_itable[i].ii_index, M_DEVBUF); + + /* Free component info and interleave table. */ free(cs->sc_cinfo, M_DEVBUF); free(cs->sc_itable, M_DEVBUF); - bzero(cs, sizeof(struct ccd_softc)); + cs->sc_flags &= ~CCDF_INITED; /* * Free ccddevice information and clear entry. @@ -1122,7 +1128,11 @@ ccdioctl(dev, cmd, data, flag, p) ccd.ccd_dk = -1; bcopy(&ccd, &ccddevs[unit], sizeof(ccd)); + /* This must be atomic. */ + s = splhigh(); ccdunlock(cs); + bzero(cs, sizeof(struct ccd_softc)); + splx(s); break; |