/* ARGSUSED */ static int objfs_init(int fstype, char *name) { vfsops_t *vfsops; int error; objfs_fstype = fstype; if (error = vfs_setfsops(fstype, objfs_vfstops, &vfsops)) { cmn_err(CE_WARN, "objfs_init: bad vfs ops template"); return (error); } if (error = gfs_make_opsvec(objfs_opsvec)) { (void) vfs_freevfsops(vfsops); return (error); } if ((objfs_major = getudev()) == (major_t)-1) { cmn_err(CE_WARN, "objfs_init: can't get unique device number"); objfs_major = 0; } objfs_data_init(); return (0); }
int VMBlockInit(int fstype, // IN: file system type char *name) // IN: Name of the file system { int ret; static const fs_operation_def_t vfsOpsArr[] = { VMBLOCK_VOP(VFSNAME_MOUNT, vfs_mount, VMBlockMount), VMBLOCK_VOP(VFSNAME_UNMOUNT, vfs_unmount, VMBlockUnmount), VMBLOCK_VOP(VFSNAME_ROOT, vfs_root, VMBlockRoot), VMBLOCK_VOP(VFSNAME_STATVFS, vfs_statvfs, VMBlockStatvfs), { NULL } }; if (!name) { Warning("VMBlockInit: received NULL input from kernel.\n"); return EINVAL; } Debug(VMBLOCK_ENTRY_LOGLEVEL, "VMBlockInit: fstype=%d, name=\"%s\"\n", fstype, name); /* * Set our file system type and the vfs operations in the kernel's VFS * switch table. */ vmblockType = fstype; ret = vfs_setfsops(vmblockType, vfsOpsArr, &vmblockVfsOps); if (ret) { Warning("VMBlockInit: could not set vfs operations.\n"); return ret; } ret = vn_make_ops(name, vnodeOpsArr, &vmblockVnodeOps); if (ret) { Warning("VMBlockInit: could not create vnode operations.\n"); /* * It's important not to call vfs_freevfsops() here; that's only for * freeing ops created with vfs_makefsops(). */ vfs_freevfsops_by_type(vmblockType); return ret; } /* * We need to find a unique device number for this instance of the module; * it will be used at each mount to secure a unique device number and file * system identifier. If one cannot be located, we'll just use zero like * other Solaris file systems. */ if ((vmblockMajor = getudev()) == (major_t)-1) { Warning("VMBlockInit: could not obtain unique device.\n"); vmblockMajor = 0; } vmblockMinor = 0; mutex_init(&vmblockMutex, NULL, MUTEX_DEFAULT, NULL); return 0; }
static int zfs_create_unique_device(dev_t *dev) { major_t new_major; do { ASSERT3U(zfs_minor, <=, MAXMIN32); minor_t start = zfs_minor; do { mutex_enter(&zfs_dev_mtx); if (zfs_minor >= MAXMIN32) { /* * If we're still using the real major * keep out of /dev/zfs and /dev/zvol minor * number space. If we're using a getudev()'ed * major number, we can use all of its minors. */ if (zfs_major == ddi_name_to_major(ZFS_DRIVER)) zfs_minor = ZFS_MIN_MINOR; else zfs_minor = 0; } else { zfs_minor++; } *dev = makedevice(zfs_major, zfs_minor); mutex_exit(&zfs_dev_mtx); } while (vfs_devismounted(*dev) && zfs_minor != start); if (zfs_minor == start) { /* * We are using all ~262,000 minor numbers for the * current major number. Create a new major number. */ if ((new_major = getudev()) == (major_t)-1) { cmn_err(CE_WARN, "zfs_mount: Can't get unique major " "device number."); return (-1); } mutex_enter(&zfs_dev_mtx); zfs_major = new_major; zfs_minor = 0; mutex_exit(&zfs_dev_mtx); } else { break; } /* CONSTANTCONDITION */ } while (1); return (0); }
iumfs_init(struct vfssw *iumfs_vfssw, int fstype) #endif { int err; DEBUG_PRINT((CE_CONT, "iumfs_init called\n")); DEBUG_PRINT((CE_CONT, "iumfs_init: fstype = %d(0x%x)\n", fstype, fstype)); iumfs_fstype = fstype; #ifdef SOL10 do { err = vfs_setfsops(fstype, iumfs_vfs_ops_def_array, &iumfs_vfsops); if (err) break; err = vn_make_ops(fsname, iumfs_vnode_ops_def_array, &iumfs_vnodeops); if (err) break; } while (FALSE); if (err) { if (iumfs_vfsops != NULL) { vfs_freevfsops_by_type(fstype); } if (iumfs_vnodeops != NULL) { vn_freevnodeops(iumfs_vnodeops); } } #endif /* * filesystem id に使うデバイス番号を決める。 */ iumfs_major = getudev(); DEBUG_PRINT((CE_CONT, "iumfs_init: major = %d(0x%x)\n", iumfs_major, iumfs_major)); DEBUG_PRINT((CE_CONT, "iumfs_init: return(%d)\n", err)); return (err); }
/*ARGSUSED*/ static int nsmb_open(dev_t *dev, int flags, int otyp, cred_t *cr) { major_t new_major; smb_dev_t *sdp, *sdv; mutex_enter(&dev_lck); for (; ; ) { minor_t start = nsmb_minor; do { if (nsmb_minor >= MAXMIN32) { if (nsmb_major == getmajor(*dev)) nsmb_minor = NSMB_MIN_MINOR; else nsmb_minor = 0; } else { nsmb_minor++; } sdv = ddi_get_soft_state(statep, nsmb_minor); } while ((sdv != NULL) && (nsmb_minor != start)); if (nsmb_minor == start) { /* * The condition we need to solve here is all the * MAXMIN32(~262000) minors numbers are reached. We * need to create a new major number. * zfs uses getudev() to create a new major number. */ if ((new_major = getudev()) == (major_t)-1) { cmn_err(CE_WARN, "nsmb: Can't get unique major " "device number."); mutex_exit(&dev_lck); return (-1); } nsmb_major = new_major; nsmb_minor = 0; } else { break; } } /* * This is called by mount or open call. * The open() routine is passed a pointer to a device number so * that the driver can change the minor number. This allows * drivers to dynamically create minor instances of the dev- * ice. An example of this might be a pseudo-terminal driver * that creates a new pseudo-terminal whenever it is opened. * A driver that chooses the minor number dynamically, normally * creates only one minor device node in attach(9E) with * ddi_create_minor_node(9F) then changes the minor number com- * ponent of *devp using makedevice(9F) and getmajor(9F) The * driver needs to keep track of available minor numbers inter- * nally. * Stuff the structure smb_dev. * return. */ if (ddi_soft_state_zalloc(statep, nsmb_minor) == DDI_FAILURE) { mutex_exit(&dev_lck); return (ENXIO); } if ((sdp = ddi_get_soft_state(statep, nsmb_minor)) == NULL) { mutex_exit(&dev_lck); return (ENXIO); } sdp->sd_seq = nsmb_minor; sdp->sd_cred = cr; sdp->sd_smbfid = -1; sdp->sd_flags |= NSMBFL_OPEN; sdp->zoneid = crgetzoneid(cr); mutex_exit(&dev_lck); *dev = makedevice(nsmb_major, nsmb_minor); return (0); }
/* * Cache initialization routine. This routine should only be called * once. It performs the following tasks: * - Initalize all global locks * - Call sub-initialization routines (localize access to variables) */ static int cachefs_init(int fstyp, char *name) { kstat_t *ksp; int error; ASSERT(cachefs_up == B_FALSE); error = cachefs_init_vfsops(fstyp); if (error != 0) return (error); error = cachefs_init_vnops(name); if (error != 0) return (error); mutex_init(&cachefs_cachelock, NULL, MUTEX_DEFAULT, NULL); mutex_init(&cachefs_newnum_lock, NULL, MUTEX_DEFAULT, NULL); mutex_init(&cachefs_kstat_key_lock, NULL, MUTEX_DEFAULT, NULL); mutex_init(&cachefs_kmem_lock, NULL, MUTEX_DEFAULT, NULL); mutex_init(&cachefs_rename_lock, NULL, MUTEX_DEFAULT, NULL); mutex_init(&cachefs_minor_lock, NULL, MUTEX_DEFAULT, NULL); mutex_init(&cachefs_async_lock, NULL, MUTEX_DEFAULT, NULL); #ifdef CFSRLDEBUG mutex_init(&cachefs_rl_debug_mutex, NULL, MUTEX_DEFAULT, NULL); #endif /* CFSRLDEBUG */ /* * set up kmem_cache entities */ cachefs_cnode_cache = kmem_cache_create("cachefs_cnode_cache", sizeof (struct cnode), 0, NULL, NULL, NULL, NULL, NULL, 0); cachefs_req_cache = kmem_cache_create("cachefs_async_request", sizeof (struct cachefs_req), 0, cachefs_req_create, cachefs_req_destroy, NULL, NULL, NULL, 0); cachefs_fscache_cache = kmem_cache_create("cachefs_fscache", sizeof (fscache_t), 0, NULL, NULL, NULL, NULL, NULL, 0); cachefs_filegrp_cache = kmem_cache_create("cachefs_filegrp", sizeof (filegrp_t), 0, filegrp_cache_create, filegrp_cache_destroy, NULL, NULL, NULL, 0); cachefs_cache_kmcache = kmem_cache_create("cachefs_cache_t", sizeof (cachefscache_t), 0, NULL, NULL, NULL, NULL, NULL, 0); /* * set up the cachefs.0.key kstat */ cachefs_kstat_key = NULL; cachefs_kstat_key_n = 0; ksp = kstat_create("cachefs", 0, "key", "misc", KSTAT_TYPE_RAW, 1, KSTAT_FLAG_VIRTUAL | KSTAT_FLAG_VAR_SIZE); if (ksp != NULL) { ksp->ks_data = &cachefs_kstat_key; ksp->ks_update = cachefs_kstat_key_update; ksp->ks_snapshot = cachefs_kstat_key_snapshot; ksp->ks_lock = &cachefs_kstat_key_lock; kstat_install(ksp); } /* * Assign unique major number for all nfs mounts */ if ((cachefs_major = getudev()) == -1) { cmn_err(CE_WARN, "cachefs: init: can't get unique device number"); cachefs_major = 0; } cachefs_up = B_TRUE; #ifdef CFSRLDEBUG cachefs_dbvalid = time; #endif /* CFSRLDEBUG */ return (0); }
/* * Save file system type/index, initialize vfs operations vector, get * unique device number for FIFOFS and initialize the FIFOFS hash. * Create and initialize a "generic" vfs pointer that will be placed * in the v_vfsp field of each pipe's vnode. */ int fifoinit(int fstype, char *name) { static const fs_operation_def_t fifo_vfsops_template[] = { NULL, NULL }; int error; major_t dev; fifofstype = fstype; error = vfs_setfsops(fstype, fifo_vfsops_template, &fifo_vfsops); if (error != 0) { cmn_err(CE_WARN, "fifoinit: bad vfs ops template"); return (error); } error = vn_make_ops(name, fifo_vnodeops_template, &fifo_vnodeops); if (error != 0) { (void) vfs_freevfsops_by_type(fstype); cmn_err(CE_WARN, "fifoinit: bad vnode ops template"); return (error); } if ((dev = getudev()) == (major_t)-1) { cmn_err(CE_WARN, "fifoinit: can't get unique device number"); dev = 0; } fifodev = makedevice(dev, 0); fifovfsp = kmem_zalloc(sizeof (struct vfs), KM_SLEEP); fifovfsp->vfs_next = NULL; vfs_setops(fifovfsp, fifo_vfsops); fifovfsp->vfs_vnodecovered = NULL; fifovfsp->vfs_flag = 0; fifovfsp->vfs_bsize = 1024; fifovfsp->vfs_fstype = fifofstype; vfs_make_fsid(&fifovfsp->vfs_fsid, fifodev, fifofstype); fifovfsp->vfs_data = NULL; fifovfsp->vfs_dev = fifodev; fifovfsp->vfs_bcount = 0; /* * It is necessary to initialize vfs_count here to 1. * This prevents the fifovfsp from getting freed when * a thread does a VFS_HOLD followed by a VFS_RELE * on the fifovfsp * * The fifovfsp should never be freed. */ fifovfsp->vfs_count = 1; mutex_init(&ftable_lock, NULL, MUTEX_DEFAULT, NULL); mutex_init(&fino_lock, NULL, MUTEX_DEFAULT, NULL); /* * vnodes are cached aligned */ fnode_cache = kmem_cache_create("fnode_cache", sizeof (fifodata_t) - sizeof (fifonode_t), 32, fnode_constructor, fnode_destructor, NULL, (void *)(sizeof (fifodata_t) - sizeof (fifonode_t)), NULL, 0); pipe_cache = kmem_cache_create("pipe_cache", sizeof (fifodata_t), 32, pipe_constructor, pipe_destructor, NULL, (void *)(sizeof (fifodata_t)), NULL, 0); #if FIFODEBUG if (Fifohiwat < FIFOHIWAT) Fifohiwat = FIFOHIWAT; #endif /* FIFODEBUG */ fifo_strdata.qi_minfo->mi_hiwat = Fifohiwat; return (0); }