DEVFS - rollup - all kernel devices
authorMatthew Dillon <dillon@apollo.backplane.com>
Tue, 4 Aug 2009 04:42:54 +0000 (21:42 -0700)
committerMatthew Dillon <dillon@apollo.backplane.com>
Tue, 4 Aug 2009 04:56:30 +0000 (21:56 -0700)
* Make changes needed to kernel devices to use devfs.

* Also pre-generate some devices (usually 4) to support system utilities
  which do not yet deal with the auto-cloning device support.

* Adjust the spec_vnops for various filesystems to vector to dummy
  code for read and write, for VBLK/VCHR nodes in old filesystems
  which are no longer supported.

Submitted-by: Alex Hornung <ahornung@gmail.com>
25 files changed:
sys/bus/cam/scsi/scsi_target.c
sys/bus/firewire/firewirereg.h
sys/bus/firewire/fwdev.c
sys/dev/disk/vn/vn.c
sys/dev/misc/snp/snp.c
sys/dev/sound/pcm/sound.c
sys/net/bpf.c
sys/net/tap/if_tap.c
sys/net/tun/if_tun.c
sys/netproto/smb/smb_dev.c
sys/vfs/gnu/ext2fs/ext2_vfsops.c
sys/vfs/gnu/ext2fs/ext2_vnops.c
sys/vfs/hammer/hammer_expand.c
sys/vfs/hammer/hammer_ondisk.c
sys/vfs/hammer/hammer_vnops.c
sys/vfs/hpfs/hpfs_vfsops.c
sys/vfs/isofs/cd9660/cd9660_vfsops.c
sys/vfs/isofs/cd9660/cd9660_vnops.c
sys/vfs/mfs/mfs_vnops.c
sys/vfs/msdosfs/msdosfs_vfsops.c
sys/vfs/nfs/nfs_vnops.c
sys/vfs/ntfs/ntfs_vfsops.c
sys/vfs/udf/udf_vfsops.c
sys/vfs/ufs/ffs_vfsops.c
sys/vfs/ufs/ufs_vnops.c

index 881d6c8..4da28d9 100644 (file)
@@ -40,6 +40,7 @@
 #include <sys/vnode.h>
 #include <sys/devicestat.h>
 #include <sys/thread2.h>
+#include <vfs/devfs/devfs.h>
 
 #include "../cam.h"
 #include "../cam_ccb.h"
@@ -99,6 +100,9 @@ static d_write_t     targwrite;
 static d_ioctl_t       targioctl;
 static d_poll_t                targpoll;
 static d_kqfilter_t    targkqfilter;
+static d_clone_t       targclone;
+DEVFS_DECLARE_CLONE_BITMAP(targ);
+
 static void            targreadfiltdetach(struct knote *kn);
 static int             targreadfilt(struct knote *kn, long hint);
 static struct filterops targread_filtops =
@@ -176,8 +180,10 @@ targopen(struct dev_open_args *ap)
        reference_dev(dev);             /* save ref for later destroy_dev() */
 
        /* Create the targ device, allocate its softc, initialize it */
+#if 0
        make_dev(&targ_ops, minor(dev), UID_ROOT, GID_WHEEL, 0600,
                         "targ%d", lminor(dev));
+#endif
        MALLOC(softc, struct targ_softc *, sizeof(*softc), M_TARG,
               M_INTWAIT | M_ZERO);
        dev->si_drv1 = softc;
@@ -205,6 +211,7 @@ targclose(struct dev_close_args *ap)
        softc = (struct targ_softc *)dev->si_drv1;
        if ((softc->periph == NULL) ||
            (softc->state & TARG_STATE_LUN_ENABLED) == 0) {
+               devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(targ), dev->si_uminor);
                destroy_dev(dev);
                FREE(softc, M_TARG);
                return (0);
@@ -225,6 +232,7 @@ targclose(struct dev_close_args *ap)
                        softc->periph = NULL;
                }
                destroy_dev(dev);       /* eats the open ref */
+               devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(targ), dev->si_uminor);
                FREE(softc, M_TARG);
        } else {
                release_dev(dev);
@@ -1032,10 +1040,24 @@ targgetdescr(struct targ_softc *softc)
        return (descr);
 }
 
+static int
+targclone(struct dev_clone_args *ap)
+{
+       int unit;
+
+       unit = devfs_clone_bitmap_get(&DEVFS_CLONE_BITMAP(targ), 0);
+       ap->a_dev = make_only_dev(&targ_ops, unit, UID_ROOT, GID_WHEEL,
+                                 0600, "targ%d", unit);
+       return 0;
+}
+
 static void
 targinit(void)
 {
-       dev_ops_add(&targ_ops, 0, 0);
+       make_dev(&targ_ops, 0, UID_ROOT, GID_WHEEL, 0600, "targ");
+       devfs_clone_bitmap_init(&DEVFS_CLONE_BITMAP(targ));
+       devfs_clone_handler_add("targ", targclone);
+       /* XXX: need uninit or so? */
 }
 
 static void
index 9453065..1dececc 100644 (file)
@@ -300,6 +300,7 @@ struct fw_device *fw_noderesolve_nodeid (struct firewire_comm *, int);
 struct fw_device *fw_noderesolve_eui64 (struct firewire_comm *, struct fw_eui64 *);
 struct fw_bind *fw_bindlookup (struct firewire_comm *, u_int16_t, u_int32_t);
 void fw_drain_txq (struct firewire_comm *);
+int fwdev_makedev (struct firewire_softc *);
 int fwdev_destroydev (struct firewire_softc *);
 void fwdev_clone (void *, char *, int, cdev_t *);
 
index 9117829..adaa634 100644 (file)
@@ -778,7 +778,7 @@ fwdev_makedev(struct firewire_softc *sc)
        int unit;
 
        unit = device_get_unit(sc->fc->bdev);
-       dev_ops_add(&firewire_ops, FW_UNITMASK, FW_UNIT(unit));
+       /*HELPME dev_ops_add(&firewire_ops, FW_UNITMASK, FW_UNIT(unit));*/
        return(0);
 }
 
index 17382c7..d925e0e 100644 (file)
 #include <vm/swap_pager.h>
 #include <vm/vm_extern.h>
 #include <vm/vm_zone.h>
+#include <vfs/devfs/devfs.h>
 
 static d_ioctl_t       vnioctl;
 static d_open_t        vnopen;
 static d_close_t       vnclose;
 static d_psize_t       vnsize;
 static d_strategy_t    vnstrategy;
+#if 0
+static d_clone_t       vnclone;
+#endif
+DEVFS_DECLARE_CLONE_BITMAP(vn);
+#define VN_PREALLOCATED_UNITS  4
 
 #define CDEV_MAJOR 43
 
