예제 #1
0
/* 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);
}
예제 #2
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;
}
예제 #3
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);
}
예제 #4
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);
}
예제 #5
0
/*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);
}
예제 #6
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);
}
예제 #7
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);
}