summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_disk.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1999-11-06 10:25:58 +0000
committerphk <phk@FreeBSD.org>1999-11-06 10:25:58 +0000
commit6d8658fdf79a07f5d249e7026b9e69f16b59198a (patch)
treee54f14b9b7b4144b798c299e0ab03a31ffae3320 /sys/kern/subr_disk.c
parentbd87d69eda3d704f97820326f8f17b533446670b (diff)
downloadFreeBSD-src-6d8658fdf79a07f5d249e7026b9e69f16b59198a.zip
FreeBSD-src-6d8658fdf79a07f5d249e7026b9e69f16b59198a.tar.gz
Put a lock on the disk structure while we open to avoid races.
PR: 14486
Diffstat (limited to 'sys/kern/subr_disk.c')
-rw-r--r--sys/kern/subr_disk.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/sys/kern/subr_disk.c b/sys/kern/subr_disk.c
index b68948e..50cb1d8 100644
--- a/sys/kern/subr_disk.c
+++ b/sys/kern/subr_disk.c
@@ -52,7 +52,7 @@ disk_create(int unit, struct disk *dp, int flags, struct cdevsw *cdevsw, struct
dev->si_disk = dp;
dp->d_dev = dev;
- dp->d_flags = flags;
+ dp->d_dsflags = flags;
dp->d_devsw = cdevsw;
return (dev);
}
@@ -114,6 +114,12 @@ diskopen(dev_t dev, int oflags, int devtype, struct proc *p)
if (!dp)
return (ENXIO);
+ while (dp->d_flags & DISKFLAG_LOCK) {
+ dp->d_flags |= DISKFLAG_WANTED;
+ tsleep(dp, PRIBIO | PCATCH, "diskopen", hz);
+ }
+ dp->d_flags |= DISKFLAG_LOCK;
+
if (!dsisopen(dp->d_slice)) {
if (!pdev->si_iosize_max)
pdev->si_iosize_max = dev->si_iosize_max;
@@ -129,12 +135,18 @@ diskopen(dev_t dev, int oflags, int devtype, struct proc *p)
dev->si_bsize_best = pdev->si_bsize_best;
if (error)
- return(error);
+ goto out;
- error = dsopen(dev, devtype, dp->d_flags, &dp->d_slice, &dp->d_label);
+ error = dsopen(dev, devtype, dp->d_dsflags, &dp->d_slice, &dp->d_label);
if (!dsisopen(dp->d_slice))
dp->d_devsw->d_close(pdev, oflags, devtype, p);
+out:
+ dp->d_flags &= ~DISKFLAG_LOCK;
+ if (dp->d_flags & DISKFLAG_WANTED) {
+ dp->d_flags &= ~DISKFLAG_WANTED;
+ wakeup(dp);
+ }
return(error);
}
OpenPOWER on IntegriCloud