@@ -116,8 +122,7 @@ struct vn_softc {
        int             sc_flags;       /* flags                        */
        u_int64_t       sc_size;        /* size of vn, sc_secsize scale */
        int             sc_secsize;     /* sector size                  */
-       struct diskslices *sc_slices;   /* XXX fields from struct disk  */
-       struct disk_info sc_info;       /* XXX fields from struct disk  */
+       struct disk     sc_disk;
        struct vnode    *sc_vp;         /* vnode if not NULL            */
        vm_object_t     sc_object;      /* backing object if not NULL   */
        struct ucred    *sc_cred;       /* credentials                  */
@@ -149,15 +154,52 @@ static int        vniocattach_swap (struct vn_softc *, struct vn_ioctl *, cdev_t dev,
 static int
 vnclose(struct dev_close_args *ap)
 {
+#if 0
        cdev_t dev = ap->a_head.a_dev;
        struct vn_softc *vn = dev->si_drv1;
-
-       IFOPT(vn, VN_LABELS)
-               if (vn->sc_slices != NULL)
-                       dsclose(dev, ap->a_devtype, vn->sc_slices);
+       if (dev->si_uminor >= VN_PREALLOCATED_UNITS) {
+               devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(vn), dev->si_uminor);
+               destroy_dev(dev);
+       }
+#endif
        return (0);
 }
 
+static struct vn_softc *
+vncreatevn(void)
+{
+       struct vn_softc *vn;
+
+       vn = kmalloc(sizeof *vn, M_DEVBUF, M_WAITOK | M_ZERO);
+       return vn;
+}
+
+static void
+vninitvn(struct vn_softc *vn, cdev_t dev)
+{
+       int unit;
+
+       KKASSERT(vn != NULL);
+       KKASSERT(dev != NULL);
+       unit = dkunit(dev);
+
+       vn->sc_unit = unit;
+       dev->si_drv1 = vn;
+       vn->sc_devlist = dev;
+       if (vn->sc_devlist->si_drv1 == NULL) {
+               reference_dev(vn->sc_devlist);
+               vn->sc_devlist->si_drv1 = vn;
+               vn->sc_devlist->si_drv2 = NULL;
+       }
+       if (vn->sc_devlist != dev) {
+               dev->si_drv1 = vn;
+               dev->si_drv2 = vn->sc_devlist;
+               vn->sc_devlist = dev;
+               reference_dev(dev);
+       }
+       SLIST_INSERT_HEAD(&vn_list, vn, sc_list);
+}
+
 /*
  * Called only when si_drv1 is NULL.  Locate the associated vn node and
  * attach the device to it.
@@ -178,26 +220,10 @@ vnfindvn(cdev_t dev)
                        break;
                }
        }
-       if (vn == NULL) {
-               vn = kmalloc(sizeof *vn, M_DEVBUF, M_WAITOK | M_ZERO);
-               vn->sc_unit = unit;
-               dev->si_drv1 = vn;
-               vn->sc_devlist = make_dev(&vn_ops, 0, UID_ROOT,
-                                       GID_OPERATOR, 0640, "vn%d", unit);
-               if (vn->sc_devlist->si_drv1 == NULL) {
-                       reference_dev(vn->sc_devlist);
-                       vn->sc_devlist->si_drv1 = vn;
-                       vn->sc_devlist->si_drv2 = NULL;
-               }
-               if (vn->sc_devlist != dev) {
-                       dev->si_drv1 = vn;
-                       dev->si_drv2 = vn->sc_devlist;
-                       vn->sc_devlist = dev;
-                       reference_dev(dev);
-               }
-               SLIST_INSERT_HEAD(&vn_list, vn, sc_list);
-       }
-       return (vn);
+
+       KKASSERT(vn != NULL);
+
+       return vn;
 }
 
 static int
@@ -205,7 +231,6 @@ vnopen(struct dev_open_args *ap)
 {
        cdev_t dev = ap->a_head.a_dev;
        struct vn_softc *vn;
-       struct disk_info *info;
 
        /*
         * Locate preexisting device
@@ -234,37 +259,6 @@ vnopen(struct dev_open_args *ap)
                kprintf("vnopen(%s, 0x%x, 0x%x)\n",
                    devtoname(dev), ap->a_oflags, ap->a_devtype);
 
-       /*
-        * Initialize label
-        */
-
-       IFOPT(vn, VN_LABELS) {
-               if (vn->sc_flags & VNF_INITED) {
-                       info = &vn->sc_info;
-                       bzero(info, sizeof(*info));
-                       info->d_media_blksize = vn->sc_secsize;
-                       info->d_media_blocks = vn->sc_size;
-                       /*
-                        * reserve mbr sector for backwards compatibility
-                        * when no slices exist.
-                        */
-                       info->d_dsflags = DSO_COMPATMBR;
-
-                       info->d_secpertrack = 32;
-                       info->d_nheads = 64 / (vn->sc_secsize / DEV_BSIZE);
-                       info->d_secpercyl = info->d_secpertrack *
-                                           info->d_nheads;
-                       info->d_ncylinders = vn->sc_size / info->d_secpercyl;
-
-                       return (dsopen(dev, ap->a_devtype, 0,
-                                       &vn->sc_slices, info));
-               }
-               if (dkslice(dev) != WHOLE_DISK_SLICE ||
-                   dkpart(dev) != WHOLE_SLICE_PART ||
-                   ap->a_devtype != S_IFCHR) {
-                       return (ENXIO);
-               }
-       }
        return(0);
 }
 
@@ -304,55 +298,17 @@ vnstrategy(struct dev_strategy_args *ap)
 
        bp->b_resid = bp->b_bcount;
 
-       IFOPT(vn, VN_LABELS) {
-               /*
-                * The vnode device is using disk/slice label support.
-                *
-                * The dscheck() function is called for validating the
-                * slices that exist ON the vnode device itself, and
-                * translate the "slice-relative" block number, again.
-                * dscheck() will call biodone() and return NULL if
-                * we are at EOF or beyond the device size.
-                */
-               if (vn->sc_slices == NULL) {
-                       nbio = bio;
-               } else if ((nbio = dscheck(dev, bio, vn->sc_slices)) == NULL) {
-                       goto done;
-               }
-       } else {
-               int64_t pbn;    /* in sc_secsize chunks */
-               long sz;        /* in sc_secsize chunks */
-
-               /*
-                * Check for required alignment.  Transfers must be a valid
-                * multiple of the sector size.
-                */
-               if (bp->b_bcount % vn->sc_secsize != 0 ||
-                   bio->bio_offset % vn->sc_secsize != 0) {
-                       goto bad;
-               }
-
-               pbn = bio->bio_offset / vn->sc_secsize;
-               sz = howmany(bp->b_bcount, vn->sc_secsize);
+       /*
+        * The vnode device is using disk/slice label support.
+        *
+        * The dscheck() function is called for validating the
+        * slices that exist ON the vnode device itself, and
+        * translate the "slice-relative" block number, again.
+        * dscheck() will call biodone() and return NULL if
+        * we are at EOF or beyond the device size.
+        */
 
-               /*
-                * Check for an illegal pbn or EOF truncation
-                */
-               if (pbn < 0)
-                       goto bad;
-               if (pbn + sz > vn->sc_size) {
-                       if (pbn > vn->sc_size || (bp->b_flags & B_BNOCLIP))
-                               goto bad;
-                       if (pbn == vn->sc_size) {
-                               bp->b_resid = bp->b_bcount;
-                               bp->b_flags |= B_INVAL;
-                               goto done;
-                       }
-                       bp->b_bcount = (vn->sc_size - pbn) * vn->sc_secsize;
-               }
-               nbio = push_bio(bio);
-               nbio->bio_offset = pbn * vn->sc_secsize;
-       }
+       nbio = bio;
 
        /*
         * Use the translated nbio from this point on
@@ -423,16 +379,6 @@ vnstrategy(struct dev_strategy_args *ap)
        }
        biodone(nbio);
        return(0);
-
-       /*
-        * Shortcuts / check failures on the original bio (not nbio).
-        */
-bad:
-       bp->b_error = EINVAL;
-       bp->b_flags |= B_ERROR | B_INVAL;
-done:
-       biodone(bio);
-       return(0);
 }
 
 /* ARGSUSED */
@@ -463,18 +409,11 @@ vnioctl(struct dev_ioctl_args *ap)
                goto vn_specific;
        }
 
-       IFOPT(vn,VN_LABELS) {
-               if (vn->sc_slices != NULL) {
-                       error = dsioctl(dev, ap->a_cmd, ap->a_data,
-                                       ap->a_fflag,
-                                       &vn->sc_slices, &vn->sc_info);
-                       if (error != ENOIOCTL)
-                               return (error);
-               }
-               if (dkslice(dev) != WHOLE_DISK_SLICE ||
-                   dkpart(dev) != WHOLE_SLICE_PART)
-                       return (ENOTTY);
-       }
+#if 0
+       if (dkslice(dev) != WHOLE_DISK_SLICE ||
+               dkpart(dev) != WHOLE_SLICE_PART)
+               return (ENOTTY);
+#endif
 
     vn_specific:
 
