From 0e9b91307aa017412ee9a1b19966547e497d643d Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Wed, 9 May 2007 00:53:36 +0000 Subject: [PATCH] Give the device major / minor numbers their own separate 32 bit fields 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). --- sys/dev/disk/ata/atapi-cd.c | 4 +- sys/dev/disk/nata/atapi-cd.c | 4 +- sys/dev/raid/asr/asr.c | 31 +----- sys/dev/raid/vinum/.gdbinit.kernel | 7 +- sys/dev/serial/sio/sio.c | 3 +- sys/emulation/linux/linux_misc.c | 6 +- sys/kern/kern_conf.c | 96 +++++++++++------ sys/kern/kern_device.c | 156 ++++++++++++++++++++------- sys/kern/kern_kinfo.c | 6 +- sys/kern/vfs_conf.c | 76 +++++++++---- sys/kern/vfs_jops.c | 10 +- sys/kern/vfs_journal.c | 10 +- sys/kern/vfs_subr.c | 34 +++--- sys/kern/vfs_syscalls.c | 15 +-- sys/kern/vfs_vnops.c | 10 +- sys/sys/conf.h | 10 +- sys/sys/device.h | 17 ++- sys/sys/journal.h | 4 +- sys/sys/kern_syscall.h | 4 +- sys/sys/vfscache.h | 5 +- sys/sys/vnode.h | 10 +- sys/vfs/fdesc/fdesc_vnops.c | 8 +- sys/vfs/gnu/ext2fs/ext2_vfsops.c | 4 +- sys/vfs/gnu/ext2fs/ext2_vnops.c | 18 ++-- sys/vfs/hpfs/hpfs_vfsops.c | 4 +- sys/vfs/hpfs/hpfs_vnops.c | 7 +- sys/vfs/isofs/cd9660/cd9660_vfsops.c | 7 +- sys/vfs/isofs/cd9660/cd9660_vnops.c | 5 +- sys/vfs/mfs/mfs_vfsops.c | 8 +- sys/vfs/mfs/mfs_vnops.c | 4 +- sys/vfs/msdosfs/msdosfs_vfsops.c | 4 +- sys/vfs/msdosfs/msdosfs_vnops.c | 11 +- sys/vfs/nfs/nfs_serv.c | 16 ++- sys/vfs/nfs/nfs_subs.c | 20 ++-- sys/vfs/nfs/nfs_vnops.c | 22 ++-- sys/vfs/ntfs/ntfs_vfsops.c | 6 +- sys/vfs/ntfs/ntfs_vnops.c | 5 +- sys/vfs/nwfs/nwfs_node.c | 5 +- sys/vfs/portal/portal_vnops.c | 5 +- sys/vfs/smbfs/smbfs_node.c | 5 +- sys/vfs/specfs/spec_vnops.c | 11 +- sys/vfs/udf/udf_vfsops.c | 4 +- sys/vfs/udf/udf_vnops.c | 5 +- sys/vfs/ufs/ffs_vfsops.c | 13 ++- sys/vfs/ufs/ufs_vnops.c | 22 ++-- 45 files changed, 463 insertions(+), 274 deletions(-) diff --git a/sys/dev/disk/ata/atapi-cd.c b/sys/dev/disk/ata/atapi-cd.c index a1bf3c291f..a0e0ab4b0a 100644 --- a/sys/dev/disk/ata/atapi-cd.c +++ b/sys/dev/disk/ata/atapi-cd.c @@ -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; diff --git a/sys/dev/disk/nata/atapi-cd.c b/sys/dev/disk/nata/atapi-cd.c index f6cf7a500b..c1e06abde7 100644 --- a/sys/dev/disk/nata/atapi-cd.c +++ b/sys/dev/disk/nata/atapi-cd.c @@ -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; diff --git a/sys/dev/raid/asr/asr.c b/sys/dev/raid/asr/asr.c index 6400c7657b..d53cd6b0c0 100644 --- a/sys/dev/raid/asr/asr.c +++ b/sys/dev/raid/asr/asr.c @@ -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)] diff --git a/sys/dev/raid/vinum/.gdbinit.kernel b/sys/dev/raid/vinum/.gdbinit.kernel index 1de0a80214..1cba58da4d 100644 --- a/sys/dev/raid/vinum/.gdbinit.kernel +++ b/sys/dev/raid/vinum/.gdbinit.kernel @@ -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, \ diff --git a/sys/dev/serial/sio/sio.c b/sys/dev/serial/sio/sio.c index 04a7cd3d7d..0fe8e4e9c5 100644 --- a/sys/dev/serial/sio/sio.c +++ b/sys/dev/serial/sio/sio.c @@ -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, diff --git a/sys/emulation/linux/linux_misc.c b/sys/emulation/linux/linux_misc.c index 5a11aad403..a1bd5e2f34 100644 --- a/sys/emulation/linux/linux_misc.c +++ b/sys/emulation/linux/linux_misc.c @@ -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); diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c index b2ca523d9c..c99b38a8eb 100644 --- a/sys/kern/kern_conf.c +++ b/sys/kern/kern_conf.c @@ -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 @@ -48,8 +48,6 @@ #include -#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)); } /* @@ -135,18 +139,23 @@ lminor(cdev_t dev) * In this case and this case only we allow a match when the ops vector * 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) { diff --git a/sys/kern/kern_device.c b/sys/kern/kern_device.c index 0f9202b832..80cb732e05 100644 --- a/sys/kern/kern_device.c +++ b/sys/kern/kern_device.c @@ -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 #include @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -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/). * - * 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,22 +554,72 @@ 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. @@ -551,10 +627,10 @@ dev_ops_remove(struct dev_ops *ops, u_int mask, u_int match) 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 * diff --git a/sys/kern/kern_kinfo.c b/sys/kern/kern_kinfo.c index 6666115930..f9bd3d85bf 100644 --- a/sys/kern/kern_kinfo.c +++ b/sys/kern/kern_kinfo.c @@ -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 diff --git a/sys/kern/vfs_conf.c b/sys/kern/vfs_conf.c index a1168e1cdf..1f68d86da0 100644 --- a/sys/kern/vfs_conf.c +++ b/sys/kern/vfs_conf.c @@ -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(" : 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. diff --git a/sys/kern/vfs_jops.c b/sys/kern/vfs_jops.c index 7d490426d9..b9f5a7433f 100644 --- a/sys/kern/vfs_jops.c +++ b/sys/kern/vfs_jops.c @@ -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); } diff --git a/sys/kern/vfs_journal.c b/sys/kern/vfs_journal.c index 88f3e9bcb2..32f625434c 100644 --- a/sys/kern/vfs_journal.c +++ b/sys/kern/vfs_journal.c @@ -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)); diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index ae90b64f02..3ce8f8eeb1 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -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; diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 42849e2f61..d604d5c7ab 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -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 @@ -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); diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 3556070f6b..60af4195b3 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -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 @@ -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; diff --git a/sys/sys/conf.h b/sys/sys/conf.h index 35e463edb8..666994fea2 100644 --- a/sys/sys/conf.h +++ b/sys/sys/conf.h @@ -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); diff --git a/sys/sys/device.h b/sys/sys/device.h index 3c3b7e7db8..1a426e726f 100644 --- a/sys/sys/device.h +++ b/sys/sys/device.h @@ -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 @@ -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 #endif +#ifndef _SYS_TREE_H_ +#include +#endif #ifndef _SYS_SYSLINK_RPC_H_ #include #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 *); diff --git a/sys/sys/journal.h b/sys/sys/journal.h index 147e162ec0..150c4a4330 100644 --- a/sys/sys/journal.h +++ b/sys/sys/journal.h @@ -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 diff --git a/sys/sys/kern_syscall.h b/sys/sys/kern_syscall.h index 85d621916c..04c8a425c4 100644 --- a/sys/sys/kern_syscall.h +++ b/sys/sys/kern_syscall.h @@ -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); diff --git a/sys/sys/vfscache.h b/sys/sys/vfscache.h index 462bb37e58..eb9afe085c 100644 --- a/sys/sys/vfscache.h +++ b/sys/sys/vfscache.h @@ -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 */ diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 7c81647a8f..c7029d4ce1 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -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); diff --git a/sys/vfs/fdesc/fdesc_vnops.c b/sys/vfs/fdesc/fdesc_vnops.c index 7f28dafcc5..44dceb1fa6 100644 --- a/sys/vfs/fdesc/fdesc_vnops.c +++ b/sys/vfs/fdesc/fdesc_vnops.c @@ -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. diff --git a/sys/vfs/gnu/ext2fs/ext2_vfsops.c b/sys/vfs/gnu/ext2fs/ext2_vfsops.c index 63ccf7fbf1..8156d114fc 100644 --- a/sys/vfs/gnu/ext2fs/ext2_vfsops.c +++ b/sys/vfs/gnu/ext2fs/ext2_vfsops.c @@ -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); diff --git a/sys/vfs/gnu/ext2fs/ext2_vnops.c b/sys/vfs/gnu/ext2fs/ext2_vnops.c index 6c13dc0650..857b5df0bc 100644 --- a/sys/vfs/gnu/ext2fs/ext2_vnops.c +++ b/sys/vfs/gnu/ext2fs/ext2_vnops.c @@ -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; diff --git a/sys/vfs/hpfs/hpfs_vfsops.c b/sys/vfs/hpfs/hpfs_vfsops.c index 3ae380370d..0f60f87214 100644 --- a/sys/vfs/hpfs/hpfs_vfsops.c +++ b/sys/vfs/hpfs/hpfs_vfsops.c @@ -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) diff --git a/sys/vfs/hpfs/hpfs_vnops.c b/sys/vfs/hpfs/hpfs_vnops.c index e78fe2570d..316ad6f130 100644 --- a/sys/vfs/hpfs/hpfs_vnops.c +++ b/sys/vfs/hpfs/hpfs_vnops.c @@ -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 @@ -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); diff --git a/sys/vfs/isofs/cd9660/cd9660_vfsops.c b/sys/vfs/isofs/cd9660/cd9660_vfsops.c index 39de059364..69c0fb674a 100644 --- a/sys/vfs/isofs/cd9660/cd9660_vfsops.c +++ b/sys/vfs/isofs/cd9660/cd9660_vfsops.c @@ -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 @@ -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: diff --git a/sys/vfs/isofs/cd9660/cd9660_vnops.c b/sys/vfs/isofs/cd9660/cd9660_vnops.c index 33323cdabf..f5ec0ee1a2 100644 --- a/sys/vfs/isofs/cd9660/cd9660_vnops.c +++ b/sys/vfs/isofs/cd9660/cd9660_vnops.c @@ -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 @@ -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) { diff --git a/sys/vfs/mfs/mfs_vfsops.c b/sys/vfs/mfs/mfs_vfsops.c index d284159cff..bbed09935a 100644 --- a/sys/vfs/mfs/mfs_vfsops.c +++ b/sys/vfs/mfs/mfs_vfsops.c @@ -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; diff --git a/sys/vfs/mfs/mfs_vnops.c b/sys/vfs/mfs/mfs_vnops.c index d0e356fa2d..564fc39194 100644 --- a/sys/vfs/mfs/mfs_vnops.c +++ b/sys/vfs/mfs/mfs_vnops.c @@ -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 @@ -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)); } diff --git a/sys/vfs/msdosfs/msdosfs_vfsops.c b/sys/vfs/msdosfs/msdosfs_vfsops.c index 3090a19a80..4f38b9e3df 100644 --- a/sys/vfs/msdosfs/msdosfs_vfsops.c +++ b/sys/vfs/msdosfs/msdosfs_vfsops.c @@ -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); diff --git a/sys/vfs/msdosfs/msdosfs_vnops.c b/sys/vfs/msdosfs/msdosfs_vnops.c index 86240e1b86..5ecd547543 100644 --- a/sys/vfs/msdosfs/msdosfs_vnops.c +++ b/sys/vfs/msdosfs/msdosfs_vnops.c @@ -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 diff --git a/sys/vfs/nfs/nfs_serv.c b/sys/vfs/nfs/nfs_serv.c index 4a00c1dc28..5eba756844 100644 --- a/sys/vfs/nfs/nfs_serv.c +++ b/sys/vfs/nfs/nfs_serv.c @@ -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); } /* diff --git a/sys/vfs/nfs/nfs_subs.c b/sys/vfs/nfs/nfs_subs.c index 02b16daf8f..7fc3dd8d9b 100644 --- a/sys/vfs/nfs/nfs_subs.c +++ b/sys/vfs/nfs/nfs_subs.c @@ -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); diff --git a/sys/vfs/nfs/nfs_vnops.c b/sys/vfs/nfs/nfs_vnops.c index 726fa3ed95..9fb149f838 100644 --- a/sys/vfs/nfs/nfs_vnops.c +++ b/sys/vfs/nfs/nfs_vnops.c @@ -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); } diff --git a/sys/vfs/ntfs/ntfs_vfsops.c b/sys/vfs/ntfs/ntfs_vfsops.c index 574dd79250..e1630ebbb2 100644 --- a/sys/vfs/ntfs/ntfs_vfsops.c +++ b/sys/vfs/ntfs/ntfs_vfsops.c @@ -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; diff --git a/sys/vfs/ntfs/ntfs_vnops.c b/sys/vfs/ntfs/ntfs_vnops.c index 43fda75b9a..7596f46999 100644 --- a/sys/vfs/ntfs/ntfs_vnops.c +++ b/sys/vfs/ntfs/ntfs_vnops.c @@ -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); diff --git a/sys/vfs/nwfs/nwfs_node.c b/sys/vfs/nwfs/nwfs_node.c index b9ebbc3e2e..1c1d8dded4 100644 --- a/sys/vfs/nwfs/nwfs_node.c +++ b/sys/vfs/nwfs/nwfs_node.c @@ -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 #include @@ -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 */ diff --git a/sys/vfs/portal/portal_vnops.c b/sys/vfs/portal/portal_vnops.c index cdfe4d6993..94435c0c7b 100644 --- a/sys/vfs/portal/portal_vnops.c +++ b/sys/vfs/portal/portal_vnops.c @@ -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; */ diff --git a/sys/vfs/smbfs/smbfs_node.c b/sys/vfs/smbfs/smbfs_node.c index 74ab3c7533..705fcd1a71 100644 --- a/sys/vfs/smbfs/smbfs_node.c +++ b/sys/vfs/smbfs/smbfs_node.c @@ -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 #include @@ -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 */ diff --git a/sys/vfs/specfs/spec_vnops.c b/sys/vfs/specfs/spec_vnops.c index ab38caa3b4..985b3f5df7 100644 --- a/sys/vfs/specfs/spec_vnops.c +++ b/sys/vfs/specfs/spec_vnops.c @@ -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 @@ -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); diff --git a/sys/vfs/udf/udf_vfsops.c b/sys/vfs/udf/udf_vfsops.c index cca4a81954..5b3711817d 100644 --- a/sys/vfs/udf/udf_vfsops.c +++ b/sys/vfs/udf/udf_vfsops.c @@ -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); diff --git a/sys/vfs/udf/udf_vnops.c b/sys/vfs/udf/udf_vnops.c index 88285a2856..4c8532addc 100644 --- a/sys/vfs/udf/udf_vnops.c +++ b/sys/vfs/udf/udf_vnops.c @@ -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 diff --git a/sys/vfs/ufs/ffs_vfsops.c b/sys/vfs/ufs/ffs_vfsops.c index 4c2646ed93..21e973385d 100644 --- a/sys/vfs/ufs/ffs_vfsops.c +++ b/sys/vfs/ufs/ffs_vfsops.c @@ -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); diff --git a/sys/vfs/ufs/ufs_vnops.c b/sys/vfs/ufs/ufs_vnops.c index d811262498..02f854e1dc 100644 --- a/sys/vfs/ufs/ufs_vnops.c +++ b/sys/vfs/ufs/ufs_vnops.c @@ -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; -- 2.41.0