diff options
author | phk <phk@FreeBSD.org> | 1999-11-06 10:25:58 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 1999-11-06 10:25:58 +0000 |
commit | 6d8658fdf79a07f5d249e7026b9e69f16b59198a (patch) | |
tree | e54f14b9b7b4144b798c299e0ab03a31ffae3320 /sys/kern/subr_disk.c | |
parent | bd87d69eda3d704f97820326f8f17b533446670b (diff) | |
download | FreeBSD-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.c | 18 |
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); } |