@@ -561,6 +500,7 @@ vniocattach_file(struct vn_softc *vn, struct vn_ioctl *vio, cdev_t dev,
        struct nlookupdata nd;
        int error, flags;
        struct vnode *vp;
+       struct disk_info info;
 
        flags = FREAD|FWRITE;
        error = nlookup_init(&nd, vio->vn_file, 
@@ -607,18 +547,28 @@ vniocattach_file(struct vn_softc *vn, struct vn_ioctl *vio, cdev_t dev,
        vn->sc_flags |= VNF_INITED;
        if (flags == FREAD)
                vn->sc_flags |= VNF_READONLY;
-       IFOPT(vn, VN_LABELS) {
-               /*
-                * Reopen so that `ds' knows which devices are open.
-                * If this is the first VNIOCSET, then we've
-                * guaranteed that the device is the cdev and that
-                * no other slices or labels are open.  Otherwise,
-                * we rely on VNIOCCLR not being abused.
-                */
-               error = dev_dopen(dev, flag, S_IFCHR, cred);
-               if (error)
-                       vnclear(vn);
-       }
+
+       /*
+        * Set the disk info so that probing is triggered
+        */
+       bzero(&info, sizeof(struct disk_info));
+       info.d_media_blksize = vn->sc_secsize;
+       info.d_media_blocks = vn->sc_size;
+       /*
+        * reserve mbr sector for backwards compatibility
+        * when no slices exist.
+        */
+       info.d_dsflags = DSO_COMPATMBR;
+       info.d_secpertrack = 32;
+       info.d_nheads = 64 / (vn->sc_secsize / DEV_BSIZE);
+       info.d_secpercyl = info.d_secpertrack * info.d_nheads;
+       info.d_ncylinders = vn->sc_size / info.d_secpercyl;
+       disk_setdiskinfo_sync(&vn->sc_disk, &info);
+
+       error = dev_dopen(dev, flag, S_IFCHR, cred);
+       if (error)
+               vnclear(vn);
+
        IFOPT(vn, VN_FOLLOW)
                kprintf("vnioctl: SET vp %p size %llx blks\n",
                       vn->sc_vp, vn->sc_size);
@@ -639,6 +589,7 @@ vniocattach_swap(struct vn_softc *vn, struct vn_ioctl *vio, cdev_t dev,
                 int flag, struct ucred *cred)
 {
        int error;
+       struct disk_info info;
 
        /*
         * Range check.  Disallow negative sizes or any size less then the
@@ -674,16 +625,24 @@ vniocattach_swap(struct vn_softc *vn, struct vn_ioctl *vio, cdev_t dev,
 
        error = vnsetcred(vn, cred);
        if (error == 0) {
-               IFOPT(vn, VN_LABELS) {
-                       /*
-                        * Reopen so that `ds' knows which devices are open.
-                        * If this is the first VNIOCSET, then we've
-                        * guaranteed that the device is the cdev and that
-                        * no other slices or labels are open.  Otherwise,
-                        * we rely on VNIOCCLR not being abused.
-                        */
-                       error = dev_dopen(dev, flag, S_IFCHR, cred);
-               }
+               /*
+                * Set the disk info so that probing is triggered
+                */
+               bzero(&info, sizeof(struct disk_info));
+               info.d_media_blksize = vn->sc_secsize;
+               info.d_media_blocks = vn->sc_size;
+               /*
+                * reserve mbr sector for backwards compatibility
+                * when no slices exist.
+                */
+               info.d_dsflags = DSO_COMPATMBR;
+               info.d_secpertrack = 32;
+               info.d_nheads = 64 / (vn->sc_secsize / DEV_BSIZE);
+               info.d_secpercyl = info.d_secpertrack * info.d_nheads;
+               info.d_ncylinders = vn->sc_size / info.d_secpercyl;
+               disk_setdiskinfo_sync(&vn->sc_disk, &info);
+
+               error = dev_dopen(dev, flag, S_IFCHR, cred);
        }
        if (error == 0) {
                IFOPT(vn, VN_FOLLOW) {
@@ -748,8 +707,6 @@ vnclear(struct vn_softc *vn)
 {
        IFOPT(vn, VN_FOLLOW)
                kprintf("vnclear(%p): vp=%p\n", vn, vn->sc_vp);
-       if (vn->sc_slices != NULL)
-               dsgone(&vn->sc_slices);
        vn->sc_flags &= ~VNF_INITED;
        if (vn->sc_vp != NULL) {
                vn_close(vn->sc_vp,
@@ -765,6 +722,9 @@ vnclear(struct vn_softc *vn)
                vm_pager_deallocate(vn->sc_object);
                vn->sc_object = NULL;
        }
+
+       disk_unprobe(&vn->sc_disk);
+
        vn->sc_size = 0;
 }
 
@@ -859,17 +819,60 @@ vnsize(struct dev_psize_args *ap)
        return(0);
 }
 
+#if 0
+static int
+vnclone(struct dev_clone_args *ap)
+{
+       int unit;
+
+       unit = devfs_clone_bitmap_get(&DEVFS_CLONE_BITMAP(vn), 0);
+       ap->a_dev = make_only_dev(&vn_ops, unit, UID_ROOT, GID_OPERATOR, 0600,
+                                                               "vn%d", unit);
+
+       return 0;
+}
+#endif
+
 static int 
 vn_modevent(module_t mod, int type, void *data)
 {
        struct vn_softc *vn;
+       struct disk_info info;
        cdev_t dev;
+       int i;
 
        switch (type) {
        case MOD_LOAD:
-               dev_ops_add(&vn_ops, 0, 0);
+#if 0
+               make_dev(&vn_ops, 0, UID_ROOT, GID_OPERATOR, 0640, "vn");
+#endif
+               devfs_clone_bitmap_init(&DEVFS_CLONE_BITMAP(vn));
+               for (i = 0; i < VN_PREALLOCATED_UNITS; i++) {
+                       vn = vncreatevn();
+                       dev = disk_create(i, &vn->sc_disk, &vn_ops);
+                       vninitvn(vn, dev);
+
+                       bzero(&info, sizeof(struct disk_info));
+                       info.d_media_blksize = 512;
+                       info.d_media_blocks = 0;
+                       info.d_dsflags = DSO_MBRQUIET;
+                       info.d_secpertrack = 32;
+                       info.d_nheads = 64;
+                       info.d_secpercyl = info.d_secpertrack * info.d_nheads;
+                       info.d_ncylinders = 0;
+                       disk_setdiskinfo_sync(&vn->sc_disk, &info);
+
+                       devfs_clone_bitmap_set(&DEVFS_CLONE_BITMAP(vn), i);
+               }
+#if 0
+               devfs_clone_handler_add("vn", vnclone);
+#endif
                break;
        case MOD_UNLOAD:
+               devfs_clone_bitmap_uninit(&DEVFS_CLONE_BITMAP(vn));
+#if 0
+               devfs_clone_handler_del("vn");
+#endif
                /* fall through */
        case MOD_SHUTDOWN:
                while ((vn = SLIST_FIRST(&vn_list)) != NULL) {
index 74aca7c..2b4994e 100644 (file)
@@ -29,6 +29,7 @@
 #include <sys/thread2.h>
 #include <sys/vnode.h>
 #include <sys/device.h>
+#include <vfs/devfs/devfs.h>
 
 static l_close_t       snplclose;
 static l_write_t       snplwrite;
@@ -38,6 +39,9 @@ static        d_read_t        snpread;
 static d_write_t       snpwrite;
 static d_ioctl_t       snpioctl;
 static d_poll_t        snppoll;
+static d_clone_t       snpclone;
+DEVFS_DECLARE_CLONE_BITMAP(snp);
+#define SNP_PREALLOCATED_UNITS 4
 
 #define CDEV_MAJOR 53
 static struct dev_ops snp_ops = {
@@ -364,8 +368,10 @@ snpopen(struct dev_open_args *ap)
        struct snoop *snp;
 
        if (dev->si_drv1 == NULL) {
+#if 0
                make_dev(&snp_ops, minor(dev), UID_ROOT, GID_WHEEL,
                    0600, "snp%d", minor(dev));
+#endif
                dev->si_drv1 = snp = kmalloc(sizeof(*snp), M_SNP,
                    M_WAITOK | M_ZERO);
        } else {
@@ -442,7 +448,10 @@ snpclose(struct dev_close_args *ap)
        kfree(snp->snp_buf, M_SNP);
        snp->snp_flags &= ~SNOOP_OPEN;
        dev->si_drv1 = NULL;
-
+       if (dev->si_uminor >= SNP_PREALLOCATED_UNITS) {
+               devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(snp), dev->si_uminor);
+               destroy_dev(dev);
+       }
        return (snp_detach(snp));
 }
 
@@ -567,20 +576,42 @@ snppoll(struct dev_poll_args *ap)
        return (0);
 }
 
+static int
+snpclone(struct dev_clone_args *ap)
+{
+       int unit;
+       unit = devfs_clone_bitmap_get(&DEVFS_CLONE_BITMAP(snp), 0);
+       ap->a_dev = make_only_dev(&snp_ops, unit, UID_ROOT, GID_WHEEL, 0600,
+                                                       "snp%d", unit);
+
+       return 0;
+}
+
 static int
 snp_modevent(module_t mod, int type, void *data)
 {
+       int i;
 
        switch (type) {
        case MOD_LOAD:
                snooplinedisc = ldisc_register(LDISC_LOAD, &snpdisc);
-               dev_ops_add(&snp_ops, 0, 0);
+               devfs_clone_bitmap_init(&DEVFS_CLONE_BITMAP(snp));
+
+               for (i = 0; i < SNP_PREALLOCATED_UNITS; i++) {
+                       make_dev(&snp_ops, i, UID_ROOT, GID_WHEEL, 0600, "snp%d", i);
+                       devfs_clone_bitmap_set(&DEVFS_CLONE_BITMAP(snp), i);
+               }
+
+               make_dev(&snp_ops, 0, UID_ROOT, GID_WHEEL, 0600, "snp");
+               devfs_clone_handler_add("snp", snpclone);
                break;
        case MOD_UNLOAD:
                if (!LIST_EMPTY(&snp_sclist))
                        return (EBUSY);
                ldisc_deregister(snooplinedisc);
+               devfs_clone_handler_del("snp");
                dev_ops_remove_all(&snp_ops);
+               devfs_clone_bitmap_uninit(&DEVFS_CLONE_BITMAP(snp));
                break;
        default:
                break;
index dc92387..45a3146 100644 (file)
@@ -966,11 +966,6 @@ pcm_unregister(device_t dev)
                }
                if (sce->audio_devt) {
                        release_dev(sce->audio_devt);
-                       /*
-                       dev_ops_remove(&dsp_cdevsw,
-                                   PCMMKMINOR(-1, -1, 0),
-                                   PCMMKMINOR(unit, SND_DEV_DSP16, sce->chan_num));
-                       */
                        sce->audio_devt = NULL;
                }
                if (sce->dspr_devt) {
index 511b32b..b2d05ab 100644 (file)
@@ -85,6 +85,7 @@ struct netmsg_bpf_output {
 
 MALLOC_DEFINE(M_BPF, "BPF", "BPF data");
 DEVFS_DECLARE_CLONE_BITMAP(bpf);
+#define BPF_PREALLOCATED_UNITS 4
 
 #if NBPF > 0
 
@@ -366,7 +367,10 @@ bpfclose(struct dev_close_args *ap)
        crit_exit();
        bpf_freed(d);
        dev->si_drv1 = NULL;
-       devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(bpf), dev->si_uminor);
+       if (dev->si_uminor >= BPF_PREALLOCATED_UNITS) {
+               devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(bpf), dev->si_uminor);
+               destroy_dev(dev);
+       }
        kfree(d, M_BPF);
        return(0);
 }
@@ -1504,14 +1508,23 @@ bpf_setdlt(struct bpf_d *d, u_int dlt)
 static void
 bpf_drvinit(void *unused)
 {
-       make_dev(&bpf_ops, 0, 0, 0, 0600, "bpf");
+       int i;
+
        devfs_clone_bitmap_init(&DEVFS_CLONE_BITMAP(bpf));
+
+       for (i = 0; i < BPF_PREALLOCATED_UNITS; i++) {
+               make_dev(&bpf_ops, i, 0, 0, 0600, "bpf%d", i);
+               devfs_clone_bitmap_set(&DEVFS_CLONE_BITMAP(bpf), i);
+       }
+
+       make_dev(&bpf_ops, 0, 0, 0, 0600, "bpf");
        devfs_clone_handler_add("bpf", bpfclone);
 }
 
 static void
 bpf_drvuninit(void *unused)
 {
+       devfs_clone_handler_del("bpf");
        dev_ops_remove_all(&bpf_ops);
        devfs_clone_bitmap_uninit(&DEVFS_CLONE_BITMAP(bpf));
 }
index 1d03033..1e49439 100644 (file)
@@ -67,6 +67,7 @@
 #include <net/if_arp.h>
 #include <net/if_clone.h>
 #include <net/route.h>
+#include <vfs/devfs/devfs.h>
 
 #include <netinet/in.h>
 
 #define VMNET          "vmnet"
 #define VMNET_DEV_MASK 0x00010000
 
+DEVFS_DECLARE_CLONE_BITMAP(tap);
+
 /* module */
 static int             tapmodevent     (module_t, int, void *);
 
 /* device */
-static void            tapcreate       (cdev_t);
+static cdev_t          tapcreate(int);
 static void            tapdestroy(struct tap_softc *);
 
 /* clone */
@@ -105,6 +108,7 @@ static void         tapifflags(struct tap_softc *);
 
 /* character device */
 static d_open_t                tapopen;
+static d_clone_t       tapclone;
 static d_close_t       tapclose;
 static d_read_t                tapread;
 static d_write_t       tapwrite;
@@ -165,7 +169,9 @@ tapmodevent(module_t mod, int type, void *data)
                if (attached)
                        return (EEXIST);
 
-               dev_ops_add(&tap_ops, 0, 0);
+               make_dev(&tap_ops, 0, 0, 0, 0600, "tap");
+               devfs_clone_bitmap_init(&DEVFS_CLONE_BITMAP(tap));
+               devfs_clone_handler_add("tap", tapclone);
                SLIST_INIT(&tap_listhead);
                if_clone_attach(&tap_cloner);
 
@@ -177,13 +183,16 @@ tapmodevent(module_t mod, int type, void *data)
                        return (EBUSY);
 
                if_clone_detach(&tap_cloner);
-               dev_ops_remove_all(&tap_ops);
 
                /* Maintain tap ifs in a local list */
                SLIST_FOREACH_MUTABLE(tp, &tap_listhead, tap_link, ntp)
                        tapdestroy(tp);
 
                attached = 0;
+
+               devfs_clone_handler_del("tap");
+               dev_ops_remove_all(&tap_ops);
+               devfs_clone_bitmap_uninit(&DEVFS_CLONE_BITMAP(tap));
                break;
 
        default:
@@ -199,18 +208,19 @@ tapmodevent(module_t mod, int type, void *data)
  *
  * to create interface
  */
-static void
-tapcreate(cdev_t dev)
+static cdev_t
+tapcreate(int unit)
 {
+       cdev_t          dev = NULL;
        struct ifnet            *ifp = NULL;
        struct tap_softc        *tp = NULL;
        uint8_t                 ether_addr[ETHER_ADDR_LEN];
-       int                      unit;
        char                    *name = NULL;
 
        /* allocate driver storage and create device */
        MALLOC(tp, struct tap_softc *, sizeof(*tp), M_TAP, M_WAITOK | M_ZERO);
-
+#if 0
+       /* XXX: fix lminor(dev) and so on, and unit,.... */
        /* select device: tap or vmnet */
        if (minor(dev) & VMNET_DEV_MASK) {
                name = VMNET;
@@ -218,9 +228,12 @@ tapcreate(cdev_t dev)
                tp->tap_flags |= TAP_VMNET;
        }
        else {
+#endif
                name = TAP;
+#if 0
                unit = lminor(dev);
        }
+#endif
 
        tp->tap_dev = make_dev(&tap_ops, minor(dev), UID_ROOT, GID_WHEEL, 
                                                0600, "%s%d", name, unit);
@@ -257,6 +270,7 @@ tapcreate(cdev_t dev)
        SLIST_INSERT_HEAD(&tap_listhead, tp, tap_link);
 
        TAPDEBUG(ifp, "created. minor = %#x\n", minor(tp->tap_dev));
+       return dev;
 } /* tapcreate */
 
 /*
@@ -269,9 +283,10 @@ tap_clone_create(struct if_clone *ifc __unused, int unit)
 {
        struct tap_softc *tp = NULL;
        cdev_t dev;
-
+#if 0
        dev = get_dev(CDEV_MAJOR, unit);
-       tapcreate(dev);
+#endif
+       dev = tapcreate(unit);
 
        tp = dev->si_drv1;
        tp->tap_flags |= TAP_CLONE;
@@ -302,7 +317,9 @@ tapopen(struct dev_open_args *ap)
        dev = ap->a_head.a_dev;
        tp = dev->si_drv1;
        if (tp == NULL) {
+#if 0
                tapcreate(dev);
+#endif
                tp = dev->si_drv1;
                ifp = &tp->arpcom.ac_if;
        } else {
@@ -346,6 +363,15 @@ tapopen(struct dev_open_args *ap)
        return (0);
 }
 
+static int
+tapclone(struct dev_clone_args *ap)
+{
+       int unit;
+
+       unit = devfs_clone_bitmap_get(&DEVFS_CLONE_BITMAP(tap), 0);
+       ap->a_dev = tapcreate(unit);
+       return (0);
+}
 
 /*
  * tapclose
index 0d9012f..a991a68 100644 (file)
@@ -48,6 +48,7 @@
 #include <net/ifq_var.h>
 #include <net/netisr.h>
 #include <net/route.h>
+#include <vfs/devfs/devfs.h>
 
 #ifdef INET
 #include <netinet/in.h>
@@ -82,6 +83,10 @@ static       d_write_t       tunwrite;
 static d_ioctl_t       tunioctl;
 static d_poll_t        tunpoll;
 
+static d_clone_t tunclone;
+DEVFS_DECLARE_CLONE_BITMAP(tun);
+#define TUN_PREALLOCATED_UNITS 4
+
 #define CDEV_MAJOR 52
 static struct dev_ops tun_ops = {
        { "tun", CDEV_MAJOR, 0 },
@@ -96,7 +101,29 @@ static struct dev_ops tun_ops = {
 static void
 tunattach(void *dummy)
 {
-       dev_ops_add(&tun_ops, 0, 0);
+       int i;
+       devfs_clone_bitmap_init(&DEVFS_CLONE_BITMAP(tun));
+
+       for (i = 0; i < TUN_PREALLOCATED_UNITS; i++) {
+               make_dev(&tun_ops, i, UID_UUCP, GID_DIALER, 0600, "tun%d", i);
+               devfs_clone_bitmap_set(&DEVFS_CLONE_BITMAP(tun), i);
+       }
+
+       make_dev(&tun_ops, 0, UID_UUCP, GID_DIALER, 0600, "tun");
+       devfs_clone_handler_add("tun", tunclone);
+       /* Doesn't need uninit because unloading is not possible, see PSEUDO_SET */
+}
+
+static int
+tunclone(struct dev_clone_args *ap)
+{
+       int unit;
+
+       unit = devfs_clone_bitmap_get(&DEVFS_CLONE_BITMAP(tun), 0);
+       ap->a_dev = make_only_dev(&tun_ops, unit, UID_UUCP, GID_DIALER, 0600,
+                                                               "tun%d", unit);
+
+       return 0;
 }
 
 static void
@@ -105,8 +132,10 @@ tuncreate(cdev_t dev)
        struct tun_softc *sc;
        struct ifnet *ifp;
 
+#if 0
        dev = make_dev(&tun_ops, minor(dev),
            UID_UUCP, GID_DIALER, 0600, "tun%d", lminor(dev));
+#endif
 
        MALLOC(sc, struct tun_softc *, sizeof(*sc), M_TUN, M_WAITOK | M_ZERO);
        sc->tun_flags = TUN_INITED;
@@ -185,6 +214,11 @@ tunclose(struct dev_close_args *ap)
        selwakeup(&tp->tun_rsel);
 
        TUNDEBUG(ifp, "closed\n");
+#if 0
+       if (dev->si_uminor >= TUN_PREALLOCATED_UNITS) {
+               devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(tun), dev->si_uminor);
+       }
+#endif
        return (0);
 }
 
index de84334..83b8a42 100644 (file)
@@ -49,7 +49,7 @@
 #include <sys/uio.h>
 #include <sys/vnode.h>
 #include <sys/thread2.h>
-
+#include <vfs/devfs/devfs.h>
 #include <net/if.h>
 
 #include "smb.h"
@@ -69,6 +69,8 @@ static d_read_t        nsmb_dev_read;
 static d_write_t nsmb_dev_write;
 static d_ioctl_t nsmb_dev_ioctl;
 static d_poll_t         nsmb_dev_poll;
+static d_clone_t nsmbclone;
+DEVFS_DECLARE_CLONE_BITMAP(nsmb);
 
 MODULE_VERSION(netsmb, NSMB_VERSION);
 
@@ -115,11 +117,13 @@ nsmb_dev_open(struct dev_open_args *ap)
         * XXX: this is just crazy - make a device for an already passed
         * device...  someone should take care of it.
         */
+#if 0
        if ((dev->si_flags & SI_NAMED) == 0) {
                make_dev(&nsmb_ops, minor(dev),
                        ap->a_cred->cr_uid, ap->a_cred->cr_gid,
                        0700, NSMB_NAME"%d", lminor(dev));
        }
+#endif
        bzero(sdp, sizeof(*sdp));
 /*
        STAILQ_INIT(&sdp->sd_rqlist);
@@ -162,6 +166,8 @@ nsmb_dev_close(struct dev_close_args *ap)
        dev->si_drv1 = NULL;
        kfree(sdp, M_NSMBDEV);
        crit_exit();
+       devfs_clone_bitmap_put(&DEVFS_CLONE_BITMAP(nsmb), dev->si_uminor);
+       destroy_dev(dev);
        return 0;
 }
 
@@ -330,6 +336,18 @@ nsmb_dev_poll(struct dev_poll_args *ap)
        return ENODEV;
 }
 
+static int
+nsmbclone(struct dev_clone_args *ap)
+{
+       int unit;
+
+       unit = devfs_clone_bitmap_get(&DEVFS_CLONE_BITMAP(nsmb), 0);
+       ap->a_dev = make_only_dev(&nsmb_ops, unit, 0, 0, 0600,
+                                 NSMB_NAME"%d", unit);
+
+       return 0;
+}
+
 static int
 nsmb_dev_load(module_t mod, int cmd, void *arg)
 {
@@ -345,14 +363,20 @@ nsmb_dev_load(module_t mod, int cmd, void *arg)
                        smb_sm_done();
                        break;
                }
-               dev_ops_add(&nsmb_ops, 0, 0);
+
+               make_dev(&nsmb_ops, 0, 0, 0, 0700, NSMB_NAME);
+               devfs_clone_bitmap_init(&DEVFS_CLONE_BITMAP(nsmb));
+               devfs_clone_handler_add(NSMB_NAME, nsmbclone);
+
                kprintf("netsmb_dev: loaded\n");
                break;
            case MOD_UNLOAD:
                smb_iod_done();
                error = smb_sm_done();
                error = 0;
+               devfs_clone_handler_del(NSMB_NAME);
                dev_ops_remove_all(&nsmb_ops);
+               devfs_clone_bitmap_uninit(&DEVFS_CLONE_BITMAP(nsmb));
                kprintf("netsmb_dev: unloaded\n");
                break;
            default:
index 082a50d..9c1799c 100644 (file)
@@ -759,7 +759,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_umajor, devvp->v_uminor) > 0)
+       if (vcount(devvp) > 0)
                return (EBUSY);
        if ((error = vinvalbuf(devvp, V_SAVE, 0, 0)) != 0)
                return (error);
index 79d6f0e..395c460 100644 (file)
@@ -112,9 +112,6 @@ static int filt_ext2write (struct knote *kn, long hint);
 static int filt_ext2vnode (struct knote *kn, long hint);
 static void filt_ext2detach (struct knote *kn);
 static int ext2_kqfilter (struct vop_kqfilter_args *ap);
-static int ext2spec_close (struct vop_close_args *);
-static int ext2spec_read (struct vop_read_args *);
-static int ext2spec_write (struct vop_write_args *);
 static int ext2fifo_close (struct vop_close_args *);
 static int ext2fifo_kqfilter (struct vop_kqfilter_args *);
 static int ext2fifo_read (struct vop_read_args *);
@@ -1815,74 +1812,6 @@ ext2_print(struct vop_print_args *ap)
        return (0);
 }
 
-/*
- * Read wrapper for special devices.
- *
- * ext2spec_read(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
- *             struct ucred *a_cred)
- */
-static
-int
-ext2spec_read(struct vop_read_args *ap)
-{
-       int error, resid;
-       struct inode *ip;
-       struct uio *uio;
-
-       uio = ap->a_uio;
-       resid = uio->uio_resid;
-       error = VOCALL(&spec_vnode_vops, &ap->a_head);
-       /*
-        * The inode may have been revoked during the call, so it must not
-        * be accessed blindly here or in the other wrapper functions.
-        */
-       ip = VTOI(ap->a_vp);
-       if (ip != NULL && (uio->uio_resid != resid || (error == 0 && resid != 0)))
-               ip->i_flag |= IN_ACCESS;
-       return (error);
-}
-
-/*
- * Write wrapper for special devices.
- *
- * ext2spec_write(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
- *              struct ucred *a_cred)
- */
-static
-int
-ext2spec_write(struct vop_write_args *ap)
-{
-       int error, resid;
-       struct inode *ip;
-       struct uio *uio;
-
-       uio = ap->a_uio;
-       resid = uio->uio_resid;
-       error = VOCALL(&spec_vnode_vops, &ap->a_head);
-       ip = VTOI(ap->a_vp);
-       if (ip != NULL && (uio->uio_resid != resid || (error == 0 && resid != 0)))
-               VTOI(ap->a_vp)->i_flag |= IN_CHANGE | IN_UPDATE;
-       return (error);
-}
-
-/*
- * Close wrapper for special devices.
- *
- * Update the times on the inode then do device close.
- *
- * ext2spec_close(struct vnode *a_vp, int a_fflag, struct ucred *a_cred)
- */
-static 
-int
-ext2spec_close(struct vop_close_args *ap)
-{
-       struct vnode *vp = ap->a_vp;
-
-       if (vp->v_sysref.refcnt > 1)
-               ext2_itimes(vp);
-       return (VOCALL(&spec_vnode_vops, &ap->a_head));
-}
-
 /*
  * Read wrapper for fifos.
  *
@@ -2202,17 +2131,17 @@ struct vop_ops ext2_vnode_vops = {
 };
 
 struct vop_ops ext2_spec_vops = {
-       .vop_default =          ext2_vnoperatespec,
+       .vop_default =          vop_defaultop,
        .vop_fsync =            ext2_fsync,
        .vop_access =           ext2_access,
-       .vop_close =            ext2spec_close,
+       .vop_close =            ext2_close,
        .vop_getattr =          ext2_getattr,
        .vop_inactive =         ext2_inactive,
        .vop_print =            ext2_print,
-       .vop_read =             ext2spec_read,
+       .vop_read =             vop_stdnoread,
        .vop_reclaim =          ext2_reclaim,
        .vop_setattr =          ext2_setattr,
-       .vop_write =            ext2spec_write
+       .vop_write =            vop_stdnowrite
 };
 
 struct vop_ops ext2_fifo_vops = {
@@ -2252,12 +2181,3 @@ ext2_vnoperatefifo(struct vop_generic_args *ap)
        return (VOCALL(&ext2_fifo_vops, ap));
 }
 
-/*
- * ext2_vnoperatespec()
- */
-int
-ext2_vnoperatespec(struct vop_generic_args *ap)
-{
-       return (VOCALL(&ext2_spec_vops, ap));
-}
-
index c3ee98b..927d342 100644 (file)
@@ -357,10 +357,8 @@ hammer_setup_device(struct vnode **devvpp, const char *dev_path, int ronly)
                        error = vfs_mountedon(*devvpp);
                }
        }
-       if (error == 0 &&
-           count_udev((*devvpp)->v_umajor, (*devvpp)->v_uminor) > 0) {
+       if (error == 0 && vcount(*devvpp) > 0)
                error = EBUSY;
-       }
        if (error == 0) {
                vn_lock(*devvpp, LK_EXCLUSIVE | LK_RETRY);
                error = vinvalbuf(*devvpp, V_SAVE, 0, 0);
index a158108..0a84669 100644 (file)
@@ -149,10 +149,8 @@ hammer_install_volume(struct hammer_mount *hmp, const char *volname,
                        error = vfs_mountedon(volume->devvp);
                }
        }
-       if (error == 0 &&
-           count_udev(volume->devvp->v_umajor, volume->devvp->v_uminor) > 0) {
+       if (error == 0 && vcount(volume->devvp) > 0)
                error = EBUSY;
-       }
        if (error == 0) {
                vn_lock(volume->devvp, LK_EXCLUSIVE | LK_RETRY);
                error = vinvalbuf(volume->devvp, V_SAVE, 0, 0);
index a6b92ba..7dfb04e 100644 (file)
@@ -88,11 +88,6 @@ static int hammer_vop_fiforead (struct vop_read_args *);
 static int hammer_vop_fifowrite (struct vop_write_args *);
 static int hammer_vop_fifokqfilter (struct vop_kqfilter_args *);
 
-static int hammer_vop_specclose (struct vop_close_args *);
-static int hammer_vop_specread (struct vop_read_args *);
-static int hammer_vop_specwrite (struct vop_write_args *);
-static int hammer_vop_specgetattr (struct vop_getattr_args *);
-
 struct vop_ops hammer_vnode_vops = {
        .vop_default =          vop_defaultop,
        .vop_fsync =            hammer_vop_fsync,
@@ -132,14 +127,14 @@ struct vop_ops hammer_vnode_vops = {
 };
 
 struct vop_ops hammer_spec_vops = {
-       .vop_default =          spec_vnoperate,
+       .vop_default =          vop_defaultop,
        .vop_fsync =            hammer_vop_fsync,
-       .vop_read =             hammer_vop_specread,
-       .vop_write =            hammer_vop_specwrite,
+       .vop_read =             vop_stdnoread,
+       .vop_write =            vop_stdnowrite,
        .vop_access =           hammer_vop_access,
-       .vop_close =            hammer_vop_specclose,
+       .vop_close =            hammer_vop_close,
        .vop_markatime =        hammer_vop_markatime,
-       .vop_getattr =          hammer_vop_specgetattr,
+       .vop_getattr =          hammer_vop_getattr,
        .vop_inactive =         hammer_vop_inactive,
        .vop_reclaim =          hammer_vop_reclaim,
        .vop_setattr =          hammer_vop_setattr
@@ -3044,44 +3039,6 @@ hammer_vop_fifokqfilter(struct vop_kqfilter_args *ap)
        return(error);
 }
 
-static int
-hammer_vop_specclose (struct vop_close_args *ap)
-{
-       /* XXX update itimes */
-       return (VOCALL(&spec_vnode_vops, &ap->a_head));
-}
-
-static int
-hammer_vop_specread (struct vop_read_args *ap)
-{
-       /* XXX update access time */
-       return (VOCALL(&spec_vnode_vops, &ap->a_head));
-}
-
-static int
-hammer_vop_specwrite (struct vop_write_args *ap)
-{
-       /* XXX update last change time */
-       return (VOCALL(&spec_vnode_vops, &ap->a_head));
-}
-
-/*
- * SPECFS's getattr will override fields as necessary, but does not fill
- *          stuff in from scratch.
- */
-static
-int
-hammer_vop_specgetattr (struct vop_getattr_args *ap)
-{
-       int error;
-
-       error = hammer_vop_getattr(ap);
-       if (error == 0)
-               VOCALL(&spec_vnode_vops, &ap->a_head);
-       return (error);
-}
-
-
 /************************************************************************
  *                         KQFILTER OPS                                *
  ************************************************************************
index 87b7ea3..a262791 100644 (file)
@@ -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_umajor, devvp->v_uminor);
+       ncount = vcount(devvp);
        if (devvp->v_object)
                ncount -= 1;
        if (ncount > 0)
index 6a4fe12..79de7ad 100644 (file)
@@ -292,7 +292,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_umajor, devvp->v_uminor) > 0)
+       if (vcount(devvp) > 0)
                return EBUSY;
        if ((error = vinvalbuf(devvp, V_SAVE, 0, 0)))
                return (error);
index bc8bca6..fdf6b02 100644 (file)
@@ -872,7 +872,8 @@ struct vop_ops cd9660_vnode_vops = {
  * Special device vnode ops
  */
 struct vop_ops cd9660_spec_vops = {
-       .vop_default =          spec_vnoperate,
+       .vop_default =          vop_defaultop,
+       .vop_read =             vop_stdnoread,
        .vop_access =           cd9660_access,
        .vop_getattr =          cd9660_getattr,
        .vop_inactive =         cd9660_inactive,
index ebf9219..62935e8 100644 (file)
@@ -68,7 +68,6 @@ static int    mfs_open (struct vop_open_args *);
 static int     mfs_reclaim (struct vop_reclaim_args *); /* XXX */
 static int     mfs_print (struct vop_print_args *); /* XXX */
 static int     mfs_strategy (struct vop_strategy_args *); /* XXX */
-static int     mfs_getpages (struct vop_getpages_args *); /* XXX */
 /*
  * mfs vnode operations.  Note: the vops here are used for the MFS block
  * device, not for operations on files (MFS calls the ffs mount code for that)
@@ -79,7 +78,6 @@ static struct vop_ops mfs_vnode_vops = {
        .vop_close =            mfs_close,
        .vop_freeblks =         mfs_freeblks,
        .vop_fsync =            mfs_fsync,
-       .vop_getpages =         mfs_getpages,
        .vop_inactive =         mfs_inactive,
        .vop_ioctl =            (void *)vop_enotty,
        .vop_open =             mfs_open,
@@ -111,19 +109,19 @@ static int
 mfs_open(struct vop_open_args *ap)
 {
        struct vnode *vp = ap->a_vp;
+       struct mfsnode *mfsp = VTOMFS(vp);
 
        if (vp->v_type != VCHR)
                panic("mfs_open not VCHR");
-
-       vp->v_rdev = NULL;
-       //v_associate_rdev(vp, get_dev(vp->v_umajor, vp->v_uminor));
+       if (vp->v_rdev == NULL)
+               v_associate_rdev(vp, mfsp->mfs_dev);
        return (vop_stdopen(ap));
 }
 
 static int
 mfs_fsync(struct vop_fsync_args *ap)
 {
-       return (VOCALL(&spec_vnode_vops, &ap->a_head));
+       return (0);
 }
 
 /*
@@ -436,8 +434,3 @@ mfs_badop(struct vop_generic_args *ap)
        return (i);
 }
 
-static int
-mfs_getpages(struct vop_getpages_args *ap)
-{
-       return (VOCALL(&spec_vnode_vops, &ap->a_head));
-}
index 58e21e8..39dd119 100644 (file)
@@ -314,7 +314,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_umajor, devvp->v_uminor) > 0)
+       if (vcount(devvp) > 0)
                return (EBUSY);
        vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
        error = vinvalbuf(devvp, V_SAVE, 0, 0);
index 02421b2..5c01b29 100644 (file)
 #define        TRUE    1
 #define        FALSE   0
 
-static int     nfsspec_read (struct vop_read_args *);
-static int     nfsspec_write (struct vop_write_args *);
 static int     nfsfifo_read (struct vop_read_args *);
 static int     nfsfifo_write (struct vop_write_args *);
-static int     nfsspec_close (struct vop_close_args *);
 static int     nfsfifo_close (struct vop_close_args *);
 #define nfs_poll vop_nopoll
 static int     nfs_setattrrpc (struct vnode *,struct vattr *,struct ucred *,struct thread *);
@@ -125,7 +122,7 @@ static      int     nfs_strategy (struct vop_strategy_args *);
 static int     nfs_lookitup (struct vnode *, const char *, int,
                        struct ucred *, struct thread *, struct nfsnode **);
 static int     nfs_sillyrename (struct vnode *,struct vnode *,struct componentname *);
-static int     nfsspec_access (struct vop_access_args *);
+static int     nfs_laccess (struct vop_access_args *);
 static int     nfs_readlink (struct vop_readlink_args *);
 static int     nfs_print (struct vop_print_args *);
 static int     nfs_advlock (struct vop_advlock_args *);
@@ -172,22 +169,22 @@ struct vop_ops nfsv2_vnode_vops = {
  * Special device vnode ops
  */
 struct vop_ops nfsv2_spec_vops = {
-       .vop_default =          spec_vnoperate,
-       .vop_access =           nfsspec_access,
-       .vop_close =            nfsspec_close,
+       .vop_default =          vop_defaultop,
+       .vop_access =           nfs_laccess,
+       .vop_close =            nfs_close,
        .vop_fsync =            nfs_fsync,
        .vop_getattr =          nfs_getattr,
        .vop_inactive =         nfs_inactive,
        .vop_print =            nfs_print,
-       .vop_read =             nfsspec_read,
+       .vop_read =             vop_stdnoread,
        .vop_reclaim =          nfs_reclaim,
        .vop_setattr =          nfs_setattr,
-       .vop_write =            nfsspec_write
+       .vop_write =            vop_stdnowrite
 };
 
 struct vop_ops nfsv2_fifo_vops = {
        .vop_default =          fifo_vnoperate,
-       .vop_access =           nfsspec_access,
+       .vop_access =           nfs_laccess,
        .vop_close =            nfsfifo_close,
        .vop_fsync =            nfs_fsync,
        .vop_getattr =          nfs_getattr,
@@ -372,14 +369,14 @@ nfs_access(struct vop_access_args *ap)
                        }
                }
        } else {
-               if ((error = nfsspec_access(ap)) != 0)
+               if ((error = nfs_laccess(ap)) != 0)
                        return (error);
 
                /*
                 * Attempt to prevent a mapped root from accessing a file
                 * which it shouldn't.  We try to read a byte from the file
                 * if the user is root and the file is not zero length.
-                * After calling nfsspec_access, we should have the correct
+                * After calling nfs_laccess, we should have the correct
                 * file size cached.
                 */
                if (ap->a_cred->cr_uid == 0 && (ap->a_mode & VREAD)
@@ -3337,10 +3334,10 @@ nfs_print(struct vop_print_args *ap)
  * Essentially just get vattr and then imitate iaccess() since the device is
  * local to the client.
  *
- * nfsspec_access(struct vnode *a_vp, int a_mode, struct ucred *a_cred)
+ * nfs_laccess(struct vnode *a_vp, int a_mode, struct ucred *a_cred)
  */
 static int
-nfsspec_access(struct vop_access_args *ap)
+nfs_laccess(struct vop_access_args *ap)
 {
        struct vattr *vap;
        gid_t *gp;
@@ -3395,73 +3392,6 @@ found:
        return (error);
 }
 
-/*
- * Read wrapper for special devices.
- *
- * nfsspec_read(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
- *             struct ucred *a_cred)
- */
-static int
-nfsspec_read(struct vop_read_args *ap)
-{
-       struct nfsnode *np = VTONFS(ap->a_vp);
-
-       /*
-        * Set access flag.
-        */
-       np->n_flag |= NACC;
-       getnanotime(&np->n_atim);
-       return (VOCALL(&spec_vnode_vops, &ap->a_head));
-}
-
-/*
- * Write wrapper for special devices.
- *
- * nfsspec_write(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
- *              struct ucred *a_cred)
- */
-static int
-nfsspec_write(struct vop_write_args *ap)
-{
-       struct nfsnode *np = VTONFS(ap->a_vp);
-
-       /*
-        * Set update flag.
-        */
-       np->n_flag |= NUPD;
-       getnanotime(&np->n_mtim);
-       return (VOCALL(&spec_vnode_vops, &ap->a_head));
-}
-
-/*
- * Close wrapper for special devices.
- *
- * Update the times on the nfsnode then do device close.
- *
- * nfsspec_close(struct vnode *a_vp, int a_fflag)
- */
-static int
-nfsspec_close(struct vop_close_args *ap)
-{
-       struct vnode *vp = ap->a_vp;
-       struct nfsnode *np = VTONFS(vp);
-       struct vattr vattr;
-
-       if (np->n_flag & (NACC | NUPD)) {
-               np->n_flag |= NCHG;
-               if (vp->v_sysref.refcnt == 1 &&
-                   (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
-                       VATTR_NULL(&vattr);
-                       if (np->n_flag & NACC)
-                               vattr.va_atime = np->n_atim;
-                       if (np->n_flag & NUPD)
-                               vattr.va_mtime = np->n_mtim;
-                       (void)VOP_SETATTR(vp, &vattr, nfs_vpcred(vp, ND_WRITE));
-               }
-       }
-       return (VOCALL(&spec_vnode_vops, &ap->a_head));
-}
-
 /*
  * Read wrapper for fifos.
  *
index 259c651..17fd2e8 100644 (file)
@@ -407,7 +407,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_umajor, devvp->v_uminor);
+       ncount = vcount(devvp);
 #if defined(__DragonFly__)
        if (devvp->v_object)
                ncount -= 1;
index b6e195b..ebe6b2b 100644 (file)
@@ -246,7 +246,7 @@ udf_mountfs(struct vnode *devvp, struct mount *mp)
         */
        if ((error = vfs_mountedon(devvp)))
                return(error);
-       if (count_udev(devvp->v_umajor, devvp->v_uminor) > 0)
+       if (vcount(devvp) > 0)
                return(EBUSY);
        if ((error = vinvalbuf(devvp, V_SAVE, 0, 0)))
                return(error);
index d1072c8..964d1bb 100644 (file)
@@ -615,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_umajor, devvp->v_uminor) > 0)
+       if (vcount(devvp) > 0)
                return (EBUSY);
        vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
        error = vinvalbuf(devvp, V_SAVE, 0, 0);
index 58d94ff..7cfcc66 100644 (file)
@@ -108,10 +108,6 @@ static int ufsfifo_close (struct vop_close_args *);
 static int ufsfifo_kqfilter (struct vop_kqfilter_args *);
 static int ufsfifo_read (struct vop_read_args *);
 static int ufsfifo_write (struct vop_write_args *);
-static int ufsspec_close (struct vop_close_args *);
-static int ufsspec_read (struct vop_read_args *);
-static int ufsspec_write (struct vop_write_args *);
-static int ufsspec_getattr (struct vop_getattr_args *);
 static int filt_ufsread (struct knote *kn, long hint);
 static int filt_ufswrite (struct knote *kn, long hint);
 static int filt_ufsvnode (struct knote *kn, long hint);
@@ -1894,90 +1890,6 @@ ufs_print(struct vop_print_args *ap)
        return (0);
 }
 
-/*
- * Read wrapper for special devices.
- *
- * ufsspec_read(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
- *             struct ucred *a_cred)
- */
-static
-int
-ufsspec_read(struct vop_read_args *ap)
-{
-       int error, resid;
-       struct inode *ip;
-       struct uio *uio;
-
-       uio = ap->a_uio;
-       resid = uio->uio_resid;
-       error = VOCALL(&spec_vnode_vops, &ap->a_head);
-       /*
-        * The inode may have been revoked during the call, so it must not
-        * be accessed blindly here or in the other wrapper functions.
-        */
-       ip = VTOI(ap->a_vp);
-       if (ip != NULL && (uio->uio_resid != resid || (error == 0 && resid != 0)))
-               ip->i_flag |= IN_ACCESS;
-       return (error);
-}
-
-/*
- * Write wrapper for special devices.
- *
- * ufsspec_write(struct vnode *a_vp, struct uio *a_uio, int a_ioflag,
- *              struct ucred *a_cred)
- */
-static
-int
-ufsspec_write(struct vop_write_args *ap)
-{
-       int error, resid;
-       struct inode *ip;
-       struct uio *uio;
-
-       uio = ap->a_uio;
-       resid = uio->uio_resid;
-       error = VOCALL(&spec_vnode_vops, &ap->a_head);
-       ip = VTOI(ap->a_vp);
-       if (ip != NULL && (uio->uio_resid != resid || (error == 0 && resid != 0)))
-               VTOI(ap->a_vp)->i_flag |= IN_CHANGE | IN_UPDATE;
-       return (error);
-}
-
-/*
- * SPECFS's getattr will override fields as necessary, but does not fill
- *         stuff in from scratch.
- */
-static
-int
-ufsspec_getattr (struct vop_getattr_args *ap)
-{
-       int error;
-
-       error = ufs_getattr(ap);
-       if (error == 0)
-               VOCALL(&spec_vnode_vops, &ap->a_head);
-       return (error);
-}
-
-/*
- * Close wrapper for special devices.
- *
- * Update the times on the inode then do device close.
- *
- * ufsspec_close(struct vnode *a_vp, int a_fflag)
- */
-static 
-int
-ufsspec_close(struct vop_close_args *ap)
-{
-       struct vnode *vp = ap->a_vp;
-
-       if (vp->v_sysref.refcnt > 1)
-               ufs_itimes(vp);
-       return (VOCALL(&spec_vnode_vops, &ap->a_head));
-}
-
 /*
  * Read wrapper for fifos.
  *
@@ -2402,18 +2314,18 @@ static struct vop_ops ufs_vnode_vops = {
 };
 
 static struct vop_ops ufs_spec_vops = {
-       .vop_default =          spec_vnoperate,
+       .vop_default =          vop_defaultop,
        .vop_fsync =            (void *)ufs_missingop,
        .vop_access =           ufs_access,
-       .vop_close =            ufsspec_close,
-       .vop_getattr =          ufsspec_getattr,
+       .vop_close =            ufs_close,
+       .vop_getattr =          ufs_getattr,
        .vop_inactive =         ufs_inactive,
        .vop_print =            ufs_print,
-       .vop_read =             ufsspec_read,
+       .vop_read =             vop_stdnoread,
        .vop_reclaim =          ufs_reclaim,
        .vop_setattr =          ufs_setattr,
        .vop_markatime =        ufs_markatime,
-       .vop_write =            ufsspec_write
+       .vop_write =            vop_stdnowrite
 };
 
 static struct vop_ops ufs_fifo_vops = {