diff options
author | tegge <tegge@FreeBSD.org> | 1997-06-25 19:07:43 +0000 |
---|---|---|
committer | tegge <tegge@FreeBSD.org> | 1997-06-25 19:07:43 +0000 |
commit | 988f978710326fc294e3ebe6b7231a5b2807c6f8 (patch) | |
tree | ab7e9ccf1be3e96bf94b4abd5d5faf132b743dd1 /sys/scsi/sd.c | |
parent | 228f6410f312edf048c05ed76a7d84d3d954a339 (diff) | |
download | FreeBSD-src-988f978710326fc294e3ebe6b7231a5b2807c6f8.zip FreeBSD-src-988f978710326fc294e3ebe6b7231a5b2807c6f8.tar.gz |
Introduce an advisory exclusive lock on the scsi link structure.
Change sd_open, sd_close and sd_ioctl to use this lock to ensure
serialization of some critical operations, thus avoiding some
race conditions. Ideas picked from NetBSD (ccd and sd devices).
This fixes one of the problems noted in PR kern/3688.
Reviewed by: "Justin T. Gibbs" <gibbs@plutotech.com>
Diffstat (limited to 'sys/scsi/sd.c')
-rw-r--r-- | sys/scsi/sd.c | 19 |
1 files changed, 18 insertions, 1 deletions
diff --git a/sys/scsi/sd.c b/sys/scsi/sd.c index cef96bd..8386c42 100644 --- a/sys/scsi/sd.c +++ b/sys/scsi/sd.c @@ -15,7 +15,7 @@ * * Ported to run under 386BSD by Julian Elischer (julian@dialix.oz.au) Sept 1992 * - * $Id: sd.c,v 1.104 1997/03/24 11:25:02 bde Exp $ + * $Id: sd.c,v 1.105 1997/05/01 19:15:38 sos Exp $ */ #include "opt_bounce.h" @@ -279,6 +279,10 @@ sd_open(dev, mode, fmt, p, sc_link) */ scsi_test_unit_ready(sc_link, 0); + errcode = scsi_device_lock(sc_link); + if (errcode) + return errcode; + /* * If it's been invalidated, then forget the label */ @@ -354,6 +358,7 @@ sd_open(dev, mode, fmt, p, sc_link) SC_DEBUG(sc_link, SDEV_DB3, ("open %ld %ld\n", sdstrats, sdqueues)); + scsi_device_unlock(sc_link); return 0; bad: @@ -361,6 +366,7 @@ bad: scsi_prevent(sc_link, PR_ALLOW, SCSI_ERR_OK | SCSI_SILENT); sc_link->flags &= ~SDEV_OPEN; } + scsi_device_unlock(sc_link); return errcode; } @@ -377,13 +383,18 @@ sd_close(dev, fflag, fmt, p, sc_link) struct scsi_link *sc_link; { struct scsi_data *sd; + errval errcode; sd = sc_link->sd; + errcode = scsi_device_lock(sc_link); + if (errcode) + return errcode; dsclose(dev, fmt, sd->dk_slices); if (!dsisopen(sd->dk_slices)) { scsi_prevent(sc_link, PR_ALLOW, SCSI_SILENT | SCSI_ERR_OK); sc_link->flags &= ~SDEV_OPEN; } + scsi_device_unlock(sc_link); return (0); } @@ -661,8 +672,14 @@ sd_ioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p, if (cmd == DIOCSBAD) return (EINVAL); /* XXX */ + + error = scsi_device_lock(sc_link); + if (error) + return error; + error = dsioctl("sd", dev, cmd, addr, flag, &sd->dk_slices, sdstrategy1, (ds_setgeom_t *)NULL); + scsi_device_unlock(sc_link); if (error != -1) return (error); if (PARTITION(dev) != RAW_PART) |