return (PRIV_POLICY(cr, needed_priv, B_FALSE, EPERM, NULL));
return (0);
#else
- return ENOTSUP;
+ return (ENOTSUP);
#endif /* HAVE_MLSLABEL */
}
{
spa_t *spa;
int error;
- nvlist_t *config, **l2cache, **spares;
- uint_t nl2cache = 0, nspares = 0;
+ nvlist_t *config;
error = spa_open(zc->zc_name, &spa, FTAG);
if (error != 0)
error = get_nvlist(zc->zc_nvlist_conf, zc->zc_nvlist_conf_size,
zc->zc_iflags, &config);
- (void) nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_L2CACHE,
- &l2cache, &nl2cache);
-
- (void) nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_SPARES,
- &spares, &nspares);
-
- /*
- * A root pool with concatenated devices is not supported.
- * Thus, can not add a device to a root pool.
- *
- * Intent log device can not be added to a rootpool because
- * during mountroot, zil is replayed, a seperated log device
- * can not be accessed during the mountroot time.
- *
- * l2cache and spare devices are ok to be added to a rootpool.
- */
- if (spa_bootfs(spa) != 0 && nl2cache == 0 && nspares == 0) {
- nvlist_free(config);
- spa_close(spa, FTAG);
- return (SET_ERROR(EDOM));
- }
-
if (error == 0) {
error = spa_vdev_add(spa, config);
nvlist_free(config);
return (err);
}
-static boolean_t
+boolean_t
dataset_name_hidden(const char *name)
{
/*
return (error);
}
-/*
- * inputs:
- * zc_name name of volume
- *
- * outputs: none
- */
-static int
-zfs_ioc_create_minor(zfs_cmd_t *zc)
-{
- return (zvol_create_minor(zc->zc_name));
-}
-
-/*
- * inputs:
- * zc_name name of volume
- *
- * outputs: none
- */
-static int
-zfs_ioc_remove_minor(zfs_cmd_t *zc)
-{
- return (zvol_remove_minor(zc->zc_name));
-}
-
/*
* inputs:
* zc_name name of filesystem
if (error != 0)
(void) dsl_destroy_head(fsname);
}
+
+#ifdef _KERNEL
+ if (error == 0 && type == DMU_OST_ZVOL)
+ zvol_create_minors(fsname);
+#endif
+
return (error);
}
if (error != 0)
(void) dsl_destroy_head(fsname);
}
+
+#ifdef _KERNEL
+ if (error == 0)
+ zvol_create_minors(fsname);
+#endif
+
return (error);
}
}
error = dsl_dataset_snapshot(snaps, props, outnvl);
+
+#ifdef _KERNEL
+ if (error == 0)
+ zvol_create_minors(poolname);
+#endif
+
return (error);
}
(name[poollen] != '/' && name[poollen] != '@'))
return (SET_ERROR(EXDEV));
- (void) zvol_remove_minor(name);
error = zfs_unmount_snap(name);
if (error != 0)
return (error);
+ (void) zvol_remove_minor(name);
}
return (dsl_destroy_snapshots_nvl(snaps, defer, outnvl));
}
/*
- * inputs:
- * zc_name name of dataset to rollback (to most recent snapshot)
+ * fsname is name of dataset to rollback (to most recent snapshot)
*
- * outputs: none
+ * innvl is not used.
+ *
+ * outnvl: "target" -> name of most recent snapshot
+ * }
*/
+/* ARGSUSED */
static int
-zfs_ioc_rollback(zfs_cmd_t *zc)
+zfs_ioc_rollback(const char *fsname, nvlist_t *args, nvlist_t *outnvl)
{
zfs_sb_t *zsb;
int error;
- if (get_zfs_sb(zc->zc_name, &zsb) == 0) {
+ if (get_zfs_sb(fsname, &zsb) == 0) {
error = zfs_suspend_fs(zsb);
if (error == 0) {
int resume_err;
- error = dsl_dataset_rollback(zc->zc_name, zsb);
- resume_err = zfs_resume_fs(zsb, zc->zc_name);
+ error = dsl_dataset_rollback(fsname, zsb, outnvl);
+ resume_err = zfs_resume_fs(zsb, fsname);
error = error ? error : resume_err;
}
deactivate_super(zsb->z_sb);
} else {
- error = dsl_dataset_rollback(zc->zc_name, NULL);
+ error = dsl_dataset_rollback(fsname, NULL, outnvl);
}
return (error);
}
{
boolean_t recursive = zc->zc_cookie & 1;
char *at;
- int err;
zc->zc_value[sizeof (zc->zc_value) - 1] = '\0';
if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 ||
return (error);
} else {
- err = dsl_dir_rename(zc->zc_name, zc->zc_value);
- if (!err && zc->zc_objset_type == DMU_OST_ZVOL) {
- (void) zvol_remove_minor(zc->zc_name);
- (void) zvol_create_minor(zc->zc_value);
- }
- return (err);
+ return (dsl_dir_rename(zc->zc_name, zc->zc_value));
}
}
error = 1;
}
#endif
+
+#ifdef _KERNEL
+ if (error == 0)
+ zvol_create_minors(tofs);
+#endif
+
/*
* On error, restore the original props.
*/
zfs_zevent_drain_all(&count);
zc->zc_cookie = count;
- return 0;
+ return (0);
}
/*
zfs_ioc_get_holds, zfs_secpolicy_read, DATASET_NAME,
POOL_CHECK_SUSPENDED, B_FALSE, B_FALSE);
+ zfs_ioctl_register("rollback", ZFS_IOC_ROLLBACK,
+ zfs_ioc_rollback, zfs_secpolicy_rollback, DATASET_NAME,
+ POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY, B_FALSE, B_TRUE);
+
/* IOCTLS that use the legacy function signature */
zfs_ioctl_register_legacy(ZFS_IOC_POOL_FREEZE, zfs_ioc_pool_freeze,
zfs_secpolicy_config, B_TRUE, POOL_CHECK_NONE);
zfs_ioctl_register_pool(ZFS_IOC_CLEAR, zfs_ioc_clear,
- zfs_secpolicy_config, B_TRUE, POOL_CHECK_SUSPENDED);
+ zfs_secpolicy_config, B_TRUE, POOL_CHECK_NONE);
zfs_ioctl_register_pool(ZFS_IOC_POOL_REOPEN, zfs_ioc_pool_reopen,
zfs_secpolicy_config, B_TRUE, POOL_CHECK_SUSPENDED);
zfs_secpolicy_none);
zfs_ioctl_register_dataset_modify(ZFS_IOC_DESTROY, zfs_ioc_destroy,
zfs_secpolicy_destroy);
- zfs_ioctl_register_dataset_modify(ZFS_IOC_ROLLBACK, zfs_ioc_rollback,
- zfs_secpolicy_rollback);
zfs_ioctl_register_dataset_modify(ZFS_IOC_RENAME, zfs_ioc_rename,
zfs_secpolicy_rename);
zfs_ioctl_register_dataset_modify(ZFS_IOC_RECV, zfs_ioc_recv,
POOL_CHECK_SUSPENDED | POOL_CHECK_READONLY);
/*
- * ZoL functions
+ * ZoL functions
*/
- zfs_ioctl_register_legacy(ZFS_IOC_CREATE_MINOR, zfs_ioc_create_minor,
- zfs_secpolicy_config, DATASET_NAME, B_FALSE, POOL_CHECK_NONE);
- zfs_ioctl_register_legacy(ZFS_IOC_REMOVE_MINOR, zfs_ioc_remove_minor,
- zfs_secpolicy_config, DATASET_NAME, B_FALSE, POOL_CHECK_NONE);
zfs_ioctl_register_legacy(ZFS_IOC_EVENTS_NEXT, zfs_ioc_events_next,
zfs_secpolicy_config, NO_NAME, B_FALSE, POOL_CHECK_NONE);
zfs_ioctl_register_legacy(ZFS_IOC_EVENTS_CLEAR, zfs_ioc_events_clear,
ASSERT(MUTEX_HELD(&zfsdev_state_lock));
for (zs = list_head(&zfsdev_state_list); zs != NULL;
- zs = list_next(&zfsdev_state_list, zs)) {
+ zs = list_next(&zfsdev_state_list, zs)) {
if (zs->zs_minor == minor) {
switch (which) {
- case ZST_ONEXIT: return (zs->zs_onexit);
- case ZST_ZEVENT: return (zs->zs_zevent);
- case ZST_ALL: return (zs);
+ case ZST_ONEXIT:
+ return (zs->zs_onexit);
+ case ZST_ZEVENT:
+ return (zs->zs_zevent);
+ case ZST_ALL:
+ return (zs);
}
}
}
- return NULL;
+ return (NULL);
}
void *
ptr = zfsdev_get_state_impl(minor, which);
mutex_exit(&zfsdev_state_lock);
- return ptr;
+ return (ptr);
}
minor_t
ASSERT(MUTEX_HELD(&zfsdev_state_lock));
- minor = zfsdev_minor_alloc();
- if (minor == 0)
- return (SET_ERROR(ENXIO));
+ minor = zfsdev_minor_alloc();
+ if (minor == 0)
+ return (SET_ERROR(ENXIO));
- zs = kmem_zalloc( sizeof(zfsdev_state_t), KM_SLEEP);
+ zs = kmem_zalloc(sizeof (zfsdev_state_t), KM_SLEEP);
zs->zs_file = filp;
zs->zs_minor = minor;
zfs_zevent_destroy(zs->zs_zevent);
list_remove(&zfsdev_state_list, zs);
- kmem_free(zs, sizeof(zfsdev_state_t));
+ kmem_free(zs, sizeof (zfsdev_state_t));
- return 0;
+ return (0);
}
static int
uint_t vecnum;
int error, rc, len, flag = 0;
const zfs_ioc_vec_t *vec;
- char saved_poolname[MAXNAMELEN];
+ char *saved_poolname;
nvlist_t *innvl = NULL;
vecnum = cmd - ZFS_IOC_FIRST;
return (-SET_ERROR(EINVAL));
vec = &zfs_ioc_vec[vecnum];
+ /*
+ * The registered ioctl list may be sparse, verify that either
+ * a normal or legacy handler are registered.
+ */
+ if (vec->zvec_func == NULL && vec->zvec_legacy_func == NULL)
+ return (-SET_ERROR(EINVAL));
+
zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP | KM_NODEBUG);
+ saved_poolname = kmem_alloc(MAXNAMELEN, KM_SLEEP);
error = ddi_copyin((void *)arg, zc, sizeof (zfs_cmd_t), flag);
if (error != 0) {
goto out;
/* legacy ioctls can modify zc_name */
- (void) strlcpy(saved_poolname, zc->zc_name, sizeof(saved_poolname));
+ (void) strlcpy(saved_poolname, zc->zc_name, sizeof (saved_poolname));
len = strcspn(saved_poolname, "/@") + 1;
saved_poolname[len] = '\0';
(void) tsd_set(zfs_allow_log_key, strdup(saved_poolname));
}
+ kmem_free(saved_poolname, MAXNAMELEN);
kmem_free(zc, sizeof (zfs_cmd_t));
return (-error);
}
static long
zfsdev_compat_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
{
- return zfsdev_ioctl(filp, cmd, arg);
+ return (zfsdev_ioctl(filp, cmd, arg));
}
#else
-#define zfsdev_compat_ioctl NULL
+#define zfsdev_compat_ioctl NULL
#endif
static const struct file_operations zfsdev_fops = {
- .open = zfsdev_open,
- .release = zfsdev_release,
- .unlocked_ioctl = zfsdev_ioctl,
- .compat_ioctl = zfsdev_compat_ioctl,
- .owner = THIS_MODULE,
+ .open = zfsdev_open,
+ .release = zfsdev_release,
+ .unlocked_ioctl = zfsdev_ioctl,
+ .compat_ioctl = zfsdev_compat_ioctl,
+ .owner = THIS_MODULE,
};
static struct miscdevice zfs_misc = {
- .minor = MISC_DYNAMIC_MINOR,
- .name = ZFS_DRIVER,
- .fops = &zfsdev_fops,
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = ZFS_DRIVER,
+ .fops = &zfsdev_fops,
};
static int
offsetof(zfsdev_state_t, zs_next));
error = misc_register(&zfs_misc);
- if (error != 0) {
+ if (error != 0) {
printk(KERN_INFO "ZFS: misc_register() failed %d\n", error);
return (error);
}
}
#ifdef DEBUG
-#define ZFS_DEBUG_STR " (DEBUG mode)"
+#define ZFS_DEBUG_STR " (DEBUG mode)"
#else
-#define ZFS_DEBUG_STR ""
+#define ZFS_DEBUG_STR ""
#endif
int
tsd_create(&zfs_allow_log_key, zfs_allow_log_destroy);
printk(KERN_NOTICE "ZFS: Loaded module v%s-%s%s, "
- "ZFS pool version %s, ZFS filesystem version %s\n",
- ZFS_META_VERSION, ZFS_META_RELEASE, ZFS_DEBUG_STR,
- SPA_VERSION_STRING, ZPL_VERSION_STRING);
+ "ZFS pool version %s, ZFS filesystem version %s\n",
+ ZFS_META_VERSION, ZFS_META_RELEASE, ZFS_DEBUG_STR,
+ SPA_VERSION_STRING, ZPL_VERSION_STRING);
+#ifndef CONFIG_FS_POSIX_ACL
+ printk(KERN_NOTICE "ZFS: Posix ACLs disabled by kernel\n");
+#endif /* CONFIG_FS_POSIX_ACL */
return (0);
zfs_fini();
spa_fini();
printk(KERN_NOTICE "ZFS: Failed to Load ZFS Filesystem v%s-%s%s"
- ", rc = %d\n", ZFS_META_VERSION, ZFS_META_RELEASE,
- ZFS_DEBUG_STR, error);
+ ", rc = %d\n", ZFS_META_VERSION, ZFS_META_RELEASE,
+ ZFS_DEBUG_STR, error);
return (error);
}
tsd_destroy(&zfs_allow_log_key);
printk(KERN_NOTICE "ZFS: Unloaded module v%s-%s%s\n",
- ZFS_META_VERSION, ZFS_META_RELEASE, ZFS_DEBUG_STR);
+ ZFS_META_VERSION, ZFS_META_RELEASE, ZFS_DEBUG_STR);
return (0);
}
MODULE_DESCRIPTION("ZFS");
MODULE_AUTHOR(ZFS_META_AUTHOR);
MODULE_LICENSE(ZFS_META_LICENSE);
+MODULE_VERSION(ZFS_META_VERSION "-" ZFS_META_RELEASE);
#endif /* HAVE_SPL */