Give the device major / minor numbers their own separate 32 bit fields
authorMatthew Dillon <dillon@dragonflybsd.org>
Wed, 9 May 2007 00:53:36 +0000 (00:53 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Wed, 9 May 2007 00:53:36 +0000 (00:53 +0000)
in the kernel.  Change dev_ops to use a RB tree to index major device
numbers and remove the 256 device major number limitation.

Build a dynamic major number assignment feature into dev_ops_add() and
adjust ASR (which already had a hand-rolled one), and MFS to use the
feature.  MFS at least does not require any filesystem visibility to
access its backing device.  Major devices numbers >= 256 are used for
dynamic assignment.

Retain filesystem compatibility for device numbers that fall within the
range that can be represented in UFS or struct stat (which is a single
32 bit field supporting 8 bit major numbers and 24 bit minor numbers).

45 files changed:
sys/dev/disk/ata/atapi-cd.c
sys/dev/disk/nata/atapi-cd.c
sys/dev/raid/asr/asr.c
sys/dev/raid/vinum/.gdbinit.kernel
sys/dev/serial/sio/sio.c
sys/emulation/linux/linux_misc.c
sys/kern/kern_conf.c
sys/kern/kern_device.c
sys/kern/kern_kinfo.c
sys/kern/vfs_conf.c
sys/kern/vfs_jops.c
sys/kern/vfs_journal.c
sys/kern/vfs_subr.c
sys/kern/vfs_syscalls.c
sys/kern/vfs_vnops.c
sys/sys/conf.h
sys/sys/device.h
sys/sys/journal.h
sys/sys/kern_syscall.h
sys/sys/vfscache.h
sys/sys/vnode.h
sys/vfs/fdesc/fdesc_vnops.c
sys/vfs/gnu/ext2fs/ext2_vfsops.c
sys/vfs/gnu/ext2fs/ext2_vnops.c
sys/vfs/hpfs/hpfs_vfsops.c
sys/vfs/hpfs/hpfs_vnops.c
sys/vfs/isofs/cd9660/cd9660_vfsops.c
sys/vfs/isofs/cd9660/cd9660_vnops.c
sys/vfs/mfs/mfs_vfsops.c
sys/vfs/mfs/mfs_vnops.c
sys/vfs/msdosfs/msdosfs_vfsops.c
sys/vfs/msdosfs/msdosfs_vnops.c
sys/vfs/nfs/nfs_serv.c
sys/vfs/nfs/nfs_subs.c
sys/vfs/nfs/nfs_vnops.c
sys/vfs/ntfs/ntfs_vfsops.c
sys/vfs/ntfs/ntfs_vnops.c
sys/vfs/nwfs/nwfs_node.c
sys/vfs/portal/portal_vnops.c
sys/vfs/smbfs/smbfs_node.c
sys/vfs/specfs/spec_vnops.c
sys/vfs/udf/udf_vfsops.c
sys/vfs/udf/udf_vnops.c
sys/vfs/ufs/ffs_vfsops.c
sys/vfs/ufs/ufs_vnops.c

index a1bf3c2..a0e0ab4 100644 (file)
@@ -26,7 +26,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/ata/atapi-cd.c,v 1.48.2.20 2002/11/25 05:30:31 njl Exp $
- * $DragonFly: src/sys/dev/disk/ata/atapi-cd.c,v 1.28 2006/12/22 23:26:15 swildner Exp $
+ * $DragonFly: src/sys/dev/disk/ata/atapi-cd.c,v 1.29 2007/05/09 00:53:32 dillon Exp $
  */
 
 #include "opt_ata.h"
@@ -1157,7 +1157,7 @@ acd_start(struct ata_device *atadev)
 
     bzero(ccb, sizeof(ccb));
 
-    track = (dev->si_udev & 0x00ff0000) >> 16;
+    track = (dev->si_uminor & 0x00ff0000) >> 16;
 
     if (track) {
        blocksize = (cdp->toc.tab[track - 1].control & 4) ? 2048 : 2352;
index f6cf7a5..c1e06ab 100644 (file)
@@ -24,7 +24,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/ata/atapi-cd.c,v 1.189 2006/06/28 15:04:10 sos Exp $
- * $DragonFly: src/sys/dev/disk/nata/atapi-cd.c,v 1.4 2007/01/09 20:56:16 tgen Exp $
+ * $DragonFly: src/sys/dev/disk/nata/atapi-cd.c,v 1.5 2007/05/09 00:53:33 dillon Exp $
  */
 
 #include "opt_ata.h"
@@ -818,7 +818,7 @@ acd_start(device_t dev, struct bio *bp)
     bzero(ccb, sizeof(ccb));
 
     /* AND the unit number out of the minor, and shift the tracknumber back */
-    track = (cdev->si_udev & 0x00ff0000) >> 16;
+    track = (cdev->si_uminor & 0x00ff0000) >> 16;
 
     if (track) {
        blocksize = (cdp->toc.tab[track - 1].control & 4) ? 2048 : 2352;
index 6400c76..d53cd6b 100644 (file)
@@ -1,5 +1,5 @@
 /* $FreeBSD: src/sys/dev/asr/asr.c,v 1.3.2.2 2001/08/23 05:21:29 scottl Exp $ */
-/* $DragonFly: src/sys/dev/raid/asr/asr.c,v 1.28 2006/12/22 23:26:23 swildner Exp $ */
+/* $DragonFly: src/sys/dev/raid/asr/asr.c,v 1.29 2007/05/09 00:53:34 dillon Exp $ */
 /*
  * Copyright (c) 1996-2000 Distributed Processing Technology Corporation
  * Copyright (c) 2000-2001 Adaptec Corporation
@@ -466,9 +466,8 @@ DRIVER_MODULE(mode0, pci, mode0_driver, mode0_devclass, 0, 0);
  *
  * only ioctl is used. the sd driver provides all other access.
  */
-#define CDEV_MAJOR 154   /* prefered default character major */
 STATIC struct dev_ops asr_ops = {
-       { "asr", CDEV_MAJOR, 0 },
+       { "asr", -1, 0 },
         .d_open =      asr_open,
         .d_close =     asr_close, 
         .d_ioctl =     asr_ioctl,
@@ -486,35 +485,15 @@ asr_drvinit (void * unused)
                 return;
         }
         asr_devsw_installed++;
-        /*
-         * Find a free spot (the report during driver load used by
-         * osd layer in engine to generate the controlling nodes).
-        *
-        * XXX this is garbage code, store a unit number in asr_ops
-        * and iterate through that instead?
-         */
-        while (asr_ops.head.maj < NUMCDEVSW &&
-               dev_ops_get(asr_ops.head.maj, -1) != NULL
-       ) {
-                ++asr_ops.head.maj;
-        }
-        if (asr_ops.head.maj >= NUMCDEVSW) {
-               asr_ops.head.maj = 0;
-               while (asr_ops.head.maj < CDEV_MAJOR &&
-                       dev_ops_get(asr_ops.head.maj, -1) != NULL
-               ) {
-                       ++asr_ops.head.maj;
-               }
-       }
 
         /*
-         *      Come to papa
+        * Adding the ops will dynamically assign a major number.
          */
         dev_ops_add(&asr_ops, 0, 0);
 } /* asr_drvinit */
 
-/* Must initialize before CAM layer picks up our HBA driver */
-SYSINIT(asrdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,asr_drvinit,NULL)
+/* XXX Must initialize before CAM layer picks up our HBA driver */
+SYSINIT(asrdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE,asr_drvinit,NULL)
 
 /* I2O support routines */
 #define defAlignLong(STRUCT,NAME) char NAME[sizeof(STRUCT)]
index 1de0a80..1cba58d 100644 (file)
@@ -1,4 +1,4 @@
-# $DragonFly: src/sys/dev/raid/vinum/.gdbinit.kernel,v 1.7 2007/02/25 23:17:12 corecode Exp $
+# $DragonFly: src/sys/dev/raid/vinum/.gdbinit.kernel,v 1.8 2007/05/09 00:53:34 dillon Exp $
 set remotebaud 38400
 set remotetimeout 1
 set complaints 1
@@ -229,9 +229,10 @@ end
 define bpp
 set $bp = (struct buf *) $arg0
     if $bp->b_dev
-      printf "  Buffer at 0x%x: dev 0x%x  data 0x%x  bcount 0x%x  doffset 0x%llx resid 0x%x\n", \
+      printf "  Buffer at 0x%x: dev 0x%x:0x%x  data 0x%x  bcount 0x%x  doffset 0x%llx resid 0x%x\n", \
         $bp, \
-        $bp->b_dev->si_udev, \
+        $bp->b_dev->si_umajor, \
+        $bp->b_dev->si_uminor, \
         $bp->b_data, \
         $bp->b_bcount, \
         $bp->b_bio_array[1].bio_offset, \
index 04a7cd3..0fe8e4e 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/isa/sio.c,v 1.291.2.35 2003/05/18 08:51:15 murray Exp $
- * $DragonFly: src/sys/dev/serial/sio/sio.c,v 1.40 2007/05/07 05:21:40 dillon Exp $
+ * $DragonFly: src/sys/dev/serial/sio/sio.c,v 1.41 2007/05/09 00:53:34 dillon Exp $
  *     from: @(#)com.c 7.5 (Berkeley) 5/16/91
  *     from: i386/isa sio.c,v 1.234
  */
@@ -2977,7 +2977,6 @@ siocninit_fini(struct consdev *cp)
 {
        int unit;
 
-       kprintf("CP %d\n", cp->cn_probegood);
        if (cp->cn_probegood) {
                unit = (int)(intptr_t)cp->cn_private;
                cp->cn_dev = make_dev(&sio_ops, unit,
index 5a11aad..a1bd5e2 100644 (file)
@@ -26,7 +26,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/compat/linux/linux_misc.c,v 1.85.2.9 2002/09/24 08:11:41 mdodd Exp $
- * $DragonFly: src/sys/emulation/linux/linux_misc.c,v 1.37 2007/02/25 23:17:12 corecode Exp $
+ * $DragonFly: src/sys/emulation/linux/linux_misc.c,v 1.38 2007/05/09 00:53:34 dillon Exp $
  */
 
 #include "opt_compat.h"
@@ -857,7 +857,9 @@ sys_linux_mknod(struct linux_mknod_args *args)
                if (args->mode & S_IFIFO) {
                        error = kern_mkfifo(&nd, args->mode);
                } else {
-                       error = kern_mknod(&nd, args->mode, args->dev);
+                       error = kern_mknod(&nd, args->mode,
+                                          umajor(args->dev),
+                                          uminor(args->dev));
                }
        }
        nlookup_done(&nd);
index b2ca523..c99b38a 100644 (file)
@@ -31,7 +31,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/kern/kern_conf.c,v 1.73.2.3 2003/03/10 02:18:25 imp Exp $
- * $DragonFly: src/sys/kern/kern_conf.c,v 1.22 2007/05/08 02:31:42 dillon Exp $
+ * $DragonFly: src/sys/kern/kern_conf.c,v 1.23 2007/05/09 00:53:34 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -48,8 +48,6 @@
 
 #include <sys/sysref2.h>
 
-#define cdevsw_ALLOCSTART      (NUMCDEVSW/2)
-
 static void cdev_terminate(struct cdev *dev);
 
 MALLOC_DEFINE(M_DEVT, "cdev_t", "dev_t storage");
@@ -76,7 +74,7 @@ static struct sysref_class     cdev_sysref_class = {
  * udev_t's show that a prime halfway between two powers of two works
  * best.
  */
-#define DEVT_HASH 83
+#define DEVT_HASH 128  /* must be power of 2 */
 static LIST_HEAD(, cdev) dev_hash[DEVT_HASH];
 
 static int free_devt;
@@ -86,7 +84,7 @@ SYSCTL_INT(_debug, OID_AUTO, dev_refs, CTLFLAG_RW, &dev_ref_debug, 0, "");
 
 /*
  * cdev_t and u_dev_t primitives.  Note that the major number is always
- * extracted from si_udev, not from si_devsw, because si_devsw is replaced
+ * extracted from si_umajor, not from si_devsw, because si_devsw is replaced
  * when a device is destroyed.
  */
 int
@@ -94,7 +92,7 @@ major(cdev_t dev)
 {
        if (dev == NULL)
                return NOUDEV;
-       return((dev->si_udev >> 8) & 0xff);
+       return(dev->si_umajor);
 }
 
 int
@@ -102,18 +100,24 @@ minor(cdev_t dev)
 {
        if (dev == NULL)
                return NOUDEV;
-       return(dev->si_udev & 0xffff00ff);
+       return(dev->si_uminor);
 }
 
+/*
+ * Compatibility function with old udev_t format to convert the
+ * non-consecutive minor space into a consecutive minor space.
+ */
 int
 lminor(cdev_t dev)
 {
-       int i;
+       int y;
 
        if (dev == NULL)
                return NOUDEV;
-       i = minor(dev);
-       return ((i & 0xff) | (i >> 8));
+       y = dev->si_uminor;
+       if (y & 0x0000ff00)
+               return NOUDEV;
+       return ((y & 0xff) | (y >> 8));
 }
 
 /*
@@ -136,17 +140,22 @@ lminor(cdev_t dev)
  * otherwise would not match.
  */
 static
+int
+__devthash(int x, int y)
+{
+       return(((x << 2) ^ y) & (DEVT_HASH - 1));
+}
+
+static
 cdev_t
 hashdev(struct dev_ops *ops, int x, int y, int allow_intercept)
 {
        struct cdev *si;
-       udev_t  udev;
        int hash;
 
-       udev = makeudev(x, y);
-       hash = udev % DEVT_HASH;
+       hash = __devthash(x, y);
        LIST_FOREACH(si, &dev_hash[hash], si_hash) {
-               if (si->si_udev == udev) {
+               if (si->si_umajor == x && si->si_uminor == y) {
                        if (si->si_ops == ops)
                                return (si);
                        if (allow_intercept && (si->si_flags & SI_INTERCEPTED))
@@ -156,7 +165,8 @@ hashdev(struct dev_ops *ops, int x, int y, int allow_intercept)
        si = sysref_alloc(&cdev_sysref_class);
        si->si_ops = ops;
        si->si_flags |= SI_HASHED | SI_ADHOC;
-       si->si_udev = udev;
+       si->si_umajor = x;
+       si->si_uminor = y;
        LIST_INSERT_HEAD(&dev_hash[hash], si, si_hash);
        sysref_activate(&si->si_sysref);
 
@@ -165,21 +175,27 @@ hashdev(struct dev_ops *ops, int x, int y, int allow_intercept)
                ++ops->head.refs;
        if (dev_ref_debug) {
                kprintf("create    dev %p %s(minor=%08x) refs=%d\n", 
-                       si, devtoname(si), uminor(si->si_udev),
+                       si, devtoname(si), y,
                        si->si_sysref.refcnt);
        }
         return (si);
 }
 
 /*
- * Convert a device pointer to a device number
+ * Convert a device pointer to an old style device number.  Return NOUDEV
+ * if the device is invalid or if the device (maj,min) cannot be converted
+ * to an old style udev_t.
  */
 udev_t
 dev2udev(cdev_t dev)
 {
        if (dev == NULL)
                return NOUDEV;
-       return (dev->si_udev);
+       if ((dev->si_umajor & 0xffffff00) ||
+           (dev->si_uminor & 0x0000ff00)) {
+               return NOUDEV;
+       }
+       return((dev->si_umajor << 8) | dev->si_uminor);
 }
 
 /*
@@ -220,18 +236,24 @@ dev_is_good(cdev_t dev)
 int
 uminor(udev_t dev)
 {
+       if (dev == NOUDEV)
+               return(-1);
        return(dev & 0xffff00ff);
 }
 
 int
 umajor(udev_t dev)
 {
+       if (dev == NOUDEV)
+               return(-1);
        return((dev & 0xff00) >> 8);
 }
 
 udev_t
 makeudev(int x, int y)
 {
+       if ((x & 0xffffff00) || (y & 0x0000ff00))
+               return NOUDEV;
         return ((x << 8) | y);
 }
 
@@ -297,7 +319,7 @@ make_sub_dev(cdev_t odev, int minor)
 {
        cdev_t  dev;
 
-       dev = hashdev(odev->si_ops, umajor(odev->si_udev), minor, FALSE);
+       dev = hashdev(odev->si_ops, odev->si_umajor, minor, FALSE);
 
        /*
         * Copy cred requirements and name info XXX DEVFS.
@@ -307,6 +329,21 @@ make_sub_dev(cdev_t odev, int minor)
        return (dev);
 }
 
+cdev_t
+get_dev(int x, int y)
+{
+       cdev_t dev;
+       struct dev_ops *ops;
+
+       if (x == NOUDEV)
+               return(NULL);
+       ops = dev_ops_get(x, y);
+       if (ops == NULL)
+               return(NULL);
+       dev = hashdev(ops, x, y, TRUE);
+       return(dev);
+}
+
 /*
  * destroy_dev() removes the adhoc association for a device and revectors
  * its ops to &dead_dev_ops.
@@ -331,18 +368,18 @@ destroy_dev(cdev_t dev)
        }
        if (dev_ref_debug) {
                kprintf("destroy   dev %p %s(minor=%08x) refs=%d\n", 
-                       dev, devtoname(dev), uminor(dev->si_udev),
+                       dev, devtoname(dev), dev->si_uminor,
                        dev->si_sysref.refcnt);
        }
        if (dev->si_sysref.refcnt < 2) {
                kprintf("destroy_dev(): too few references on device! "
                        "%p %s(minor=%08x) refs=%d\n",
-                   dev, devtoname(dev), uminor(dev->si_udev),
+                   dev, devtoname(dev), dev->si_uminor,
                    dev->si_sysref.refcnt);
        }
        dev->si_flags &= ~SI_ADHOC;
        if (dev->si_flags & SI_HASHED) {
-               hash = dev->si_udev % DEVT_HASH;
+               hash = __devthash(dev->si_umajor, dev->si_uminor);
                LIST_REMOVE(dev, si_hash);
                dev->si_flags &= ~SI_HASHED;
        }
@@ -368,10 +405,8 @@ destroy_dev(cdev_t dev)
  * values. 
  *
  * Unlike the ops functions whos link structures do not contain
- * any major bits, this function scans through the dev list via si_udev
- * which is a 32 bit field that contains both major and minor bits.
- * Because of this, we must mask the minor bits in the passed mask variable
- * to allow -1 to be specified generically.
+ * any major bits, this function scans through the dev list via
+ * si_umajor/si_uminor.
  *
  * The caller must not include any major bits in the match value.
  */
@@ -382,14 +417,13 @@ destroy_all_devs(struct dev_ops *ops, u_int mask, u_int match)
        cdev_t dev;
        cdev_t ndev;
 
-       mask = uminor(mask);
        for (i = 0; i < DEVT_HASH; ++i) {
                ndev = LIST_FIRST(&dev_hash[i]);
                while ((dev = ndev) != NULL) {
                    ndev = LIST_NEXT(dev, si_hash);
                    KKASSERT(dev->si_flags & SI_ADHOC);
                    if (dev->si_ops == ops && 
-                       (dev->si_udev & mask) == match
+                       ((u_int)dev->si_uminor & mask) == match
                    ) {
                        reference_dev(dev);
                        destroy_dev(dev);
@@ -414,7 +448,7 @@ reference_dev(cdev_t dev)
                sysref_get(&dev->si_sysref);
                if (dev_ref_debug) {
                        kprintf("reference dev %p %s(minor=%08x) refs=%d\n", 
-                           dev, devtoname(dev), uminor(dev->si_udev),
+                           dev, devtoname(dev), dev->si_uminor,
                            dev->si_sysref.refcnt);
                }
        }
@@ -425,7 +459,7 @@ reference_dev(cdev_t dev)
  * release a reference on a device.  The device will be terminated when the
  * last reference has been released.
  *
- * NOTE: we must use si_udev to figure out the original (major, minor),
+ * NOTE: we must use si_umajor to figure out the original major number,
  * because si_ops could already be pointing at dead_dev_ops.
  */
 void
@@ -444,7 +478,7 @@ cdev_terminate(struct cdev *dev)
 
        if (dev_ref_debug) {
                kprintf("release   dev %p %s(minor=%08x) refs=%d\n", 
-                       dev, devtoname(dev), uminor(dev->si_udev),
+                       dev, devtoname(dev), dev->si_uminor,
                        dev->si_sysref.refcnt);
        }
        if (dev->si_flags & SI_ADHOC) {
index 0f9202b..80cb732 100644 (file)
@@ -27,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/kern/kern_device.c,v 1.23 2007/04/29 06:11:19 dillon Exp $
+ * $DragonFly: src/sys/kern/kern_device.c,v 1.24 2007/05/09 00:53:34 dillon Exp $
  */
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -42,6 +42,7 @@
 #include <sys/vnode.h>
 #include <sys/queue.h>
 #include <sys/device.h>
+#include <sys/tree.h>
 #include <sys/syslink_rpc.h>
 #include <sys/proc.h>
 #include <machine/stdarg.h>
@@ -94,11 +95,6 @@ struct dev_ops default_dev_ops = {
        .d_clone = noclone
 };
     
-/*
- * This is used to look-up devices
- */
-static struct dev_ops_link *dev_ops_array[NUMCDEVSW];
-
 /************************************************************************
  *                     GENERAL DEVICE API FUNCTIONS                    *
  ************************************************************************/
@@ -380,11 +376,13 @@ compile_dev_ops(struct dev_ops *ops)
 /*
  * This makes a dev_ops entry visible to userland (e.g /dev/<blah>).
  *
- * The kernel can overload a major number by making multiple dev_ops_add()
- * calls, but only the most recent one (the first one in the dev_ops_array[]
- * list matching the mask/match) will be visible to userland.  make_dev() does
- * not automatically call dev_ops_add() (nor do we want it to, since 
- * partition-managed disk devices are overloaded on top of the raw device).
+ * The kernel can overload a data space by making multiple dev_ops_add()
+ * calls, but only the most recent one in the list matching the mask/match
+ * will be visible to userland.
+ *
+ * make_dev() does not automatically call dev_ops_add() (nor do we want it
+ * to, since partition-managed disk devices are overloaded on top of the
+ * raw device).
  *
  * Disk devices typically register their major, e.g. 'ad0', and then call
  * into the disk label management code which overloads its own onto e.g. 'ad0'
@@ -397,20 +395,44 @@ compile_dev_ops(struct dev_ops *ops)
  * may be conveniently specified as -1 without creating any major number
  * interference.
  */
+
+static
+int
+rb_dev_ops_compare(struct dev_ops_maj *a, struct dev_ops_maj *b)
+{
+    if (a->maj < b->maj)
+       return(-1);
+    else if (a->maj > b->maj)
+       return(1);
+    return(0);
+}
+
+RB_GENERATE2(dev_ops_rb_tree, dev_ops_maj, rbnode, rb_dev_ops_compare, int, maj);
+
+struct dev_ops_rb_tree dev_ops_rbhead = RB_INITIALIZER(dev_ops_rbhead);
+
 int
 dev_ops_add(struct dev_ops *ops, u_int mask, u_int match)
 {
-    int maj;
+    static int next_maj = 256;         /* first dynamic major number */
+    struct dev_ops_maj *rbmaj;
     struct dev_ops_link *link;
 
     compile_dev_ops(ops);
-    maj = ops->head.maj;
-    if (maj < 0 || maj >= NUMCDEVSW) {
-           kprintf("%s: ERROR: driver has bogus dev_ops->head.maj = %d\n",
-                  ops->head.name, maj);
-           return (EINVAL);
+    if (ops->head.maj < 0) {
+       while (dev_ops_rb_tree_RB_LOOKUP(&dev_ops_rbhead, next_maj) != NULL) {
+               if (++next_maj <= 0)
+                       next_maj = 256;
+       }
+       ops->head.maj = next_maj;
+    }
+    rbmaj = dev_ops_rb_tree_RB_LOOKUP(&dev_ops_rbhead, ops->head.maj);
+    if (rbmaj == NULL) {
+       rbmaj = kmalloc(sizeof(*rbmaj), M_DEVBUF, M_INTWAIT | M_ZERO);
+       rbmaj->maj = ops->head.maj;
+       dev_ops_rb_tree_RB_INSERT(&dev_ops_rbhead, rbmaj);
     }
-    for (link = dev_ops_array[maj]; link; link = link->next) {
+    for (link = rbmaj->link; link; link = link->next) {
            /*
             * If we get an exact match we usurp the target, but we only print
             * a warning message if a different device switch is installed.
@@ -418,7 +440,7 @@ dev_ops_add(struct dev_ops *ops, u_int mask, u_int match)
            if (link->mask == mask && link->match == match) {
                    if (link->ops != ops) {
                            kprintf("WARNING: \"%s\" (%p) is usurping \"%s\"'s"
-                               " (%p) dev_ops_array[]\n",
+                               " (%p)\n",
                                ops->head.name, ops, 
                                link->ops->head.name, link->ops);
                            link->ops = ops;
@@ -435,8 +457,8 @@ dev_ops_add(struct dev_ops *ops, u_int mask, u_int match)
     link->mask = mask;
     link->match = match;
     link->ops = ops;
-    link->next = dev_ops_array[maj];
-    dev_ops_array[maj] = link;
+    link->next = rbmaj->link;
+    rbmaj->link = link;
     ++ops->head.refs;
     return(0);
 }
@@ -456,11 +478,13 @@ dev_ops_add(struct dev_ops *ops, u_int mask, u_int match)
 struct dev_ops *
 dev_ops_get(int x, int y)
 {
+       struct dev_ops_maj *rbmaj;
        struct dev_ops_link *link;
 
-       if (x < 0 || x >= NUMCDEVSW)
+       rbmaj = dev_ops_rb_tree_RB_LOOKUP(&dev_ops_rbhead, x);
+       if (rbmaj == NULL)
                return(NULL);
-       for (link = dev_ops_array[x]; link; link = link->next) {
+       for (link = rbmaj->link; link; link = link->next) {
                if (y == -1 || (link->mask & y) == link->match)
                        return(link->ops);
        }
@@ -502,25 +526,27 @@ dev_ops_add_override(cdev_t backing_dev, struct dev_ops *template,
 int
 dev_ops_remove(struct dev_ops *ops, u_int mask, u_int match)
 {
-       int maj = ops->head.maj;
+       struct dev_ops_maj *rbmaj;
        struct dev_ops_link *link;
        struct dev_ops_link **plink;
      
-       if (maj < 0 || maj >= NUMCDEVSW) {
-               kprintf("%s: ERROR: driver has bogus ops->d_maj = %d\n",
-                       ops->head.name, maj);
-               return EINVAL;
-       }
        if (ops != &dead_dev_ops)
                destroy_all_devs(ops, mask, match);
-       for (plink = &dev_ops_array[maj]; (link = *plink) != NULL;
+
+       rbmaj = dev_ops_rb_tree_RB_LOOKUP(&dev_ops_rbhead, ops->head.maj);
+       if (rbmaj == NULL) {
+               kprintf("double-remove of dev_ops %p for %s(%d)\n",
+                       ops, ops->head.name, ops->head.maj);
+               return(0);
+       }
+       for (plink = &rbmaj->link; (link = *plink) != NULL;
             plink = &link->next) {
                if (link->mask == mask && link->match == match) {
                        if (link->ops == ops)
                                break;
-                       kprintf("%s: ERROR: cannot remove from dev_ops_array[], "
+                       kprintf("%s: ERROR: cannot remove dev_ops, "
                               "its major number %d was stolen by %s\n",
-                               ops->head.name, maj,
+                               ops->head.name, ops->head.maj,
                                link->ops->head.name
                        );
                }
@@ -528,33 +554,83 @@ dev_ops_remove(struct dev_ops *ops, u_int mask, u_int match)
        if (link == NULL) {
                kprintf("%s(%d)[%08x/%08x]: WARNING: ops removed "
                       "multiple times!\n",
-                      ops->head.name, maj, mask, match);
+                      ops->head.name, ops->head.maj, mask, match);
        } else {
                *plink = link->next;
                --ops->head.refs; /* XXX ops_release() / record refs */
                kfree(link, M_DEVBUF);
        }
-       if (dev_ops_array[maj] == NULL && ops->head.refs != 0) {
+
+       /*
+        * Scrap the RB tree node for the major number if no ops are
+        * installed any longer.
+        */
+       if (rbmaj->link == NULL) {
+               dev_ops_rb_tree_RB_REMOVE(&dev_ops_rbhead, rbmaj);
+               kfree(rbmaj, M_DEVBUF);
+       }
+
+       if (ops->head.refs != 0) {
                kprintf("%s(%d)[%08x/%08x]: Warning: dev_ops_remove() called "
                        "while %d device refs still exist!\n", 
-                       ops->head.name, maj, mask, match, ops->head.refs);
+                       ops->head.name, ops->head.maj, mask, match,
+                       ops->head.refs);
        } else {
-               kprintf("%s: ops removed\n", ops->head.name);
+               if (bootverbose)
+                       kprintf("%s: ops removed\n", ops->head.name);
        }
        return 0;
 }
 
 /*
+ * dev_ops_scan() - Issue a callback for all installed dev_ops structures.
+ *
+ * The scan will terminate if a callback returns a negative number.
+ */
+struct dev_ops_scan_info {
+       int     (*callback)(struct dev_ops *, void *);
+       void    *arg;
+};
+
+static
+int
+dev_ops_scan_callback(struct dev_ops_maj *rbmaj, void *arg)
+{
+       struct dev_ops_scan_info *info = arg;
+       struct dev_ops_link *link;
+       int count = 0;
+       int r;
+
+       for (link = rbmaj->link; link; link = link->next) {
+               r = info->callback(link->ops, info->arg);
+               if (r < 0)
+                       return(r);
+               count += r;
+       }
+       return(count);
+}
+
+int
+dev_ops_scan(int (*callback)(struct dev_ops *, void *), void *arg)
+{
+       struct dev_ops_scan_info info = { callback, arg };
+
+       return (dev_ops_rb_tree_RB_SCAN(&dev_ops_rbhead, NULL,
+                                       dev_ops_scan_callback, &info));
+}
+
+
+/*
  * Release a ops entry.  When the ref count reaches zero, recurse
  * through the stack.
  */
 void
 dev_ops_release(struct dev_ops *ops)
 {
-    --ops->head.refs;
-    if (ops->head.refs == 0) {
-       /* XXX */
-    }
+       --ops->head.refs;
+       if (ops->head.refs == 0) {
+               /* XXX */
+       }
 }
 
 struct dev_ops *
index 6666115..f9bd3d8 100644 (file)
@@ -32,7 +32,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/kern/kern_kinfo.c,v 1.10 2007/05/08 02:31:42 dillon Exp $
+ * $DragonFly: src/sys/kern/kern_kinfo.c,v 1.11 2007/05/09 00:53:34 dillon Exp $
  */
 
 /*
@@ -107,9 +107,7 @@ fill_kinfo_proc(struct proc *p, struct kinfo_proc *kp)
        if (SESS_LEADER(p))
                kp->kp_auxflags |= KI_SLEADER;
        if (((p->p_flag & P_CONTROLT) != 0) && (sess->s_ttyp != NULL)) {
-               kp->kp_tdev = (sess->s_ttyp->t_dev != NULL) ?
-                                       sess->s_ttyp->t_dev->si_udev :
-                                       NOUDEV;
+               kp->kp_tdev = dev2udev(sess->s_ttyp->t_dev);
                if (sess->s_ttyp->t_pgrp != NULL)
                        kp->kp_tpgid = sess->s_ttyp->t_pgrp->pg_id;
                else
index a1168e1..1f68d86 100644 (file)
@@ -26,7 +26,7 @@
  * SUCH DAMAGE.
  *
  *     $FreeBSD: src/sys/kern/vfs_conf.c,v 1.49.2.5 2003/01/07 11:56:53 joerg Exp $
- *     $DragonFly: src/sys/kern/vfs_conf.c,v 1.28 2007/05/08 02:31:42 dillon Exp $
+ *     $DragonFly: src/sys/kern/vfs_conf.c,v 1.29 2007/05/09 00:53:34 dillon Exp $
  */
 
 /*
@@ -269,13 +269,13 @@ done:
 /*
  * Spin prompting on the console for a suitable root filesystem
  */
+static int vfs_mountroot_ask_callback(struct dev_ops *ops, void *arg);
+
 static int
 vfs_mountroot_ask(void)
 {
        char name[128];
-       int i;
        int llimit = 100;
-       cdev_t dev;
 
        kprintf("\nManual root filesystem specification:\n");
        kprintf("  <fstype>:<device>  Specify root (e.g. ufs:da0s1a)\n");
@@ -291,11 +291,7 @@ vfs_mountroot_ask(void)
                        ;
                } else if (name[0] == '?') {
                        kprintf("Possibly valid devices for 'ufs' root:\n");
-                       for (i = 0; i < NUMCDEVSW; i++) {
-                               dev = udev2dev(makeudev(i, 0), 0);
-                               if (dev_is_good(dev))
-                                       kprintf(" \"%s\"", dev_dname(dev));
-                       }
+                       dev_ops_scan(vfs_mountroot_ask_callback, NULL);
                        kprintf("\n");
                        continue;
                } else if (strcmp(name, "panic") == 0) {
@@ -309,6 +305,18 @@ vfs_mountroot_ask(void)
        return(1);
 }
 
+static
+int
+vfs_mountroot_ask_callback(struct dev_ops *ops, void *arg __unused)
+{
+       cdev_t dev;
+
+       dev = get_dev(ops->head.maj, 0);
+       if (dev_is_good(dev))
+               kprintf(" \"%s\"", dev_dname(dev));
+       return(0);
+}
+
 static int
 getline(char *cp, int limit)
 {
@@ -363,14 +371,23 @@ getline(char *cp, int limit)
  * Convert a given name to the cdev_t of the disk-like device
  * it refers to.
  */
+struct kdbn_info {
+       const char *name;
+       int nlen;
+       int minor;
+       cdev_t dev;
+};
+
+static int kgetdiskbyname_callback(struct dev_ops *ops, void *arg);
+
 cdev_t
 kgetdiskbyname(const char *name) 
 {
        char *cp;
        int nlen;
-       int cd, unit, slice, part;
-       cdev_t dev;
+       int unit, slice, part;
        cdev_t rdev;
+       struct kdbn_info info;
 
        /*
         * Get the base name of the device
@@ -433,18 +450,12 @@ kgetdiskbyname(const char *name)
        /*
         * Locate the device
         */
-       for (cd = 0; cd < NUMCDEVSW; cd++) {
-               const char *dname;
-
-               dev = udev2dev(makeudev(cd, dkmakeminor(unit, slice, part)), 0);
-               if (dev_is_good(dev) && (dname = dev_dname(dev)) != NULL) {
-                       if (strlen(dname) == nlen &&
-                           strncmp(dname, name, nlen) == 0) {
-                               break;
-                       }
-               }
-       }
-       if (cd == NUMCDEVSW) {
+       bzero(&info, sizeof(info));
+       info.nlen = nlen;
+       info.name = name;
+       info.minor = dkmakeminor(unit, slice, part);
+       dev_ops_scan(kgetdiskbyname_callback, &info);
+       if (info.dev == NULL) {
                kprintf("no such device '%*.*s'\n", nlen, nlen, name);
                return (NULL);
        }
@@ -452,10 +463,29 @@ kgetdiskbyname(const char *name)
        /*
         * FOUND DEVICE
         */
-       rdev = make_sub_dev(dev, dkmakeminor(unit, slice, part));
+       rdev = make_sub_dev(info.dev, info.minor);
        return(rdev);
 }
 
+static
+int
+kgetdiskbyname_callback(struct dev_ops *ops, void *arg)
+{
+       struct kdbn_info *info = arg;
+       cdev_t dev;
+       const char *dname;
+
+       dev = get_dev(ops->head.maj, info->minor);
+       if (dev_is_good(dev) && (dname = dev_dname(dev)) != NULL) {
+               if (strlen(dname) == info->nlen &&
+                   strncmp(dname, info->name, info->nlen) == 0) {
+                       info->dev = dev;
+                       return(-1);
+               }
+       }
+       return(0);
+}
+
 /*
  * Set rootdev to match (name), given that we expect it to
  * refer to a disk-like device.
index 7d49042..b9f5a74 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/kern/vfs_jops.c,v 1.33 2006/12/23 00:35:04 swildner Exp $
+ * $DragonFly: src/sys/kern/vfs_jops.c,v 1.34 2007/05/09 00:53:34 dillon Exp $
  */
 /*
  * Each mount point may have zero or more independantly configured journals
@@ -703,8 +703,12 @@ jrecord_undo_file(struct jrecord *jrec, struct vnode *vp, int jrflags,
            jrecord_leaf(jrec, JLEAF_GEN, &attr.va_gen, sizeof(attr.va_gen));
        if ((jrflags & JRUNDO_FLAGS) && attr.va_flags != VNOVAL)
            jrecord_leaf(jrec, JLEAF_FLAGS, &attr.va_flags, sizeof(attr.va_flags));
-       if ((jrflags & JRUNDO_UDEV) && attr.va_rdev != VNOVAL)
-           jrecord_leaf(jrec, JLEAF_UDEV, &attr.va_rdev, sizeof(attr.va_rdev));
+       if ((jrflags & JRUNDO_UDEV) && attr.va_rmajor != VNOVAL) {
+           udev_t rdev = makeudev(attr.va_rmajor, attr.va_rminor);
+           jrecord_leaf(jrec, JLEAF_UDEV, &rdev, sizeof(rdev));
+           jrecord_leaf(jrec, JLEAF_UMAJOR, &attr.va_rmajor, sizeof(attr.va_rmajor));
+           jrecord_leaf(jrec, JLEAF_UMINOR, &attr.va_rminor, sizeof(attr.va_rminor));
+       }
        jrecord_pop(jrec, save2);
     }
 
index 88f3e9b..32f6254 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/kern/vfs_journal.c,v 1.32 2007/01/25 18:19:31 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_journal.c,v 1.33 2007/05/09 00:53:34 dillon Exp $
  */
 /*
  * The journaling protocol is intended to evolve into a two-way stream
@@ -1229,8 +1229,12 @@ jrecord_write_vattr(struct jrecord *jrec, struct vattr *vat)
        jrecord_leaf(jrec, JLEAF_GEN, &vat->va_gen, sizeof(vat->va_gen));
     if (vat->va_flags != VNOVAL)
        jrecord_leaf(jrec, JLEAF_FLAGS, &vat->va_flags, sizeof(vat->va_flags));
-    if (vat->va_rdev != VNOVAL)
-       jrecord_leaf(jrec, JLEAF_UDEV, &vat->va_rdev, sizeof(vat->va_rdev));
+    if (vat->va_rmajor != VNOVAL) {
+       udev_t rdev = makeudev(vat->va_rmajor, vat->va_rminor);
+       jrecord_leaf(jrec, JLEAF_UDEV, &rdev, sizeof(rdev));
+       jrecord_leaf(jrec, JLEAF_UMAJOR, &vat->va_rmajor, sizeof(vat->va_rmajor));
+       jrecord_leaf(jrec, JLEAF_UMINOR, &vat->va_rminor, sizeof(vat->va_rminor));
+    }
 #if 0
     if (vat->va_filerev != VNOVAL)
        jrecord_leaf(jrec, JLEAF_FILEREV, &vat->va_filerev, sizeof(vat->va_filerev));
index ae90b64..3ce8f8e 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)vfs_subr.c  8.31 (Berkeley) 5/26/95
  * $FreeBSD: src/sys/kern/vfs_subr.c,v 1.249.2.30 2003/04/04 20:35:57 tegge Exp $
- * $DragonFly: src/sys/kern/vfs_subr.c,v 1.103 2007/05/08 02:31:42 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_subr.c,v 1.104 2007/05/09 00:53:34 dillon Exp $
  */
 
 /*
@@ -244,7 +244,8 @@ vattr_null(struct vattr *vap)
        vap->va_fsid = VNOVAL;
        vap->va_fileid = VNOVAL;
        vap->va_blocksize = VNOVAL;
-       vap->va_rdev = VNOVAL;
+       vap->va_rmajor = VNOVAL;
+       vap->va_rminor = VNOVAL;
        vap->va_atime.tv_sec = VNOVAL;
        vap->va_atime.tv_nsec = VNOVAL;
        vap->va_mtime.tv_sec = VNOVAL;
@@ -985,7 +986,8 @@ bdevvp(cdev_t dev, struct vnode **vpp)
        }
        vp = nvp;
        vp->v_type = VCHR;
-       vp->v_udev = dev->si_udev;
+       vp->v_umajor = dev->si_umajor;
+       vp->v_uminor = dev->si_uminor;
        vx_unlock(vp);
        *vpp = vp;
        return (0);
@@ -996,7 +998,7 @@ v_associate_rdev(struct vnode *vp, cdev_t dev)
 {
        lwkt_tokref ilock;
 
-       if (dev == NULL || dev == NULL)
+       if (dev == NULL)
                return(ENXIO);
        if (dev_is_good(dev) == 0)
                return(ENXIO);
@@ -1032,11 +1034,12 @@ v_release_rdev(struct vnode *vp)
  * disassociated on last close.
  */
 void
-addaliasu(struct vnode *nvp, udev_t nvp_udev)
+addaliasu(struct vnode *nvp, int x, int y)
 {
        if (nvp->v_type != VBLK && nvp->v_type != VCHR)
                panic("addaliasu on non-special vnode");
-       nvp->v_udev = nvp_udev;
+       nvp->v_umajor = x;
+       nvp->v_uminor = y;
 }
 
 /*
@@ -1180,10 +1183,10 @@ vop_stdrevoke(struct vop_revoke_args *ap)
         * The passed vp will probably show up in the list, do not VX lock
         * it twice!
         */
-       if (vp->v_type != VCHR && vp->v_type != VBLK)
+       if (vp->v_type != VCHR)
                return(0);
        if ((dev = vp->v_rdev) == NULL) {
-               if ((dev = udev2dev(vp->v_udev, vp->v_type == VBLK)) == NULL)
+               if ((dev = get_dev(vp->v_umajor, vp->v_uminor)) == NULL)
                        return(0);
        }
        reference_dev(dev);
@@ -1317,11 +1320,11 @@ count_dev(cdev_t dev)
 }
 
 int
-count_udev(udev_t udev)
+count_udev(int x, int y)
 {
        cdev_t dev;
 
-       if ((dev = udev2dev(udev, 0)) == NULL)
+       if ((dev = get_dev(x, y)) == NULL)
                return(0);
        return(count_dev(dev));
 }
@@ -1522,8 +1525,10 @@ vfs_mountedon(struct vnode *vp)
 {
        cdev_t dev;
 
-       if ((dev = vp->v_rdev) == NULL)
-               dev = udev2dev(vp->v_udev, (vp->v_type == VBLK));
+       if ((dev = vp->v_rdev) == NULL) {
+               if (vp->v_type != VBLK)
+                       dev = get_dev(vp->v_uminor, vp->v_umajor);
+       }
        if (dev != NULL && dev->si_mountpoint)
                return (EBUSY);
        return (0);
@@ -2000,14 +2005,15 @@ vn_isdisk(struct vnode *vp, int *errp)
 {
        cdev_t dev;
 
-       if (vp->v_type != VBLK && vp->v_type != VCHR) {
+       if (vp->v_type != VCHR) {
                if (errp != NULL)
                        *errp = ENOTBLK;
                return (0);
        }
 
        if ((dev = vp->v_rdev) == NULL)
-               dev = udev2dev(vp->v_udev, (vp->v_type == VBLK));
+               dev = get_dev(vp->v_umajor, vp->v_uminor);
+
        if (dev == NULL) {
                if (errp != NULL)
                        *errp = ENXIO;
index 42849e2..d604d5c 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)vfs_syscalls.c      8.13 (Berkeley) 4/15/94
  * $FreeBSD: src/sys/kern/vfs_syscalls.c,v 1.151.2.18 2003/04/04 20:35:58 tegge Exp $
- * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.115 2007/05/06 19:23:31 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.116 2007/05/09 00:53:34 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -1607,7 +1607,7 @@ sys_open(struct open_args *uap)
 }
 
 int
-kern_mknod(struct nlookupdata *nd, int mode, int dev)
+kern_mknod(struct nlookupdata *nd, int mode, int rmajor, int rminor)
 {
        struct thread *td = curthread;
        struct proc *p = td->td_proc;
@@ -1641,7 +1641,8 @@ kern_mknod(struct nlookupdata *nd, int mode, int dev)
 
        VATTR_NULL(&vattr);
        vattr.va_mode = (mode & ALLPERMS) &~ p->p_fd->fd_cmask;
-       vattr.va_rdev = dev;
+       vattr.va_rmajor = rmajor;
+       vattr.va_rminor = rminor;
        whiteout = 0;
 
        switch (mode & S_IFMT) {
@@ -1686,8 +1687,10 @@ sys_mknod(struct mknod_args *uap)
        int error;
 
        error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0);
-       if (error == 0)
-               error = kern_mknod(&nd, uap->mode, uap->dev);
+       if (error == 0) {
+               error = kern_mknod(&nd, uap->mode,
+                                  umajor(uap->dev), uminor(uap->dev));
+       }
        nlookup_done(&nd);
        return (error);
 }
@@ -3263,7 +3266,7 @@ sys_revoke(struct revoke_args *uap)
                        error = VOP_GETATTR(vp, &vattr);
                if (error == 0 && cred->cr_uid != vattr.va_uid)
                        error = suser_cred(cred, PRISON_ROOT);
-               if (error == 0 && count_udev(vp->v_udev) > 0) {
+               if (error == 0 && count_udev(vp->v_umajor, vp->v_uminor) > 0) {
                        error = 0;
                        vx_lock(vp);
                        VOP_REVOKE(vp, REVOKEALL);
index 3556070..60af419 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)vfs_vnops.c 8.2 (Berkeley) 1/21/94
  * $FreeBSD: src/sys/kern/vfs_vnops.c,v 1.87.2.13 2002/12/29 18:19:53 dillon Exp $
- * $DragonFly: src/sys/kern/vfs_vnops.c,v 1.49 2006/10/27 04:56:31 dillon Exp $
+ * $DragonFly: src/sys/kern/vfs_vnops.c,v 1.50 2007/05/09 00:53:34 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -847,7 +847,7 @@ vn_stat(struct vnode *vp, struct stat *sb, struct ucred *cred)
        sb->st_nlink = vap->va_nlink;
        sb->st_uid = vap->va_uid;
        sb->st_gid = vap->va_gid;
-       sb->st_rdev = vap->va_rdev;
+       sb->st_rdev = makeudev(vap->va_rmajor, vap->va_rminor);
        sb->st_size = vap->va_size;
        sb->st_atimespec = vap->va_atime;
        sb->st_mtimespec = vap->va_mtime;
@@ -889,8 +889,10 @@ vn_stat(struct vnode *vp, struct stat *sb, struct ucred *cred)
                 */
                cdev_t dev;
 
-               if ((dev = vp->v_rdev) == NULL)
-                       dev = udev2dev(vp->v_udev, vp->v_type == VBLK);
+               if ((dev = vp->v_rdev) == NULL) {
+                       if (vp->v_type == VCHR)
+                               dev = get_dev(vp->v_umajor, vp->v_uminor);
+               }
                sb->st_blksize = dev->si_bsize_best;
                if (sb->st_blksize < dev->si_bsize_phys)
                        sb->st_blksize = dev->si_bsize_phys;
index 35e463e..666994f 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)conf.h      8.5 (Berkeley) 1/9/95
  * $FreeBSD: src/sys/sys/conf.h,v 1.103.2.6 2002/03/11 01:14:55 dd Exp $
- * $DragonFly: src/sys/sys/conf.h,v 1.17 2007/05/08 02:31:43 dillon Exp $
+ * $DragonFly: src/sys/sys/conf.h,v 1.18 2007/05/09 00:53:35 dillon Exp $
  */
 
 #ifndef _SYS_CONF_H_
@@ -67,7 +67,8 @@ struct dev_ops;
 
 struct cdev {
        u_int           si_flags;
-       udev_t          si_udev;
+       int             si_uminor;
+       int             si_umajor;
        LIST_ENTRY(cdev)        si_hash;
        SLIST_HEAD(, vnode) si_hlist;
        char            si_name[SPECNAMELEN + 1];
@@ -175,8 +176,6 @@ struct swdevt {
 
 #ifdef _KERNEL
 
-#define NUMCDEVSW 256
-
 l_ioctl_t      l_nullioctl;
 l_read_t       l_noread;
 l_write_t      l_nowrite;
@@ -198,9 +197,10 @@ static moduledata_t name##_mod = {                                 \
 DECLARE_MODULE(name, name##_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE)
 
 int    count_dev (cdev_t dev);
-int    count_udev (udev_t dev);
+int    count_udev (int x, int y);
 void   destroy_dev (cdev_t dev);
 void   release_dev (cdev_t dev);
+cdev_t get_dev (int x, int y);
 cdev_t reference_dev (cdev_t dev);
 struct dev_ops *devsw (cdev_t dev);
 const char *devtoname (cdev_t dev);
index 3c3b7e7..1a426e7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003,2004 The DragonFly Project.  All rights reserved.
+ * Copyright (c) 2003,2004,2007 The DragonFly Project.  All rights reserved.
  * 
  * This code is derived from software contributed to The DragonFly Project
  * by Matthew Dillon <dillon@backplane.com>
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * 
- * $DragonFly: src/sys/sys/device.h,v 1.8 2007/04/26 02:11:00 dillon Exp $
+ * $DragonFly: src/sys/sys/device.h,v 1.9 2007/05/09 00:53:35 dillon Exp $
  */
 
 #ifndef _SYS_DEVICE_H_
@@ -40,6 +40,9 @@
 #ifndef _SYS_TYPES_H_
 #include <sys/types.h>
 #endif
+#ifndef _SYS_TREE_H_
+#include <sys/tree.h>
+#endif
 #ifndef _SYS_SYSLINK_RPC_H_
 #include <sys/syslink_rpc.h>
 #endif
@@ -259,6 +262,15 @@ struct dev_ops_link {
        struct dev_ops  *ops;
 };
 
+struct dev_ops_maj {
+       RB_ENTRY(dev_ops_maj) rbnode; /* red-black tree of major nums */
+       struct dev_ops_link *link;
+       int             maj;
+};
+
+RB_HEAD(dev_ops_rb_tree, dev_ops_maj);
+RB_PROTOTYPE2(dev_ops_rb_tree, dev_ops_maj, rbnode, rb_dev_ops_compare, int);
+
 #ifdef _KERNEL
 
 extern struct dev_ops dead_dev_ops;
@@ -318,6 +330,7 @@ extern struct syslink_desc dev_kqfilter_desc;
 extern struct syslink_desc dev_clone_desc;
 
 void compile_dev_ops(struct dev_ops *);
+int dev_ops_scan(int (*callback)(struct dev_ops *, void *), void *arg);
 int dev_ops_add(struct dev_ops *, u_int mask, u_int match);
 int dev_ops_remove(struct dev_ops *, u_int mask, u_int match);
 void dev_ops_release(struct dev_ops *);
index 147e162..150c4a4 100644 (file)
@@ -31,7 +31,7 @@
  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/sys/journal.h,v 1.12 2006/05/20 02:42:13 dillon Exp $
+ * $DragonFly: src/sys/sys/journal.h,v 1.13 2007/05/09 00:53:35 dillon Exp $
  */
 
 #ifndef _SYS_JOURNAL_H_
@@ -310,6 +310,8 @@ struct journal_subrecord {
 #define JLEAF_FILEREV          0x041C
 #define JLEAF_VTYPE            0x041D
 #define JLEAF_ERROR            0x041E
+#define JLEAF_UMAJOR           0x041F
+#define JLEAF_UMINOR           0x0420
 
 /*
  * Low level journal data file structures
index 85d6219..04c8a42 100644 (file)
@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/sys/kern_syscall.h,v 1.35 2007/03/12 21:07:42 corecode Exp $
+ * $DragonFly: src/sys/sys/kern_syscall.h,v 1.36 2007/05/09 00:53:35 dillon Exp $
  */
 
 #ifndef _SYS_KERN_SYSCALL_H_
@@ -145,7 +145,7 @@ int kern_mountctl(const char *path, int op, struct file *fp,
                 void *buf, int buflen, int *res);
 int kern_mkdir(struct nlookupdata *nd, int mode);
 int kern_mkfifo(struct nlookupdata *nd, int mode);
-int kern_mknod(struct nlookupdata *nd, int mode, int dev);
+int kern_mknod(struct nlookupdata *nd, int mode, int rmajor, int rminor);
 int kern_open(struct nlookupdata *nd, int flags, int mode, int *res);
 int kern_close(int fd);
 int kern_closefrom(int fd);
index 462bb37..eb9afe0 100644 (file)
@@ -63,7 +63,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $DragonFly: src/sys/sys/vfscache.h,v 1.7 2006/05/20 02:42:13 dillon Exp $
+ * $DragonFly: src/sys/sys/vfscache.h,v 1.8 2007/05/09 00:53:35 dillon Exp $
  */
 /*
  * This module serves as a focal point for virtually all filesystem and
@@ -130,7 +130,8 @@ struct vattr {
        struct timespec va_ctime;       /* time file changed */
        u_long          va_gen;         /* generation number of file */
        u_long          va_flags;       /* flags defined for file */
-       udev_t          va_rdev;        /* device the special file represents */
+       int             va_rmajor;      /* device the special file represents */
+       int             va_rminor;
        u_quad_t        va_bytes;       /* bytes of disk space held by file */
        u_quad_t        va_filerev;     /* file modification number */
        u_int           va_vaflags;     /* operations flags, see below */
index 7c81647..c7029d4 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)vnode.h     8.7 (Berkeley) 2/4/94
  * $FreeBSD: src/sys/sys/vnode.h,v 1.111.2.19 2002/12/29 18:19:53 dillon Exp $
- * $DragonFly: src/sys/sys/vnode.h,v 1.74 2007/05/06 19:23:33 dillon Exp $
+ * $DragonFly: src/sys/sys/vnode.h,v 1.75 2007/05/09 00:53:35 dillon Exp $
  */
 
 #ifndef _SYS_VNODE_H_
@@ -209,7 +209,8 @@ struct vnode {
        union {
                struct socket   *vu_socket;     /* unix ipc (VSOCK) */
                struct {
-                       udev_t  vu_udev;        /* device number for attach */
+                       int     vu_umajor;      /* device number for attach */
+                       int     vu_uminor;
                        struct cdev     *vu_cdevinfo; /* device (VCHR, VBLK) */
                        SLIST_ENTRY(vnode) vu_cdevnext;
                } vu_cdev;
@@ -242,7 +243,8 @@ struct vnode {
        void    *v_xaddr;
 };
 #define        v_socket        v_un.vu_socket
-#define v_udev         v_un.vu_cdev.vu_udev
+#define v_umajor       v_un.vu_cdev.vu_umajor
+#define v_uminor       v_un.vu_cdev.vu_uminor
 #define        v_rdev          v_un.vu_cdev.vu_cdevinfo
 #define        v_cdevnext      v_un.vu_cdev.vu_cdevnext
 #define        v_fifoinfo      v_un.vu_fifoinfo
@@ -444,7 +446,7 @@ struct uio;
 struct vattr;
 struct vnode;
 
-void   addaliasu (struct vnode *vp, udev_t nvp_udev);
+void   addaliasu (struct vnode *vp, int x, int y);
 int    v_associate_rdev(struct vnode *vp, cdev_t dev);
 void   v_release_rdev(struct vnode *vp);
 int    bdevvp (cdev_t dev, struct vnode **vpp);
index 7f28daf..44dceb1 100644 (file)
@@ -36,7 +36,7 @@
  *     @(#)fdesc_vnops.c       8.9 (Berkeley) 1/21/94
  *
  * $FreeBSD: src/sys/miscfs/fdesc/fdesc_vnops.c,v 1.47.2.1 2001/10/22 22:49:26 chris Exp $
- * $DragonFly: src/sys/vfs/fdesc/fdesc_vnops.c,v 1.36 2006/12/23 00:41:29 swildner Exp $
+ * $DragonFly: src/sys/vfs/fdesc/fdesc_vnops.c,v 1.37 2007/05/09 00:53:35 dillon Exp $
  */
 
 /*
@@ -297,7 +297,8 @@ fdesc_getattr(struct vop_getattr_args *ap)
                vap->va_ctime = vap->va_mtime;
                vap->va_gen = 0;
                vap->va_flags = 0;
-               vap->va_rdev = 0;
+               vap->va_rmajor = VNOVAL;
+               vap->va_rminor = VNOVAL;
                vap->va_bytes = 0;
                break;
 
@@ -326,7 +327,8 @@ fdesc_getattr(struct vop_getattr_args *ap)
                        vap->va_fileid = VTOFDESC(vp)->fd_ix;
                        vap->va_size = stb.st_size;
                        vap->va_blocksize = stb.st_blksize;
-                       vap->va_rdev = stb.st_rdev;
+                       vap->va_rmajor = umajor(stb.st_rdev);
+                       vap->va_rminor = uminor(stb.st_rdev);
 
                        /*
                         * If no time data is provided, use the current time.
index 63ccf7f..8156d11 100644 (file)
@@ -38,7 +38,7 @@
  *
  *     @(#)ffs_vfsops.c        8.8 (Berkeley) 4/18/94
  *     $FreeBSD: src/sys/gnu/ext2fs/ext2_vfsops.c,v 1.63.2.7 2002/07/01 00:18:51 iedowse Exp $
- *     $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_vfsops.c,v 1.52 2006/12/23 00:41:29 swildner Exp $
+ *     $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_vfsops.c,v 1.53 2007/05/09 00:53:35 dillon Exp $
  */
 
 #include "opt_quota.h"
@@ -711,7 +711,7 @@ ext2_mountfs(struct vnode *devvp, struct mount *mp, struct ucred *cred)
         */
        if ((error = vfs_mountedon(devvp)) != 0)
                return (error);
-       if (count_udev(devvp->v_udev) > 0)
+       if (count_udev(devvp->v_umajor, devvp->v_uminor) > 0)
                return (EBUSY);
        if ((error = vinvalbuf(devvp, V_SAVE, 0, 0)) != 0)
                return (error);
index 6c13dc0..857b5df 100644 (file)
@@ -44,7 +44,7 @@
  *     @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95
  *     @(#)ext2_vnops.c        8.7 (Berkeley) 2/3/94
  * $FreeBSD: src/sys/gnu/ext2fs/ext2_vnops.c,v 1.51.2.2 2003/01/02 17:26:18 bde Exp $
- * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_vnops.c,v 1.38 2007/05/06 19:23:33 dillon Exp $
+ * $DragonFly: src/sys/vfs/gnu/ext2fs/ext2_vnops.c,v 1.39 2007/05/09 00:53:35 dillon Exp $
  */
 
 #include "opt_quota.h"
@@ -286,18 +286,23 @@ ext2_mknod(struct vop_old_mknod_args *ap)
        ino_t ino;
        int error;
 
+       if (vap->va_rmajor != VNOVAL &&
+           makeudev(vap->va_rmajor, vap->va_rminor) == NOUDEV) {
+               return (EINVAL);
+       }
+
        error = ext2_makeinode(MAKEIMODE(vap->va_type, vap->va_mode),
            ap->a_dvp, vpp, ap->a_cnp);
        if (error)
                return (error);
        ip = VTOI(*vpp);
        ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
-       if (vap->va_rdev != VNOVAL) {
+       if (vap->va_rmajor != VNOVAL) {
                /*
                 * Want to be able to use this to make badblock
                 * inodes, so don't truncate the dev number.
                 */
-               ip->i_rdev = vap->va_rdev;
+               ip->i_rdev = makeudev(vap->va_rmajor, vap->va_rminor);
        }
        /*
         * Remove inode, then reload it through VFS_VGET so it is
@@ -1441,7 +1446,8 @@ ext2_getattr(struct vop_getattr_args *ap)
            ip->i_effnlink : ip->i_nlink;
        vap->va_uid = ip->i_uid;
        vap->va_gid = ip->i_gid;
-       vap->va_rdev = ip->i_rdev;
+       vap->va_rmajor = umajor(ip->i_rdev);
+       vap->va_rminor = uminor(ip->i_rdev);
        vap->va_size = ip->i_din.di_size;
        vap->va_atime.tv_sec = ip->i_atime;
        vap->va_atime.tv_nsec = ip->i_atimensec;
@@ -1478,7 +1484,7 @@ ext2_setattr(struct vop_setattr_args *ap)
         */
        if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
            (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
-           (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
+           (vap->va_blocksize != VNOVAL) || (vap->va_rmajor != VNOVAL) ||
            ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) {
                return (EINVAL);
        }
@@ -2040,7 +2046,7 @@ ext2_vinit(struct mount *mntp, struct vnode **vpp)
        case VCHR:
        case VBLK:
                vp->v_ops = &mntp->mnt_vn_spec_ops;
-               addaliasu(vp, ip->i_rdev);
+               addaliasu(vp, umajor(ip->i_rdev), uminor(ip->i_rdev));
                break;
        case VFIFO:
                vp->v_ops = &mntp->mnt_vn_fifo_ops;
index 3ae3803..0f60f87 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/fs/hpfs/hpfs_vfsops.c,v 1.3.2.2 2001/12/25 01:44:45 dillon Exp $
- * $DragonFly: src/sys/vfs/hpfs/hpfs_vfsops.c,v 1.40 2006/12/23 00:41:29 swildner Exp $
+ * $DragonFly: src/sys/vfs/hpfs/hpfs_vfsops.c,v 1.41 2007/05/09 00:53:35 dillon Exp $
  */
 
 
@@ -238,7 +238,7 @@ hpfs_mountfs(struct vnode *devvp, struct mount *mp, struct hpfs_args *argsp)
        error = vfs_mountedon(devvp);
        if (error)
                return (error);
-       ncount = count_udev(devvp->v_udev);
+       ncount = count_udev(devvp->v_umajor, devvp->v_uminor);
        if (devvp->v_object)
                ncount -= 1;
        if (ncount > 0)
index e78fe25..316ad6f 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/fs/hpfs/hpfs_vnops.c,v 1.2.2.2 2002/01/15 18:35:09 semenu Exp $
- * $DragonFly: src/sys/vfs/hpfs/hpfs_vnops.c,v 1.40 2007/05/06 19:23:34 dillon Exp $
+ * $DragonFly: src/sys/vfs/hpfs/hpfs_vnops.c,v 1.41 2007/05/09 00:53:35 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -460,7 +460,8 @@ hpfs_getattr(struct vop_getattr_args *ap)
        vap->va_nlink = 1;
        vap->va_uid = hp->h_uid;
        vap->va_gid = hp->h_gid;
-       vap->va_rdev = 0;                               /* XXX UNODEV ? */
+       vap->va_rmajor = VNOVAL;
+       vap->va_rminor = VNOVAL;
        vap->va_size = hp->h_fn.fn_size;
        vap->va_bytes = ((hp->h_fn.fn_size + DEV_BSIZE-1) & ~(DEV_BSIZE-1)) +
                        DEV_BSIZE;
@@ -505,7 +506,7 @@ hpfs_setattr(struct vop_setattr_args *ap)
         */
        if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
            (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
-           (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
+           (vap->va_blocksize != VNOVAL) || (vap->va_rmajor != VNOVAL) ||
            (vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) {
                dprintf(("hpfs_setattr: changing nonsettable attr\n"));
                return (EINVAL);
index 39de059..69c0fb6 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)cd9660_vfsops.c     8.18 (Berkeley) 5/22/95
  * $FreeBSD: src/sys/isofs/cd9660/cd9660_vfsops.c,v 1.74.2.7 2002/04/08 09:39:29 bde Exp $
- * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_vfsops.c,v 1.43 2006/12/23 00:41:29 swildner Exp $
+ * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_vfsops.c,v 1.44 2007/05/09 00:53:35 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -290,7 +290,7 @@ iso_mountfs(struct vnode *devvp, struct mount *mp, struct iso_args *argp)
         */
        if ((error = vfs_mountedon(devvp)))
                return error;
-       if (count_udev(devvp->v_udev) > 0)
+       if (count_udev(devvp->v_umajor, devvp->v_uminor) > 0)
                return EBUSY;
        if ((error = vinvalbuf(devvp, V_SAVE, 0, 0)))
                return (error);
@@ -842,7 +842,8 @@ again:
        case VCHR:
        case VBLK:
                vp->v_ops = &mp->mnt_vn_spec_ops;
-               addaliasu(vp, ip->inode.iso_rdev);
+               addaliasu(vp, umajor(ip->inode.iso_rdev),
+                         uminor(ip->inode.iso_rdev));
                break;
        case VREG:
        case VDIR:
index 33323cd..f5ec0ee 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)cd9660_vnops.c      8.19 (Berkeley) 5/27/95
  * $FreeBSD: src/sys/isofs/cd9660/cd9660_vnops.c,v 1.62 1999/12/15 23:01:51 eivind Exp $
- * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_vnops.c,v 1.33 2006/12/23 00:41:29 swildner Exp $
+ * $DragonFly: src/sys/vfs/isofs/cd9660/cd9660_vnops.c,v 1.34 2007/05/09 00:53:35 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -214,7 +214,8 @@ cd9660_getattr(struct vop_getattr_args *ap)
        vap->va_atime   = ip->inode.iso_atime;
        vap->va_mtime   = ip->inode.iso_mtime;
        vap->va_ctime   = ip->inode.iso_ctime;
-       vap->va_rdev    = ip->inode.iso_rdev;
+       vap->va_rmajor  = umajor(ip->inode.iso_rdev);
+       vap->va_rminor  = uminor(ip->inode.iso_rdev);
 
        vap->va_size    = (u_quad_t)(unsigned long)ip->i_size;
        if (ip->i_size == 0 && (vap->va_mode & S_IFMT) == S_IFLNK) {
index d284159..bbed099 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)mfs_vfsops.c        8.11 (Berkeley) 6/19/95
  * $FreeBSD: src/sys/ufs/mfs/mfs_vfsops.c,v 1.81.2.3 2001/07/04 17:35:21 tegge Exp $
- * $DragonFly: src/sys/vfs/mfs/mfs_vfsops.c,v 1.39 2007/05/06 19:23:34 dillon Exp $
+ * $DragonFly: src/sys/vfs/mfs/mfs_vfsops.c,v 1.40 2007/05/09 00:53:35 dillon Exp $
  */
 
 
@@ -85,10 +85,8 @@ d_open_t     mfsopen;
 d_close_t      mfsclose;
 d_strategy_t   mfsstrategy;
 
-#define MFS_CDEV_MAJOR 253
-
 static struct dev_ops mfs_ops = {
-       { "MFS", MFS_CDEV_MAJOR, D_DISK },
+       { "MFS", -1, D_DISK },
        .d_open =       mfsopen,
        .d_close =      mfsclose,
        .d_read =       physread,
@@ -323,7 +321,7 @@ mfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
        dev->si_bsize_phys = DEV_BSIZE;
        dev->si_iosize_max = DFLTPHYS;
        dev->si_drv1 = mfsp;
-       addaliasu(devvp, makeudev(MFS_CDEV_MAJOR, minnum));
+       addaliasu(devvp, mfs_ops.head.maj, minnum);
        devvp->v_data = mfsp;
        mfsp->mfs_baseoff = args.base;
        mfsp->mfs_size = args.size;
index d0e356f..564fc39 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)mfs_vnops.c 8.11 (Berkeley) 5/22/95
  * $FreeBSD: src/sys/ufs/mfs/mfs_vnops.c,v 1.47.2.1 2001/05/22 02:06:43 bp Exp $
- * $DragonFly: src/sys/vfs/mfs/mfs_vnops.c,v 1.34 2007/05/06 19:23:34 dillon Exp $
+ * $DragonFly: src/sys/vfs/mfs/mfs_vnops.c,v 1.35 2007/05/09 00:53:35 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -114,7 +114,7 @@ mfs_open(struct vop_open_args *ap)
 
        if (vp->v_type != VCHR)
                panic("mfs_open not VCHR");
-       v_associate_rdev(vp, udev2dev(vp->v_udev, 0));
+       v_associate_rdev(vp, get_dev(vp->v_umajor, vp->v_uminor));
        return (vop_stdopen(ap));
 }
 
index 3090a19..4f38b9e 100644 (file)
@@ -1,5 +1,5 @@
 /* $FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/msdosfs/Attic/msdosfs_vfsops.c,v 1.60.2.8 2004/03/02 09:43:04 tjr Exp $ */
-/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_vfsops.c,v 1.44 2007/05/06 19:23:34 dillon Exp $ */
+/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_vfsops.c,v 1.45 2007/05/09 00:53:35 dillon Exp $ */
 /*     $NetBSD: msdosfs_vfsops.c,v 1.51 1997/11/17 15:36:58 ws Exp $   */
 
 /*-
@@ -318,7 +318,7 @@ mountmsdosfs(struct vnode *devvp, struct mount *mp, struct msdosfs_args *argp)
        error = vfs_mountedon(devvp);
        if (error)
                return (error);
-       if (count_udev(devvp->v_udev) > 0)
+       if (count_udev(devvp->v_umajor, devvp->v_uminor) > 0)
                return (EBUSY);
        vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
        error = vinvalbuf(devvp, V_SAVE, 0, 0);
index 86240e1..5ecd547 100644 (file)
@@ -1,5 +1,5 @@
 /* $FreeBSD: src/sys/msdosfs/msdosfs_vnops.c,v 1.95.2.4 2003/06/13 15:05:47 trhodes Exp $ */
-/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_vnops.c,v 1.46 2007/05/06 19:23:34 dillon Exp $ */
+/* $DragonFly: src/sys/vfs/msdosfs/msdosfs_vnops.c,v 1.47 2007/05/09 00:53:35 dillon Exp $ */
 /*     $NetBSD: msdosfs_vnops.c,v 1.68 1998/02/10 14:10:04 mrg Exp $   */
 
 /*-
@@ -355,7 +355,8 @@ msdosfs_getattr(struct vop_getattr_args *ap)
        vap->va_uid = pmp->pm_uid;
        vap->va_gid = pmp->pm_gid;
        vap->va_nlink = 1;
-       vap->va_rdev = 0;
+       vap->va_rmajor = VNOVAL;
+       vap->va_rminor = VNOVAL;
        vap->va_size = dep->de_FileSize;
        dos2unixtime(dep->de_MDate, dep->de_MTime, 0, &vap->va_mtime);
        if (pmp->pm_flags & MSDOSFSMNT_LONGNAME) {
@@ -401,14 +402,14 @@ msdosfs_setattr(struct vop_setattr_args *ap)
         */
        if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
            (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
-           (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
+           (vap->va_blocksize != VNOVAL) || (vap->va_rmajor != VNOVAL) ||
            (vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) {
 #ifdef MSDOSFS_DEBUG
                kprintf("msdosfs_setattr(): returning EINVAL\n");
                kprintf("    va_type %d, va_nlink %x, va_fsid %lx, va_fileid %lx\n",
                    vap->va_type, vap->va_nlink, vap->va_fsid, vap->va_fileid);
-               kprintf("    va_blocksize %lx, va_rdev %x, va_bytes %qx, va_gen %lx\n",
-                   vap->va_blocksize, vap->va_rdev, vap->va_bytes, vap->va_gen);
+               kprintf("    va_blocksize %lx, va_rmajor %x, va_bytes %qx, va_gen %lx\n",
+                   vap->va_blocksize, vap->va_rmajor, vap->va_bytes, vap->va_gen);
                kprintf("    va_uid %x, va_gid %x\n",
                    vap->va_uid, vap->va_gid);
 #endif
index 4a00c1d..5eba756 100644 (file)
@@ -35,7 +35,7 @@
  *
  *     @(#)nfs_serv.c  8.8 (Berkeley) 7/31/95
  * $FreeBSD: src/sys/nfs/nfs_serv.c,v 1.93.2.6 2002/12/29 18:19:53 dillon Exp $
- * $DragonFly: src/sys/vfs/nfs/nfs_serv.c,v 1.42 2006/12/23 00:41:29 swildner Exp $
+ * $DragonFly: src/sys/vfs/nfs/nfs_serv.c,v 1.43 2007/05/09 00:53:35 dillon Exp $
  */
 
 /*
@@ -1540,7 +1540,8 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        struct nlookupdata nd;
        int32_t t1;
        caddr_t bpos;
-       int error = 0, rdev, len, tsize, dirfor_ret = 1, diraft_ret = 1;
+       int error = 0, len, tsize, dirfor_ret = 1, diraft_ret = 1;
+       udev_t rdev = NOUDEV;
        int v3 = (nfsd->nd_flag & ND_NFSV3), how, exclusive_flag = 0;
        caddr_t cp;
        char *cp2;
@@ -1554,9 +1555,6 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        u_char cverf[NFSX_V3CREATEVERF];
 
        nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
-#ifndef nolint
-       rdev = 0;
-#endif
        nlookup_zero(&nd);
        dirp = NULL;
        dvp = NULL;
@@ -1688,7 +1686,8 @@ nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
                             (error = suser_cred(cred, 0))) {
                                goto nfsmreply0;
                         }
-                       vap->va_rdev = rdev;
+                       vap->va_rmajor = umajor(rdev);
+                       vap->va_rminor = uminor(rdev);
 
                        vput(dvp);
                        dvp = NULL;
@@ -1864,9 +1863,8 @@ nfsrv_mknod(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
        nfsm_srvsattr(vap);
        if (vtyp == VCHR || vtyp == VBLK) {
                nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
-               major = fxdr_unsigned(u_int32_t, *tl++);
-               minor = fxdr_unsigned(u_int32_t, *tl);
-               vap->va_rdev = makeudev(major, minor);
+               vap->va_rmajor = fxdr_unsigned(u_int32_t, *tl++);
+               vap->va_rminor = fxdr_unsigned(u_int32_t, *tl);
        }
 
        /*
index 02b16da..7fc3dd8 100644 (file)
@@ -35,7 +35,7 @@
  *
  *     @(#)nfs_subs.c  8.8 (Berkeley) 5/22/95
  * $FreeBSD: /repoman/r/ncvs/src/sys/nfsclient/nfs_subs.c,v 1.128 2004/04/14 23:23:55 peadar Exp $
- * $DragonFly: src/sys/vfs/nfs/nfs_subs.c,v 1.45 2006/12/23 00:41:29 swildner Exp $
+ * $DragonFly: src/sys/vfs/nfs/nfs_subs.c,v 1.46 2007/05/09 00:53:35 dillon Exp $
  */
 
 /*
@@ -1124,6 +1124,7 @@ nfs_loadattrcache(struct vnode **vpp, struct mbuf **mdp, caddr_t *dposp,
        int32_t t1;
        caddr_t cp2;
        int error = 0;
+       int rmajor, rminor;
        udev_t rdev;
        struct mbuf *md;
        enum vtype vtyp;
@@ -1139,8 +1140,8 @@ nfs_loadattrcache(struct vnode **vpp, struct mbuf **mdp, caddr_t *dposp,
        if (v3) {
                vtyp = nfsv3tov_type(fp->fa_type);
                vmode = fxdr_unsigned(u_short, fp->fa_mode);
-               rdev = makeudev(fxdr_unsigned(int, fp->fa3_rdev.specdata1),
-                       fxdr_unsigned(int, fp->fa3_rdev.specdata2));
+               rmajor = (int)fxdr_unsigned(int, fp->fa3_rdev.specdata1);
+               rminor = (int)fxdr_unsigned(int, fp->fa3_rdev.specdata2);
                fxdr_nfsv3time(&fp->fa3_mtime, &mtime);
        } else {
                vtyp = nfsv2tov_type(fp->fa_type);
@@ -1167,6 +1168,8 @@ nfs_loadattrcache(struct vnode **vpp, struct mbuf **mdp, caddr_t *dposp,
                if (vtyp == VNON || (vtyp == VREG && (vmode & S_IFMT) != 0))
                        vtyp = IFTOVT(vmode);
                rdev = fxdr_unsigned(int32_t, fp->fa2_rdev);
+               rmajor = umajor(rdev);
+               rminor = uminor(rdev);
                fxdr_nfsv2time(&fp->fa2_mtime, &mtime);
 
                /*
@@ -1190,7 +1193,7 @@ nfs_loadattrcache(struct vnode **vpp, struct mbuf **mdp, caddr_t *dposp,
                        vp->v_ops = &vp->v_mount->mnt_vn_fifo_ops;
                } else if (vp->v_type == VCHR || vp->v_type == VBLK) {
                        vp->v_ops = &vp->v_mount->mnt_vn_spec_ops;
-                       addaliasu(vp, rdev);
+                       addaliasu(vp, rmajor, rminor);
                } else {
                        vp->v_ops = &vp->v_mount->mnt_vn_use_ops;
                }
@@ -1217,7 +1220,8 @@ nfs_loadattrcache(struct vnode **vpp, struct mbuf **mdp, caddr_t *dposp,
        vap = &np->n_vattr;
        vap->va_type = vtyp;
        vap->va_mode = (vmode & 07777);
-       vap->va_rdev = rdev;
+       vap->va_rmajor = rmajor;
+       vap->va_rminor = rminor;
        vap->va_mtime = mtime;
        vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
        if (v3) {
@@ -1763,8 +1767,8 @@ nfsm_srvfattr(struct nfsrv_descript *nfsd, struct vattr *vap,
                fp->fa_mode = vtonfsv3_mode(vap->va_mode);
                txdr_hyper(vap->va_size, &fp->fa3_size);
                txdr_hyper(vap->va_bytes, &fp->fa3_used);
-               fp->fa3_rdev.specdata1 = txdr_unsigned(umajor(vap->va_rdev));
-               fp->fa3_rdev.specdata2 = txdr_unsigned(uminor(vap->va_rdev));
+               fp->fa3_rdev.specdata1 = txdr_unsigned(vap->va_rmajor);
+               fp->fa3_rdev.specdata2 = txdr_unsigned(vap->va_rminor);
                fp->fa3_fsid.nfsuquad[0] = 0;
                fp->fa3_fsid.nfsuquad[1] = txdr_unsigned(vap->va_fsid);
                fp->fa3_fileid.nfsuquad[0] = 0;
@@ -1780,7 +1784,7 @@ nfsm_srvfattr(struct nfsrv_descript *nfsd, struct vattr *vap,
                if (vap->va_type == VFIFO)
                        fp->fa2_rdev = 0xffffffff;
                else
-                       fp->fa2_rdev = txdr_unsigned(vap->va_rdev);
+                       fp->fa2_rdev = txdr_unsigned(makeudev(vap->va_rmajor, vap->va_rminor));
                fp->fa2_blocks = txdr_unsigned(vap->va_bytes / NFS_FABLKSIZE);
                fp->fa2_fsid = txdr_unsigned(vap->va_fsid);
                fp->fa2_fileid = txdr_unsigned(vap->va_fileid);
index 726fa3e..9fb149f 100644 (file)
@@ -35,7 +35,7 @@
  *
  *     @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95
  * $FreeBSD: src/sys/nfs/nfs_vnops.c,v 1.150.2.5 2001/12/20 19:56:28 dillon Exp $
- * $DragonFly: src/sys/vfs/nfs/nfs_vnops.c,v 1.70 2007/05/06 19:23:34 dillon Exp $
+ * $DragonFly: src/sys/vfs/nfs/nfs_vnops.c,v 1.71 2007/05/09 00:53:35 dillon Exp $
  */
 
 
@@ -1363,14 +1363,16 @@ nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp,
        caddr_t bpos, dpos;
        int error = 0, wccflag = NFSV3_WCCRATTR, gotvp = 0;
        struct mbuf *mreq, *mrep, *md, *mb, *mb2;
-       u_int32_t rdev;
+       int rmajor, rminor;
        int v3 = NFS_ISV3(dvp);
 
-       if (vap->va_type == VCHR || vap->va_type == VBLK)
-               rdev = txdr_unsigned(vap->va_rdev);
-       else if (vap->va_type == VFIFO || vap->va_type == VSOCK)
-               rdev = nfs_xdrneg1;
-       else {
+       if (vap->va_type == VCHR || vap->va_type == VBLK) {
+               rmajor = txdr_unsigned(vap->va_rmajor);
+               rminor = txdr_unsigned(vap->va_rminor);
+       } else if (vap->va_type == VFIFO || vap->va_type == VSOCK) {
+               rmajor = nfs_xdrneg1;
+               rminor = nfs_xdrneg1;
+       } else {
                return (EOPNOTSUPP);
        }
        if ((error = VOP_GETATTR(dvp, &vattr)) != 0) {
@@ -1387,15 +1389,15 @@ nfs_mknodrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp,
                nfsm_v3attrbuild(vap, FALSE);
                if (vap->va_type == VCHR || vap->va_type == VBLK) {
                        nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
-                       *tl++ = txdr_unsigned(umajor(vap->va_rdev));
-                       *tl = txdr_unsigned(uminor(vap->va_rdev));
+                       *tl++ = txdr_unsigned(vap->va_rmajor);
+                       *tl = txdr_unsigned(vap->va_rminor);
                }
        } else {
                nfsm_build(sp, struct nfsv2_sattr *, NFSX_V2SATTR);
                sp->sa_mode = vtonfsv2_mode(vap->va_type, vap->va_mode);
                sp->sa_uid = nfs_xdrneg1;
                sp->sa_gid = nfs_xdrneg1;
-               sp->sa_size = rdev;
+               sp->sa_size = makeudev(rmajor, rminor);
                txdr_nfsv2time(&vap->va_atime, &sp->sa_atime);
                txdr_nfsv2time(&vap->va_mtime, &sp->sa_mtime);
        }
index 574dd79..e1630eb 100644 (file)
@@ -26,7 +26,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/ntfs/ntfs_vfsops.c,v 1.20.2.5 2001/12/25 01:44:45 dillon Exp $
- * $DragonFly: src/sys/vfs/ntfs/ntfs_vfsops.c,v 1.45 2007/05/06 19:23:34 dillon Exp $
+ * $DragonFly: src/sys/vfs/ntfs/ntfs_vfsops.c,v 1.46 2007/05/09 00:53:35 dillon Exp $
  */
 
 
@@ -310,7 +310,7 @@ ntfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
                error = ENOTBLK;
                goto error_2;
        }
-       if (umajor(devvp->v_udev) >= nblkdev) {
+       if (devvp->v_umajor >= nblkdev) {
                error = ENXIO;
                goto error_2;
        }
@@ -406,7 +406,7 @@ ntfs_mountfs(struct vnode *devvp, struct mount *mp, struct ntfs_args *argsp,
        error = vfs_mountedon(devvp);
        if (error)
                return (error);
-       ncount = count_udev(devvp->v_udev);
+       ncount = count_udev(devvp->v_umajor, devvp->v_uminor);
 #if defined(__DragonFly__)
        if (devvp->v_object)
                ncount -= 1;
index 43fda75..7596f46 100644 (file)
@@ -36,7 +36,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/ntfs/ntfs_vnops.c,v 1.9.2.4 2002/08/06 19:35:18 semenu Exp $
- * $DragonFly: src/sys/vfs/ntfs/ntfs_vnops.c,v 1.39 2007/05/06 19:23:34 dillon Exp $
+ * $DragonFly: src/sys/vfs/ntfs/ntfs_vnops.c,v 1.40 2007/05/09 00:53:36 dillon Exp $
  *
  */
 
@@ -238,7 +238,8 @@ ntfs_getattr(struct vop_getattr_args *ap)
        vap->va_nlink = ip->i_nlink;
        vap->va_uid = ip->i_mp->ntm_uid;
        vap->va_gid = ip->i_mp->ntm_gid;
-       vap->va_rdev = 0;                               /* XXX UNODEV ? */
+       vap->va_rmajor = VNOVAL;
+       vap->va_rminor = VNOVAL;
        vap->va_size = fp->f_size;
        vap->va_bytes = fp->f_allocated;
        vap->va_atime = ntfs_nttimetounix(fp->f_times.t_access);
index b9ebbc3..1c1d8dd 100644 (file)
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/nwfs/nwfs_node.c,v 1.3.2.8 2001/12/25 01:44:45 dillon Exp $
- * $DragonFly: src/sys/vfs/nwfs/nwfs_node.c,v 1.25 2007/05/06 19:23:35 dillon Exp $
+ * $DragonFly: src/sys/vfs/nwfs/nwfs_node.c,v 1.26 2007/05/09 00:53:36 dillon Exp $
  */
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -314,7 +314,8 @@ nwfs_attr_cacheenter(struct vnode *vp, const struct nw_entry_info *fi)
        va->va_ctime = va->va_mtime;    /* time file changed */
        va->va_gen = VNOVAL;            /* generation number of file */
        va->va_flags = 0;               /* flags defined for file */
-       va->va_rdev = VNOVAL;           /* device the special file represents */
+       va->va_rmajor = VNOVAL;         /* device the special file represents */
+       va->va_rminor = VNOVAL;
        va->va_bytes = va->va_size;     /* bytes of disk space held by file */
        va->va_filerev = 0;             /* file modification number */
        va->va_vaflags = 0;             /* operations flags */
index cdfe4d6..94435c0 100644 (file)
@@ -36,7 +36,7 @@
  *     @(#)portal_vnops.c      8.14 (Berkeley) 5/21/95
  *
  * $FreeBSD: src/sys/miscfs/portal/portal_vnops.c,v 1.38 1999/12/21 06:29:00 chris Exp $
- * $DragonFly: src/sys/vfs/portal/portal_vnops.c,v 1.35 2007/04/22 01:13:17 dillon Exp $
+ * $DragonFly: src/sys/vfs/portal/portal_vnops.c,v 1.36 2007/05/09 00:53:36 dillon Exp $
  */
 
 /*
@@ -455,7 +455,8 @@ portal_getattr(struct vop_getattr_args *ap)
        vap->va_ctime = vap->va_mtime;
        vap->va_gen = 0;
        vap->va_flags = 0;
-       vap->va_rdev = 0;
+       vap->va_rmajor = VNOVAL;
+       vap->va_rminor = VNOVAL;
        /* vap->va_qbytes = 0; */
        vap->va_bytes = 0;
        /* vap->va_qsize = 0; */
index 74ab3c7..705fcd1 100644 (file)
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/fs/smbfs/smbfs_node.c,v 1.2.2.3 2003/01/17 08:20:26 tjr Exp $
- * $DragonFly: src/sys/vfs/smbfs/smbfs_node.c,v 1.23 2007/05/06 19:23:35 dillon Exp $
+ * $DragonFly: src/sys/vfs/smbfs/smbfs_node.c,v 1.24 2007/05/09 00:53:36 dillon Exp $
  */
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -410,7 +410,8 @@ smbfs_attr_cachelookup(struct vnode *vp, struct vattr *va)
        va->va_atime = va->va_ctime = va->va_mtime;     /* time file changed */
        va->va_gen = VNOVAL;            /* generation number of file */
        va->va_flags = 0;               /* flags defined for file */
-       va->va_rdev = VNOVAL;           /* device the special file represents */
+       va->va_rmajor = VNOVAL;         /* device the special file represents */
+       va->va_rminor = VNOVAL;
        va->va_bytes = va->va_size;     /* bytes of disk space held by file */
        va->va_filerev = 0;             /* file modification number */
        va->va_vaflags = 0;             /* operations flags */
index ab38caa..985b3f5 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)spec_vnops.c        8.14 (Berkeley) 5/21/95
  * $FreeBSD: src/sys/miscfs/specfs/spec_vnops.c,v 1.131.2.4 2001/02/26 04:23:20 jlemon Exp $
- * $DragonFly: src/sys/vfs/specfs/spec_vnops.c,v 1.50 2006/12/23 00:41:30 swildner Exp $
+ * $DragonFly: src/sys/vfs/specfs/spec_vnops.c,v 1.51 2007/05/09 00:53:36 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -140,7 +140,6 @@ spec_open(struct vop_open_args *ap)
        struct vnode *vp = ap->a_vp;
        cdev_t dev;
        int error;
-       int isblk = (vp->v_type == VBLK) ? 1 : 0;
        const char *cp;
 
        /*
@@ -148,6 +147,8 @@ spec_open(struct vop_open_args *ap)
         */
        if (vp->v_mount && (vp->v_mount->mnt_flag & MNT_NODEV))
                return (ENXIO);
+       if (vp->v_type == VBLK)
+               return (ENXIO);
 
        /*
         * Resolve the device.  If the vnode is already open v_rdev may
@@ -157,7 +158,7 @@ spec_open(struct vop_open_args *ap)
         * it when replacing the rdev reference.
         */
        if (vp->v_rdev != NULL) {
-               dev = udev2dev(vp->v_udev, isblk);
+               dev = get_dev(vp->v_umajor, vp->v_uminor);
                if (dev != vp->v_rdev) {
                        int oc = vp->v_opencount;
                        kprintf(
@@ -165,7 +166,7 @@ spec_open(struct vop_open_args *ap)
                            vp->v_rdev->si_name);
                        v_release_rdev(vp);
                        error = v_associate_rdev(vp, 
-                                       udev2dev(vp->v_udev, isblk));
+                                       get_dev(vp->v_umajor, vp->v_uminor));
                        if (error) {
                                kprintf(", reacquisition failed\n");
                        } else {
@@ -176,7 +177,7 @@ spec_open(struct vop_open_args *ap)
                        error = 0;
                }
        } else {
-               error = v_associate_rdev(vp, udev2dev(vp->v_udev, isblk));
+               error = v_associate_rdev(vp, get_dev(vp->v_umajor, vp->v_uminor));
        }
        if (error)
                return(error);
index cca4a81..5b37118 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/fs/udf/udf_vfsops.c,v 1.16 2003/11/05 06:56:08 scottl Exp $
- * $DragonFly: src/sys/vfs/udf/udf_vfsops.c,v 1.25 2006/12/23 00:41:30 swildner Exp $
+ * $DragonFly: src/sys/vfs/udf/udf_vfsops.c,v 1.26 2007/05/09 00:53:36 dillon Exp $
  */
 
 /* udf_vfsops.c */
@@ -244,7 +244,7 @@ udf_mountfs(struct vnode *devvp, struct mount *mp)
         */
        if ((error = vfs_mountedon(devvp)))
                return(error);
-       if (count_udev(devvp->v_udev) > 0)
+       if (count_udev(devvp->v_umajor, devvp->v_uminor) > 0)
                return(EBUSY);
        if ((error = vinvalbuf(devvp, V_SAVE, 0, 0)))
                return(error);
index 88285a2..4c8532a 100644 (file)
@@ -24,7 +24,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/fs/udf/udf_vnops.c,v 1.33 2003/12/07 05:04:49 scottl Exp $
- * $DragonFly: src/sys/vfs/udf/udf_vnops.c,v 1.29 2006/12/23 00:41:30 swildner Exp $
+ * $DragonFly: src/sys/vfs/udf/udf_vnops.c,v 1.30 2007/05/09 00:53:36 dillon Exp $
  */
 
 /* udf_vnops.c */
@@ -378,7 +378,8 @@ udf_getattr(struct vop_getattr_args *a)
        udf_timetotimespec(&fentry->atime, &vap->va_atime);
        udf_timetotimespec(&fentry->mtime, &vap->va_mtime);
        vap->va_ctime = vap->va_mtime; /* XXX Stored as an Extended Attribute */
-       vap->va_rdev = 0; /* XXX */
+       vap->va_rmajor = VNOVAL;
+       vap->va_rminor = VNOVAL;
        if (vp->v_type & VDIR) {
                /*
                 * Directories that are recorded within their ICB will show
index 4c2646e..21e9733 100644 (file)
@@ -32,7 +32,7 @@
  *
  *     @(#)ffs_vfsops.c        8.31 (Berkeley) 5/20/95
  * $FreeBSD: src/sys/ufs/ffs/ffs_vfsops.c,v 1.117.2.10 2002/06/23 22:34:52 iedowse Exp $
- * $DragonFly: src/sys/vfs/ufs/ffs_vfsops.c,v 1.53 2007/04/20 22:20:12 dillon Exp $
+ * $DragonFly: src/sys/vfs/ufs/ffs_vfsops.c,v 1.54 2007/05/09 00:53:36 dillon Exp $
  */
 
 #include "opt_quota.h"
@@ -319,13 +319,16 @@ ffs_mount(struct mount *mp,               /* mount struct pointer */
                 * um_devvp, so continue using um_devvp and throw away devvp.
                 */
                if (devvp != ump->um_devvp) {
-                       if (devvp->v_udev == ump->um_devvp->v_udev) {
+                       if (devvp->v_umajor == ump->um_devvp->v_umajor &&
+                           devvp->v_uminor == ump->um_devvp->v_uminor) {
                                vrele(devvp);
                                devvp = ump->um_devvp;
                        } else {
                                kprintf("cannot update mount, udev does"
-                                       " not match %08x vs %08x\n",
-                                       devvp->v_udev, ump->um_devvp->v_udev);
+                                       " not match %08x:%08x vs %08x:%08x\n",
+                                       devvp->v_umajor, devvp->v_uminor,
+                                       ump->um_devvp->v_umajor,
+                                       ump->um_devvp->v_uminor);
                                error = EINVAL; /* needs translation */
                        }
                } else {
@@ -612,7 +615,7 @@ ffs_mountfs(struct vnode *devvp, struct mount *mp, struct malloc_type *mtype)
        error = vfs_mountedon(devvp);
        if (error)
                return (error);
-       if (count_udev(devvp->v_udev) > 0)
+       if (count_udev(devvp->v_umajor, devvp->v_uminor) > 0)
                return (EBUSY);
        vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
        error = vinvalbuf(devvp, V_SAVE, 0, 0);
index d811262..02f854e 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95
  * $FreeBSD: src/sys/ufs/ufs/ufs_vnops.c,v 1.131.2.8 2003/01/02 17:26:19 bde Exp $
- * $DragonFly: src/sys/vfs/ufs/ufs_vnops.c,v 1.59 2007/05/06 19:23:35 dillon Exp $
+ * $DragonFly: src/sys/vfs/ufs/ufs_vnops.c,v 1.60 2007/05/09 00:53:36 dillon Exp $
  */
 
 #include "opt_quota.h"
@@ -220,6 +220,15 @@ ufs_mknod(struct vop_old_mknod_args *ap)
        ino_t ino;
        int error;
 
+       /*
+        * UFS cannot represent the entire major/minor range supported by
+        * the kernel.
+        */
+       if (vap->va_rmajor != VNOVAL &&
+           makeudev(vap->va_rmajor, vap->va_rminor) == NOUDEV) {
+               return(EINVAL);
+       }
+
        error = ufs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode),
            ap->a_dvp, vpp, ap->a_cnp);
        if (error)
@@ -227,12 +236,12 @@ ufs_mknod(struct vop_old_mknod_args *ap)
        VN_KNOTE(ap->a_dvp, NOTE_WRITE);
        ip = VTOI(*vpp);
        ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
-       if (vap->va_rdev != VNOVAL) {
+       if (vap->va_rmajor != VNOVAL) {
                /*
                 * Want to be able to use this to make badblock
                 * inodes, so don't truncate the dev number.
                 */
-               ip->i_rdev = vap->va_rdev;
+               ip->i_rdev = makeudev(vap->va_rmajor, vap->va_rminor);
        }
        /*
         * Remove inode, then reload it through VFS_VGET so it is
@@ -415,7 +424,8 @@ ufs_getattr(struct vop_getattr_args *ap)
            ip->i_effnlink : ip->i_nlink;
        vap->va_uid = ip->i_uid;
        vap->va_gid = ip->i_gid;
-       vap->va_rdev = ip->i_rdev;
+       vap->va_rmajor = umajor(ip->i_rdev);
+       vap->va_rminor = uminor(ip->i_rdev);
        vap->va_size = ip->i_din.di_size;
        vap->va_atime.tv_sec = ip->i_atime;
        vap->va_atime.tv_nsec = ip->i_atimensec;
@@ -454,7 +464,7 @@ ufs_setattr(struct vop_setattr_args *ap)
         */
        if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
            (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
-           (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
+           (vap->va_blocksize != VNOVAL) || (vap->va_rmajor != VNOVAL) ||
            ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) {
                return (EINVAL);
        }
@@ -2100,7 +2110,7 @@ ufs_vinit(struct mount *mntp, struct vnode **vpp)
        case VCHR:
        case VBLK:
                vp->v_ops = &mntp->mnt_vn_spec_ops;
-               addaliasu(vp, ip->i_rdev);
+               addaliasu(vp, umajor(ip->i_rdev), uminor(ip->i_rdev));
                break;
        case VFIFO:
                vp->v_ops = &mntp->mnt_vn_fifo_ops;