The diff below adds some very common disk driver logic into
subr_disk.c and refactors most of the MI disk drivers to take
advantage of them.  I'll followup with the MD disk drivers later (a
lot of them need other cleanups anyway).

There should be no behavioral change.  The only part of the diff that
might not be intuitive is in cd.c and sd.c, the 'out' label is
effectively moved to before the partition validity check, but that's
okay because 'goto out' is only run when opening the raw partition
(which is still unconditionally allowed by disk_openpart()).

ok?

Index: sys/disk.h
===================================================================
RCS file: /home/mdempsky/anoncvs/cvs/src/sys/sys/disk.h,v
retrieving revision 1.30
diff -u -p -r1.30 disk.h
--- sys/disk.h  19 Jun 2011 04:51:06 -0000      1.30
+++ sys/disk.h  27 Jun 2011 17:02:15 -0000
@@ -154,6 +154,9 @@ void        disk_init(void);
 int    disk_construct(struct disk *);
 void   disk_attach(struct device *, struct disk *);
 void   disk_detach(struct disk *);
+int    disk_openpart(struct disk *, int, int, int);
+void   disk_closepart(struct disk *, int, int);
+void   disk_gone(int (*)(dev_t, int, int, struct proc *), int);
 void   disk_busy(struct disk *);
 void   disk_unbusy(struct disk *, long, int);
 
Index: kern/subr_disk.c
===================================================================
RCS file: /home/mdempsky/anoncvs/cvs/src/sys/kern/subr_disk.c,v
retrieving revision 1.126
diff -u -p -r1.126 subr_disk.c
--- kern/subr_disk.c    19 Jun 2011 04:53:17 -0000      1.126
+++ kern/subr_disk.c    27 Jun 2011 17:02:15 -0000
@@ -896,6 +896,63 @@ disk_detach(struct disk *diskp)
                panic("disk_detach: disk_count < 0");
 }
 
+int
+disk_openpart(struct disk *dk, int part, int fmt, int haslabel)
+{
+       KASSERT(part >= 0 && part < MAXPARTITIONS);
+
+       /* Unless opening the raw partition, check that the partition exists. */
+       if (part != RAW_PART && (!haslabel ||
+           part >= dk->dk_label->d_npartitions ||
+           dk->dk_label->d_partitions[part].p_fstype == FS_UNUSED))
+               return (ENXIO);
+
+       /* Ensure the partition doesn't get changed under our feet. */
+       switch (fmt) {
+       case S_IFCHR:
+               dk->dk_copenmask |= (1 << part);
+               break;
+       case S_IFBLK:
+               dk->dk_bopenmask |= (1 << part);
+               break;
+       }
+       dk->dk_openmask = dk->dk_copenmask | dk->dk_bopenmask;
+
+       return (0);
+}
+
+void
+disk_closepart(struct disk *dk, int part, int fmt)
+{
+       KASSERT(part >= 0 && part < MAXPARTITIONS);
+
+       switch (fmt) {
+       case S_IFCHR:
+               dk->dk_copenmask &= ~(1 << part);
+               break;
+       case S_IFBLK:
+               dk->dk_bopenmask &= ~(1 << part);
+               break;
+       }
+       dk->dk_openmask = dk->dk_copenmask | dk->dk_bopenmask;
+}
+
+void
+disk_gone(int (*open)(dev_t, int, int, struct proc *), int unit)
+{
+       int bmaj, cmaj, mn;
+
+       /* Locate the lowest minor number to be detached. */
+       mn = DISKMINOR(unit, 0);
+
+       for (bmaj = 0; bmaj < nblkdev; bmaj++)
+               if (bdevsw[bmaj].d_open == open)
+                       vdevgone(bmaj, mn, mn + MAXPARTITIONS - 1, VBLK);
+       for (cmaj = 0; cmaj < nchrdev; cmaj++)
+               if (cdevsw[cmaj].d_open == open)
+                       vdevgone(cmaj, mn, mn + MAXPARTITIONS - 1, VCHR);
+}
+
 /*
  * Increment a disk's busy counter.  If the counter is going from
  * 0 to 1, set the timestamp.
Index: scsi/sd.c
===================================================================
RCS file: /home/mdempsky/anoncvs/cvs/src/sys/scsi/sd.c,v
retrieving revision 1.230
diff -u -p -r1.230 sd.c
--- scsi/sd.c   19 Jun 2011 04:55:34 -0000      1.230
+++ scsi/sd.c   27 Jun 2011 17:02:15 -0000
@@ -297,19 +297,10 @@ int
 sddetach(struct device *self, int flags)
 {
        struct sd_softc *sc = (struct sd_softc *)self;
-       int bmaj, cmaj, mn;
 
        bufq_drain(&sc->sc_bufq);
 
-       /* Locate the lowest minor number to be detached. */
-       mn = DISKMINOR(self->dv_unit, 0);
-
-       for (bmaj = 0; bmaj < nblkdev; bmaj++)
-               if (bdevsw[bmaj].d_open == sdopen)
-                       vdevgone(bmaj, mn, mn + MAXPARTITIONS - 1, VBLK);
-       for (cmaj = 0; cmaj < nchrdev; cmaj++)
-               if (cdevsw[cmaj].d_open == sdopen)
-                       vdevgone(cmaj, mn, mn + MAXPARTITIONS - 1, VCHR);
+       disk_gone(sdopen, self->dv_unit);
 
        /* Get rid of the shutdown hook. */
        if (sc->sc_sdhook != NULL)
@@ -428,24 +419,10 @@ sdopen(dev_t dev, int flag, int fmt, str
                SC_DEBUG(sc_link, SDEV_DB3, ("Disklabel loaded\n"));
        }
 
-       /* Check that the partition exists. */
-       if (part != RAW_PART &&
-           (part >= sc->sc_dk.dk_label->d_npartitions ||
-           sc->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) {
-               error = ENXIO;
+out:
+       if ((error = disk_openpart(&sc->sc_dk, part, fmt, 1)) != 0)
                goto bad;
-       }
 
-out:   /* Insure only one open at a time. */
-       switch (fmt) {
-       case S_IFCHR:
-               sc->sc_dk.dk_copenmask |= (1 << part);
-               break;
-       case S_IFBLK:
-               sc->sc_dk.dk_bopenmask |= (1 << part);
-               break;
-       }
-       sc->sc_dk.dk_openmask = sc->sc_dk.dk_copenmask | sc->sc_dk.dk_bopenmask;
        SC_DEBUG(sc_link, SDEV_DB3, ("open complete\n"));
 
        /* It's OK to fall through because dk_openmask is now non-zero. */
@@ -483,15 +460,7 @@ sdclose(dev_t dev, int flag, int fmt, st
 
        disk_lock_nointr(&sc->sc_dk);
 
-       switch (fmt) {
-       case S_IFCHR:
-               sc->sc_dk.dk_copenmask &= ~(1 << part);
-               break;
-       case S_IFBLK:
-               sc->sc_dk.dk_bopenmask &= ~(1 << part);
-               break;
-       }
-       sc->sc_dk.dk_openmask = sc->sc_dk.dk_copenmask | sc->sc_dk.dk_bopenmask;
+       disk_closepart(&sc->sc_dk, part, fmt);
 
        if (sc->sc_dk.dk_openmask == 0) {
                if ((sc->flags & SDF_DIRTY) != 0)
Index: scsi/cd.c
===================================================================
RCS file: /home/mdempsky/anoncvs/cvs/src/sys/scsi/cd.c,v
retrieving revision 1.204
diff -u -p -r1.204 cd.c
--- scsi/cd.c   19 Jun 2011 04:55:34 -0000      1.204
+++ scsi/cd.c   27 Jun 2011 17:02:15 -0000
@@ -264,19 +264,10 @@ int
 cddetach(struct device *self, int flags)
 {
        struct cd_softc *sc = (struct cd_softc *)self;
-       int bmaj, cmaj, mn;
 
        bufq_drain(&sc->sc_bufq);
 
-       /* Locate the lowest minor number to be detached. */
-       mn = DISKMINOR(self->dv_unit, 0);
-
-       for (bmaj = 0; bmaj < nblkdev; bmaj++)
-               if (bdevsw[bmaj].d_open == cdopen)
-                       vdevgone(bmaj, mn, mn + MAXPARTITIONS - 1, VBLK);
-       for (cmaj = 0; cmaj < nchrdev; cmaj++)
-               if (cdevsw[cmaj].d_open == cdopen)
-                       vdevgone(cmaj, mn, mn + MAXPARTITIONS - 1, VCHR);
+       disk_gone(cdopen, self->dv_unit);
 
        /* Detach disk. */
        bufq_destroy(&sc->sc_bufq);
@@ -379,23 +370,10 @@ cdopen(dev_t dev, int flag, int fmt, str
                SC_DEBUG(sc_link, SDEV_DB3, ("Disklabel fabricated\n"));
        }
 
-       /* Check that the partition exists. */
-       if (part != RAW_PART && (part >= sc->sc_dk.dk_label->d_npartitions ||
-           sc->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) {
-               error = ENXIO;
+out:
+       if ((error = disk_openpart(&sc->sc_dk, part, fmt, 1)) != 0)
                goto bad;
-       }
 
-out:   /* Insure only one open at a time. */
-       switch (fmt) {
-       case S_IFCHR:
-               sc->sc_dk.dk_copenmask |= (1 << part);
-               break;
-       case S_IFBLK:
-               sc->sc_dk.dk_bopenmask |= (1 << part);
-               break;
-       }
-       sc->sc_dk.dk_openmask = sc->sc_dk.dk_copenmask | sc->sc_dk.dk_bopenmask;
        sc_link->flags |= SDEV_OPEN;
        SC_DEBUG(sc_link, SDEV_DB3, ("open complete\n"));
 
@@ -433,15 +411,7 @@ cdclose(dev_t dev, int flag, int fmt, st
 
        disk_lock_nointr(&sc->sc_dk);
 
-       switch (fmt) {
-       case S_IFCHR:
-               sc->sc_dk.dk_copenmask &= ~(1 << part);
-               break;
-       case S_IFBLK:
-               sc->sc_dk.dk_bopenmask &= ~(1 << part);
-               break;
-       }
-       sc->sc_dk.dk_openmask = sc->sc_dk.dk_copenmask | sc->sc_dk.dk_bopenmask;
+       disk_closepart(&sc->sc_dk, part, fmt);
 
        if (sc->sc_dk.dk_openmask == 0) {
                /* XXXX Must wait for I/O to complete! */
Index: dev/ata/wd.c
===================================================================
RCS file: /home/mdempsky/anoncvs/cvs/src/sys/dev/ata/wd.c,v
retrieving revision 1.106
diff -u -p -r1.106 wd.c
--- dev/ata/wd.c        20 Jun 2011 06:45:07 -0000      1.106
+++ dev/ata/wd.c        27 Jun 2011 17:02:15 -0000
@@ -370,21 +370,12 @@ int
 wddetach(struct device *self, int flags)
 {
        struct wd_softc *sc = (struct wd_softc *)self;
-       int bmaj, cmaj, mn;
 
        timeout_del(&sc->sc_restart_timeout);
 
        bufq_drain(&sc->sc_bufq);
 
-       /* Locate the lowest minor number to be detached. */
-       mn = DISKMINOR(self->dv_unit, 0);
-
-       for (bmaj = 0; bmaj < nblkdev; bmaj++)
-               if (bdevsw[bmaj].d_open == wdopen)
-                       vdevgone(bmaj, mn, mn + MAXPARTITIONS - 1, VBLK);
-       for (cmaj = 0; cmaj < nchrdev; cmaj++)
-               if (cdevsw[cmaj].d_open == wdopen)
-                       vdevgone(cmaj, mn, mn + MAXPARTITIONS - 1, VCHR);
+       disk_gone(wdopen, self->dv_unit);
 
        /* Get rid of the shutdown hook. */
        if (sc->sc_sdhook != NULL)
@@ -686,25 +677,8 @@ wdopen(dev_t dev, int flag, int fmt, str
 
        part = DISKPART(dev);
 
-       /* Check that the partition exists. */
-       if (part != RAW_PART &&
-           (part >= wd->sc_dk.dk_label->d_npartitions ||
-            wd->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) {
-               error = ENXIO;
+       if ((error = disk_openpart(&wd->sc_dk, part, fmt, 1)) != 0)
                goto bad;
-       }
-
-       /* Insure only one open at a time. */
-       switch (fmt) {
-       case S_IFCHR:
-               wd->sc_dk.dk_copenmask |= (1 << part);
-               break;
-       case S_IFBLK:
-               wd->sc_dk.dk_bopenmask |= (1 << part);
-               break;
-       }
-       wd->sc_dk.dk_openmask =
-           wd->sc_dk.dk_copenmask | wd->sc_dk.dk_bopenmask;
 
        disk_unlock(&wd->sc_dk);
        device_unref(&wd->sc_dev);
@@ -735,16 +709,7 @@ wdclose(dev_t dev, int flag, int fmt, st
 
        disk_lock_nointr(&wd->sc_dk);
 
-       switch (fmt) {
-       case S_IFCHR:
-               wd->sc_dk.dk_copenmask &= ~(1 << part);
-               break;
-       case S_IFBLK:
-               wd->sc_dk.dk_bopenmask &= ~(1 << part);
-               break;
-       }
-       wd->sc_dk.dk_openmask =
-           wd->sc_dk.dk_copenmask | wd->sc_dk.dk_bopenmask;
+       disk_closepart(&wd->sc_dk, part, fmt);
 
        if (wd->sc_dk.dk_openmask == 0) {
                wd_flushcache(wd, 0);
Index: dev/vnd.c
===================================================================
RCS file: /home/mdempsky/anoncvs/cvs/src/sys/dev/vnd.c,v
retrieving revision 1.133
diff -u -p -r1.133 vnd.c
--- dev/vnd.c   21 Jun 2011 01:47:15 -0000      1.133
+++ dev/vnd.c   27 Jun 2011 17:02:15 -0000
@@ -181,7 +181,7 @@ vndopen(dev_t dev, int flags, int mode, 
 {
        int unit = vndunit(dev);
        struct vnd_softc *sc;
-       int error = 0, part, pmask;
+       int error = 0, part;
 
        DNPRINTF(VDB_FOLLOW, "vndopen(%x, %x, %x, %p)\n", dev, flags, mode, p);
 
@@ -204,29 +204,9 @@ vndopen(dev_t dev, int flags, int mode, 
        }
 
        part = DISKPART(dev);
-       pmask = 1 << part;
 
-       /* Check that the partition exists. */
-       if (part != RAW_PART &&
-           ((sc->sc_flags & VNF_HAVELABEL) == 0 ||
-           part >= sc->sc_dk.dk_label->d_npartitions ||
-           sc->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) {
-               error = ENXIO;
-               goto bad;
-       }
-
-       /* Prevent our unit from being unconfigured while open. */
-       switch (mode) {
-       case S_IFCHR:
-               sc->sc_dk.dk_copenmask |= pmask;
-               break;
-
-       case S_IFBLK:
-               sc->sc_dk.dk_bopenmask |= pmask;
-               break;
-       }
-       sc->sc_dk.dk_openmask =
-           sc->sc_dk.dk_copenmask | sc->sc_dk.dk_bopenmask;
+       error = disk_openpart(&sc->sc_dk, part, mode,
+           (sc->sc_flags & VNF_HAVELABEL) != 0);
 
 bad:
        disk_unlock(&sc->sc_dk);
@@ -280,18 +260,7 @@ vndclose(dev_t dev, int flags, int mode,
 
        part = DISKPART(dev);
 
-       /* ...that much closer to allowing unconfiguration... */
-       switch (mode) {
-       case S_IFCHR:
-               sc->sc_dk.dk_copenmask &= ~(1 << part);
-               break;
-
-       case S_IFBLK:
-               sc->sc_dk.dk_bopenmask &= ~(1 << part);
-               break;
-       }
-       sc->sc_dk.dk_openmask =
-           sc->sc_dk.dk_copenmask | sc->sc_dk.dk_bopenmask;
+       disk_closepart(&sc->sc_dk, part, mode);
 
        disk_unlock(&sc->sc_dk);
        return (0);
Index: dev/rd.c
===================================================================
RCS file: /home/mdempsky/anoncvs/cvs/src/sys/dev/rd.c,v
retrieving revision 1.3
diff -u -p -r1.3 rd.c
--- dev/rd.c    23 Jun 2011 17:06:07 -0000      1.3
+++ dev/rd.c    27 Jun 2011 17:26:06 -0000
@@ -136,17 +136,8 @@ int
 rd_detach(struct device *self, int flags)
 {
        struct rd_softc *sc = (struct rd_softc *)self;
-       int bmaj, cmaj, mn;
 
-       /* Locate the lowest minor number to be detached. */
-       mn = DISKMINOR(self->dv_unit, 0);
-
-       for (bmaj = 0; bmaj < nblkdev; bmaj++)
-               if (bdevsw[bmaj].d_open == rdopen)
-                       vdevgone(bmaj, mn, mn + MAXPARTITIONS - 1, VBLK);
-       for (cmaj = 0; cmaj < nchrdev; cmaj++)
-               if (cdevsw[cmaj].d_open == rdopen)
-                       vdevgone(cmaj, mn, mn + MAXPARTITIONS - 1, VCHR);
+       disk_gone(rdopen, self->dv_unit);
 
        /* Detach disk. */
        disk_detach(&sc->sc_dk);
@@ -178,23 +169,7 @@ rdopen(dev_t dev, int flag, int fmt, str
                        goto unlock;
        }
 
-       /* Check that the partition exists. */
-       if (part != RAW_PART && (part >= sc->sc_dk.dk_label->d_npartitions ||
-           sc->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) {
-               error = ENXIO;
-               goto unlock;
-       }
-
-       /* Ensure the partition doesn't get changed under our feet. */
-       switch (fmt) {
-       case S_IFCHR:
-               sc->sc_dk.dk_copenmask |= (1 << part);
-               break;
-       case S_IFBLK:
-               sc->sc_dk.dk_bopenmask |= (1 << part);
-               break;
-       }
-       sc->sc_dk.dk_openmask = sc->sc_dk.dk_copenmask | sc->sc_dk.dk_bopenmask;
+       error = disk_openpart(&sc->sc_dk, part, fmt, 1);
 
  unlock:
        disk_unlock(&sc->sc_dk);
@@ -218,15 +193,7 @@ rdclose(dev_t dev, int flag, int fmt, st
 
        disk_lock_nointr(&sc->sc_dk);
 
-       switch (fmt) {
-       case S_IFCHR:
-               sc->sc_dk.dk_copenmask &= ~(1 << part);
-               break;
-       case S_IFBLK:
-               sc->sc_dk.dk_bopenmask &= ~(1 << part);
-               break;
-       }
-       sc->sc_dk.dk_openmask = sc->sc_dk.dk_copenmask | sc->sc_dk.dk_bopenmask;
+       disk_closepart(&sc->sc_dk, part, fmt);
 
        disk_unlock(&sc->sc_dk);
        device_unref(&sc->sc_dev);
Index: dev/ccd.c
===================================================================
RCS file: /home/mdempsky/anoncvs/cvs/src/sys/dev/ccd.c,v
retrieving revision 1.95
diff -u -p -r1.95 ccd.c
--- dev/ccd.c   5 Jun 2011 18:40:33 -0000       1.95
+++ dev/ccd.c   27 Jun 2011 17:03:29 -0000
@@ -553,7 +553,7 @@ ccdopen(dev_t dev, int flags, int fmt, s
        int unit = DISKUNIT(dev);
        struct ccd_softc *cs;
        struct disklabel *lp;
-       int error = 0, part, pmask;
+       int error = 0, part;
 
        CCD_DPRINTF(CCDB_FOLLOW, ("ccdopen(%x, %x)\n", dev, flags));
 
@@ -567,7 +567,6 @@ ccdopen(dev_t dev, int flags, int fmt, s
        lp = cs->sc_dkdev.dk_label;
 
        part = DISKPART(dev);
-       pmask = (1 << part);
 
        /*
         * If we're initialized, check to see if there are any other
@@ -577,30 +576,9 @@ ccdopen(dev_t dev, int flags, int fmt, s
        if ((cs->sc_flags & CCDF_INITED) && (cs->sc_dkdev.dk_openmask == 0))
                ccdgetdisklabel(dev, cs, lp, 0);
 
-       /* Check that the partition exists. */
-       if (part != RAW_PART) {
-               if (((cs->sc_flags & CCDF_INITED) == 0) ||
-                   ((part >= lp->d_npartitions) ||
-                   (lp->d_partitions[part].p_fstype == FS_UNUSED))) {
-                       error = ENXIO;
-                       goto done;
-               }
-       }
-
-       /* Prevent our unit from being unconfigured while open. */
-       switch (fmt) {
-       case S_IFCHR:
-               cs->sc_dkdev.dk_copenmask |= pmask;
-               break;
-
-       case S_IFBLK:
-               cs->sc_dkdev.dk_bopenmask |= pmask;
-               break;
-       }
-       cs->sc_dkdev.dk_openmask =
-           cs->sc_dkdev.dk_copenmask | cs->sc_dkdev.dk_bopenmask;
+       error = disk_openpart(&cs->sc_dkdev, part, fmt,
+           (cs->sc_flags & CCDF_INITED) != 0);
 
- done:
        ccdunlock(cs);
        return (error);
 }
@@ -624,18 +602,7 @@ ccdclose(dev_t dev, int flags, int fmt, 
 
        part = DISKPART(dev);
 
-       /* ...that much closer to allowing unconfiguration... */
-       switch (fmt) {
-       case S_IFCHR:
-               cs->sc_dkdev.dk_copenmask &= ~(1 << part);
-               break;
-
-       case S_IFBLK:
-               cs->sc_dkdev.dk_bopenmask &= ~(1 << part);
-               break;
-       }
-       cs->sc_dkdev.dk_openmask =
-           cs->sc_dkdev.dk_copenmask | cs->sc_dkdev.dk_bopenmask;
+       disk_closepart(&cs->sc_dkdev, part, fmt);
 
        ccdunlock(cs);
        return (0);

Reply via email to