* Portions Copyright 2012 Pawel Jakub Dawidek <pawel@dawidek.net>
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
* Copyright 2011 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright (c) 201i3 by Delphix. All rights reserved.
* Copyright (c) 2013 by Saso Kiselkov. All rights reserved.
- * Copyright (c) 2012 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Steven Hartland. All rights reserved.
*/
/*
}
/*
- * zfs_earlier_version
- *
- * Return non-zero if the spa version is less than requested version.
+ * Return non-zero if the spa version is less than requested version.
*/
static int
zfs_earlier_version(const char *name, int version)
}
/*
- * zpl_earlier_version
- *
* Return TRUE if the ZPL version is less than requested version.
*/
static boolean_t
zone_dataset_visible(zc->zc_name, NULL))
return (0);
- return (ENOENT);
+ return (SET_ERROR(ENOENT));
}
static int
*/
if (!INGLOBALZONE(curproc) &&
!zone_dataset_visible(dataset, &writable))
- return (ENOENT);
+ return (SET_ERROR(ENOENT));
if (INGLOBALZONE(curproc)) {
/*
* global zone.
*/
if (secpolicy_zfs(cr) && zoned)
- return (EPERM);
+ return (SET_ERROR(EPERM));
} else {
/*
* If we are in a local zone, the 'zoned' property must be set.
*/
if (!zoned)
- return (EPERM);
+ return (SET_ERROR(EPERM));
/* must be writable by this zone */
if (!writable)
- return (EPERM);
+ return (SET_ERROR(EPERM));
}
return (0);
}
uint64_t zoned;
if (dsl_prop_get_integer(dataset, "zoned", &zoned, NULL))
- return (ENOENT);
+ return (SET_ERROR(ENOENT));
return (zfs_dozonecheck_impl(dataset, zoned, cr));
}
uint64_t zoned;
if (dsl_prop_get_int_ds(ds, "zoned", &zoned))
- return (ENOENT);
+ return (SET_ERROR(ENOENT));
return (zfs_dozonecheck_impl(dataset, zoned, cr));
}
error = dsl_prop_get(name, zfs_prop_to_name(ZFS_PROP_MLSLABEL),
1, sizeof (ds_hexsl), &ds_hexsl, NULL);
if (error != 0)
- return (EPERM);
+ return (SET_ERROR(EPERM));
if (strcasecmp(strval, ZFS_MLSLABEL_DEFAULT) == 0)
new_default = TRUE;
/* The label must be translatable */
if (!new_default && (hexstr_to_label(strval, &new_sl) != 0))
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
/*
* In a non-global zone, disallow attempts to set a label that
*/
if (!INGLOBALZONE(curproc)) {
if (new_default || !blequal(&new_sl, CR_SL(CRED())))
- return (EPERM);
+ return (SET_ERROR(EPERM));
return (0);
}
*/
if (dsl_prop_get_integer(name,
zfs_prop_to_name(ZFS_PROP_ZONED), &zoned, NULL))
- return (EPERM);
+ return (SET_ERROR(EPERM));
if (!zoned) {
if (zfs_check_global_label(name, strval) != 0)
- return (EPERM);
+ return (SET_ERROR(EPERM));
}
/*
error = dmu_objset_own(name, DMU_OST_ZFS, B_TRUE,
setsl_tag, &os);
if (error != 0)
- return (EPERM);
+ return (SET_ERROR(EPERM));
dmu_objset_disown(os, setsl_tag);
}
if (hexstr_to_label(strval, &new_sl) != 0)
- return (EPERM);
+ return (SET_ERROR(EPERM));
if (blstrictdom(&ds_sl, &new_sl))
needed_priv = PRIV_FILE_DOWNGRADE_SL;
return (PRIV_POLICY(cr, needed_priv, B_FALSE, EPERM, NULL));
return (0);
#else
- return ENOTSUP;
+ return (ENOTSUP);
#endif /* HAVE_MLSLABEL */
}
* Disallow setting of 'zoned' from within a local zone.
*/
if (!INGLOBALZONE(curproc))
- return (EPERM);
+ return (SET_ERROR(EPERM));
break;
case ZFS_PROP_QUOTA:
*/
if (dsl_prop_get_integer(dsname, "zoned", &zoned,
setpoint))
- return (EPERM);
+ return (SET_ERROR(EPERM));
if (!zoned || strlen(dsname) <= strlen(setpoint))
- return (EPERM);
+ return (SET_ERROR(EPERM));
}
break;
case ZFS_PROP_MLSLABEL:
if (!is_system_labeled())
- return (EPERM);
+ return (SET_ERROR(EPERM));
if (nvpair_value_string(propval, &strval) == 0) {
int err;
*/
cp = strchr(zc->zc_name, '@');
if (cp == NULL)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
error = dsl_pool_hold(zc->zc_name, FTAG, &dp);
if (error != 0)
return (error);
(strcmp((char *)refstr_value(vp->v_vfsp->vfs_resource),
zc->zc_name) != 0)) {
VN_RELE(vp);
- return (EPERM);
+ return (SET_ERROR(EPERM));
}
VN_RELE(vp);
{
#ifdef HAVE_SMB_SHARE
if (!INGLOBALZONE(curproc))
- return (EPERM);
+ return (SET_ERROR(EPERM));
if (secpolicy_nfs(cr) == 0) {
return (0);
return (zfs_secpolicy_deleg_share(zc, innvl, cr));
}
#else
- return (ENOTSUP);
+ return (SET_ERROR(ENOTSUP));
#endif /* HAVE_SMB_SHARE */
}
{
#ifdef HAVE_SMB_SHARE
if (!INGLOBALZONE(curproc))
- return (EPERM);
+ return (SET_ERROR(EPERM));
if (secpolicy_smb(cr) == 0) {
return (0);
return (zfs_secpolicy_deleg_share(zc, innvl, cr));
}
#else
- return (ENOTSUP);
+ return (SET_ERROR(ENOTSUP));
#endif /* HAVE_SMB_SHARE */
}
} else {
cp = strrchr(parent, '/');
if (cp == NULL)
- return (ENOENT);
+ return (SET_ERROR(ENOENT));
cp[0] = '\0';
}
int error = 0;
if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
pair = nextpair) {
dsl_pool_t *dp;
nvpair_t *pair;
if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
pair = nvlist_next_nvpair(snaps, pair)) {
char *name = nvpair_name(pair);
char *atp = strchr(name, '@');
if (atp == NULL) {
- error = EINVAL;
+ error = SET_ERROR(EINVAL);
break;
}
*atp = '\0';
* to log to.
*/
if (tsd_get(zfs_allow_log_key) == NULL)
- return (EPERM);
+ return (SET_ERROR(EPERM));
return (0);
}
zfs_secpolicy_config(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
{
if (secpolicy_sys_config(cr, B_FALSE) != 0)
- return (EPERM);
+ return (SET_ERROR(EPERM));
return (0);
}
if (prop == ZPROP_INVAL) {
if (!zfs_prop_user(zc->zc_value))
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
return (zfs_secpolicy_write_perms(zc->zc_name,
ZFS_DELEG_PERM_USERPROP, cr));
} else {
return (err);
if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
if (zc->zc_value[0] == 0) {
/*
return (err);
if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
return (zfs_secpolicy_write_perms(zc->zc_name,
userquota_perms[zc->zc_objset_type], cr));
error = nvlist_lookup_nvlist(innvl, "holds", &holds);
if (error != 0)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
for (pair = nvlist_next_nvpair(holds, NULL); pair != NULL;
pair = nvlist_next_nvpair(holds, pair)) {
* Read in and unpack the user-supplied nvlist.
*/
if (size == 0)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
packed = kmem_alloc(size, KM_SLEEP | KM_NODEBUG);
int n = 0;
if (max < 1024)
- return (ENOMEM);
+ return (SET_ERROR(ENOMEM));
fnvlist_add_int32(errors, ZPROP_N_MORE_ERRORS, 0);
more_errors = nvlist_prev_nvpair(errors, NULL);
size = fnvlist_size(nvl);
if (size > zc->zc_nvlist_dst_size) {
- error = ENOMEM;
+ error = SET_ERROR(ENOMEM);
} else {
packed = fnvlist_pack(nvl, &size);
if (ddi_copyout(packed, (void *)(uintptr_t)zc->zc_nvlist_dst,
size, zc->zc_iflags) != 0)
- error = EFAULT;
+ error = SET_ERROR(EFAULT);
fnvlist_pack_free(packed, size);
}
return (error);
if (dmu_objset_type(os) != DMU_OST_ZFS) {
dmu_objset_rele(os, FTAG);
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
}
mutex_enter(&os->os_user_ptr_lock);
if (*zsbp && (*zsbp)->z_sb) {
atomic_inc(&((*zsbp)->z_sb->s_active));
} else {
- error = ESRCH;
+ error = SET_ERROR(ESRCH);
}
mutex_exit(&os->os_user_ptr_lock);
dmu_objset_rele(os, FTAG);
/*
* XXX we could probably try again, since the unmounting
* thread should be just about to disassociate the
- * objset from the zfsvfs.
+ * objset from the zsb.
*/
rrw_exit(&(*zsbp)->z_teardown_lock, tag);
- return (EBUSY);
+ return (SET_ERROR(EBUSY));
}
}
return (error);
(void) nvlist_lookup_uint64(props,
zpool_prop_to_name(ZPOOL_PROP_VERSION), &version);
if (!SPA_VERSION_IS_SUPPORTED(version)) {
- error = EINVAL;
+ error = SET_ERROR(EINVAL);
goto pool_props_bad;
}
(void) nvlist_lookup_nvlist(props, ZPOOL_ROOTFS_PROPS, &nvl);
if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &guid) != 0 ||
guid != zc->zc_guid)
- error = EINVAL;
+ error = SET_ERROR(EINVAL);
else
error = spa_import(zc->zc_name, config, props, zc->zc_cookie);
int error;
if ((configs = spa_all_configs(&zc->zc_cookie)) == NULL)
- return (EEXIST);
+ return (SET_ERROR(EEXIST));
error = put_nvlist(zc, configs);
nvlist_free(tryconfig);
if (config == NULL)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
error = put_nvlist(zc, config);
nvlist_free(config);
if (zc->zc_cookie < spa_version(spa) ||
!SPA_VERSION_IS_SUPPORTED(zc->zc_cookie)) {
spa_close(spa, FTAG);
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
}
spa_upgrade(spa, zc->zc_cookie);
int error;
if ((size = zc->zc_history_len) == 0)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
if ((error = spa_open(zc->zc_name, &spa, FTAG)) != 0)
return (error);
if (spa_version(spa) < SPA_VERSION_ZPOOL_HISTORY) {
spa_close(spa, FTAG);
- return (ENOTSUP);
+ return (SET_ERROR(ENOTSUP));
}
hist_buf = vmem_alloc(size, KM_SLEEP);
return (error);
if (dmu_objset_type(os) != DMU_OST_ZFS) {
dmu_objset_rele(os, FTAG);
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
}
error = zfs_obj_to_path(os, zc->zc_obj, zc->zc_value,
sizeof (zc->zc_value));
return (error);
if (dmu_objset_type(os) != DMU_OST_ZFS) {
dmu_objset_rele(os, FTAG);
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
}
error = zfs_obj_to_stats(os, zc->zc_obj, &zc->zc_stat, zc->zc_value,
sizeof (zc->zc_value));
{
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 (EDOM);
- }
-
if (error == 0) {
error = spa_vdev_add(spa, config);
nvlist_free(config);
break;
default:
- error = EINVAL;
+ error = SET_ERROR(EINVAL);
}
zc->zc_cookie = newstate;
spa_close(spa, FTAG);
* SPA_VERSION_RECVD_PROPS.
*/
if (!dsl_prop_get_hasrecvd(zc->zc_name))
- return (ENOTSUP);
+ return (SET_ERROR(ENOTSUP));
if (zc->zc_nvlist_dst != 0 &&
(error = dsl_prop_get_received(zc->zc_name, &nv)) == 0) {
err = put_nvlist(zc, nv);
nvlist_free(nv);
} else {
- err = ENOENT;
+ err = SET_ERROR(ENOENT);
}
dmu_objset_rele(os, FTAG);
return (err);
}
-static boolean_t
+boolean_t
dataset_name_hidden(const char *name)
{
/*
top:
if ((error = dmu_objset_hold(zc->zc_name, FTAG, &os))) {
if (error == ENOENT)
- error = ESRCH;
+ error = SET_ERROR(ESRCH);
return (error);
}
sizeof (zc->zc_name) - (p - zc->zc_name), p,
NULL, &zc->zc_cookie);
if (error == ENOENT)
- error = ESRCH;
+ error = SET_ERROR(ESRCH);
} while (error == 0 && dataset_name_hidden(zc->zc_name));
dmu_objset_rele(os, FTAG);
*/
if (strlcat(zc->zc_name, "@", sizeof (zc->zc_name)) >= MAXNAMELEN) {
dmu_objset_rele(os, FTAG);
- return (ESRCH);
+ return (SET_ERROR(ESRCH));
}
error = dmu_snapshot_list_next(os,
dsl_dataset_rele(ds, FTAG);
}
} else if (error == ENOENT) {
- error = ESRCH;
+ error = SET_ERROR(ESRCH);
}
dmu_objset_rele(os, FTAG);
VERIFY(nvpair_value_nvlist(pair, &attrs) == 0);
if (nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
&pair) != 0)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
}
/*
if ((dash = strchr(propname, '-')) == NULL ||
nvpair_value_uint64_array(pair, &valary, &vallen) != 0 ||
vallen != 3)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
domain = dash + 1;
type = valary[0];
attrs = fnvpair_value_nvlist(pair);
if (nvlist_lookup_nvpair(attrs, ZPROP_VALUE,
&propval) != 0)
- err = EINVAL;
+ err = SET_ERROR(EINVAL);
}
/* Validate value type */
if (err == 0 && prop == ZPROP_INVAL) {
if (zfs_prop_user(propname)) {
if (nvpair_type(propval) != DATA_TYPE_STRING)
- err = EINVAL;
+ err = SET_ERROR(EINVAL);
} else if (zfs_prop_userquota(propname)) {
if (nvpair_type(propval) !=
DATA_TYPE_UINT64_ARRAY)
- err = EINVAL;
+ err = SET_ERROR(EINVAL);
} else {
- err = EINVAL;
+ err = SET_ERROR(EINVAL);
}
} else if (err == 0) {
if (nvpair_type(propval) == DATA_TYPE_STRING) {
if (zfs_prop_get_type(prop) != PROP_TYPE_STRING)
- err = EINVAL;
+ err = SET_ERROR(EINVAL);
} else if (nvpair_type(propval) == DATA_TYPE_UINT64) {
const char *unused;
case PROP_TYPE_NUMBER:
break;
case PROP_TYPE_STRING:
- err = EINVAL;
+ err = SET_ERROR(EINVAL);
break;
case PROP_TYPE_INDEX:
if (zfs_prop_index_to_string(prop,
intval, &unused) != 0)
- err = EINVAL;
+ err = SET_ERROR(EINVAL);
break;
default:
cmn_err(CE_PANIC,
"unknown property type");
}
} else {
- err = EINVAL;
+ err = SET_ERROR(EINVAL);
}
}
if (!zfs_prop_user(propname) ||
nvpair_type(pair) != DATA_TYPE_STRING)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
if ((error = zfs_secpolicy_write_perms(fsname,
ZFS_DELEG_PERM_USERPROP, CRED())))
return (error);
if (strlen(propname) >= ZAP_MAXNAMELEN)
- return (ENAMETOOLONG);
+ return (SET_ERROR(ENAMETOOLONG));
VERIFY(nvpair_value_string(pair, &valstr) == 0);
if (strlen(valstr) >= ZAP_MAXVALUELEN)
- return (E2BIG);
+ return (SET_ERROR(E2BIG));
}
return (0);
}
*/
if (prop == ZPROP_INVAL) {
if (!zfs_prop_user(propname))
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
type = PROP_TYPE_STRING;
} else if (prop == ZFS_PROP_VOLSIZE ||
prop == ZFS_PROP_VERSION) {
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
} else {
type = zfs_prop_get_type(prop);
}
break;
default:
nvlist_free(dummy);
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
}
pair = nvlist_next_nvpair(dummy, NULL);
* they are not considered inheritable.
*/
if (prop != ZPROP_INVAL && !zfs_prop_inheritable(prop))
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
}
/* property name has been validated by zfs_secpolicy_inherit_prop() */
if (error == 0 && zc->zc_nvlist_dst != 0)
error = put_nvlist(zc, nvp);
else
- error = EFAULT;
+ error = SET_ERROR(EFAULT);
nvlist_free(nvp);
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 = zfs_deleg_verify_nvlist(fsaclnv)) != 0) {
nvlist_free(fsaclnv);
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
}
/*
/*
* inputs:
- * createprops list of properties requested by creator
- * default_zplver zpl version to use if unspecified in createprops
- * fuids_ok fuids allowed in this version of the spa?
* os parent objset pointer (NULL if root fs)
+ * fuids_ok fuids allowed in this version of the spa?
+ * sa_ok SAs allowed in this version of the spa?
+ * createprops list of properties requested by creator
*
* outputs:
* zplprops values for the zplprops we attach to the master node object
(zplver < ZPL_VERSION_NORMALIZATION &&
(norm != ZFS_PROP_UNDEFINED || u8 != ZFS_PROP_UNDEFINED ||
sense != ZFS_PROP_UNDEFINED)))
- return (ENOTSUP);
+ return (SET_ERROR(ENOTSUP));
/*
* Put the version in the zplprops
boolean_t is_insensitive = B_FALSE;
if (nvlist_lookup_int32(innvl, "type", &type32) != 0)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
type = type32;
(void) nvlist_lookup_nvlist(innvl, "props", &nvprops);
}
if (strchr(fsname, '@') ||
strchr(fsname, '%'))
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
zct.zct_props = nvprops;
if (cbfunc == NULL)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
if (type == DMU_OST_ZVOL) {
uint64_t volsize, volblocksize;
if (nvprops == NULL)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
if (nvlist_lookup_uint64(nvprops,
zfs_prop_to_name(ZFS_PROP_VOLSIZE), &volsize) != 0)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
if ((error = nvlist_lookup_uint64(nvprops,
zfs_prop_to_name(ZFS_PROP_VOLBLOCKSIZE),
&volblocksize)) != 0 && error != ENOENT)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
if (error != 0)
volblocksize = zfs_prop_default_numeric(
if (error != 0)
(void) dsl_destroy_head(fsname);
}
+
+#ifdef _KERNEL
+ if (error == 0 && type == DMU_OST_ZVOL)
+ zvol_create_minors(fsname);
+#endif
+
return (error);
}
char *origin_name;
if (nvlist_lookup_string(innvl, "origin", &origin_name) != 0)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
(void) nvlist_lookup_nvlist(innvl, "props", &nvprops);
if (strchr(fsname, '@') ||
strchr(fsname, '%'))
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
if (dataset_namecheck(origin_name, NULL, NULL) != 0)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
error = dmu_objset_clone(fsname, origin_name);
if (error != 0)
return (error);
if (error != 0)
(void) dsl_destroy_head(fsname);
}
+
+#ifdef _KERNEL
+ if (error == 0)
+ zvol_create_minors(fsname);
+#endif
+
return (error);
}
if (!nvlist_empty(props) &&
zfs_earlier_version(poolname, SPA_VERSION_SNAP_PROPS))
- return (ENOTSUP);
+ return (SET_ERROR(ENOTSUP));
if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
poollen = strlen(poolname);
for (pair = nvlist_next_nvpair(snaps, NULL); pair != NULL;
pair = nvlist_next_nvpair(snaps, pair)) {
* contain only valid characters.
*/
if (cp == NULL || snapshot_namecheck(cp + 1, NULL, NULL) != 0)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
/*
* The snap must be in the specified pool.
*/
if (strncmp(name, poolname, poollen) != 0 ||
(name[poollen] != '/' && name[poollen] != '@'))
- return (EXDEV);
+ return (SET_ERROR(EXDEV));
/* This must be the only snap of this fs. */
for (pair2 = nvlist_next_nvpair(snaps, pair);
pair2 != NULL; pair2 = nvlist_next_nvpair(snaps, pair2)) {
if (strncmp(name, nvpair_name(pair2), cp - name + 1)
== 0) {
- return (EXDEV);
+ return (SET_ERROR(EXDEV));
}
}
}
error = dsl_dataset_snapshot(snaps, props, outnvl);
+
+#ifdef _KERNEL
+ if (error == 0)
+ zvol_create_minors(poolname);
+#endif
+
return (error);
}
if (nvlist_lookup_string(innvl, "message", &message) != 0) {
spa_close(spa, FTAG);
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
}
if (spa_version(spa) < SPA_VERSION_ZPOOL_HISTORY) {
spa_close(spa, FTAG);
- return (ENOTSUP);
+ return (SET_ERROR(ENOTSUP));
}
error = spa_history_log(spa, message);
*
* This function is best-effort. Callers must deal gracefully if it
* remains mounted (or is remounted after this call).
+ *
+ * XXX: This function should detect a failure to unmount a snapdir of a dataset
+ * and return the appropriate error code when it is mounted. Its Illumos and
+ * FreeBSD counterparts do this. We do not do this on Linux because there is no
+ * clear way to access the mount information that FreeBSD and Illumos use to
+ * distinguish between things with mounted snapshot directories, and things
+ * without mounted snapshot directories, which include zvols. Returning a
+ * failure for the latter causes `zfs destroy` to fail on zvol snapshots.
*/
-void
+int
zfs_unmount_snap(const char *snapname)
{
zfs_sb_t *zsb = NULL;
char *ptr;
if ((ptr = strchr(snapname, '@')) == NULL)
- return;
+ return (0);
dsname = kmem_alloc(ptr - snapname + 1, KM_SLEEP);
strlcpy(dsname, snapname, ptr - snapname + 1);
kmem_free(dsname, ptr - snapname + 1);
strfree(fullname);
- return;
+ return (0);
}
/* ARGSUSED */
static int
zfs_unmount_snap_cb(const char *snapname, void *arg)
{
- zfs_unmount_snap(snapname);
- return (0);
+ return (zfs_unmount_snap(snapname));
}
/*
char originname[MAXNAMELEN];
dsl_dataset_name(ds->ds_prev, originname);
dmu_objset_rele(os, FTAG);
- zfs_unmount_snap(originname);
+ (void) zfs_unmount_snap(originname);
} else {
dmu_objset_rele(os, FTAG);
}
static int
zfs_ioc_destroy_snaps(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
{
- int poollen;
+ int error, poollen;
nvlist_t *snaps;
nvpair_t *pair;
boolean_t defer;
if (nvlist_lookup_nvlist(innvl, "snaps", &snaps) != 0)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
defer = nvlist_exists(innvl, "defer");
poollen = strlen(poolname);
*/
if (strncmp(name, poolname, poollen) != 0 ||
(name[poollen] != '/' && name[poollen] != '@'))
- return (EXDEV);
+ return (SET_ERROR(EXDEV));
- zfs_unmount_snap(name);
+ error = zfs_unmount_snap(name);
+ if (error != 0)
+ return (error);
(void) zvol_remove_minor(name);
}
zfs_ioc_destroy(zfs_cmd_t *zc)
{
int err;
- if (strchr(zc->zc_name, '@') && zc->zc_objset_type == DMU_OST_ZFS)
- zfs_unmount_snap(zc->zc_name);
+
+ if (zc->zc_objset_type == DMU_OST_ZFS) {
+ err = zfs_unmount_snap(zc->zc_name);
+ if (err != 0)
+ return (err);
+ }
if (strchr(zc->zc_name, '@'))
err = dsl_destroy_snapshot(zc->zc_name, zc->zc_defer_destroy);
}
/*
- * 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);
- 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);
+ error = dsl_dataset_rollback(fsname, NULL, outnvl);
}
return (error);
}
fullname = kmem_asprintf("%s@%s", fsname, snapname);
zfs_unmount_snap(fullname);
strfree(fullname);
- return (0);
+ return (zfs_unmount_snap(fullname));
}
/*
{
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 ||
strchr(zc->zc_value, '%'))
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
at = strchr(zc->zc_name, '@');
if (at != NULL) {
/* snaps must be in same fs */
+ int error;
+
if (strncmp(zc->zc_name, zc->zc_value, at - zc->zc_name + 1))
- return (EXDEV);
+ return (SET_ERROR(EXDEV));
*at = '\0';
if (zc->zc_objset_type == DMU_OST_ZFS) {
- int error = dmu_objset_find(zc->zc_name,
+ error = dmu_objset_find(zc->zc_name,
recursive_unmount, at + 1,
recursive ? DS_FIND_CHILDREN : 0);
- if (error != 0)
+ if (error != 0) {
+ *at = '@';
return (error);
+ }
}
- return (dsl_dataset_rename_snapshot(zc->zc_name,
- at + 1, strchr(zc->zc_value, '@') + 1, recursive));
+ error = dsl_dataset_rename_snapshot(zc->zc_name,
+ at + 1, strchr(zc->zc_value, '@') + 1, recursive);
+ *at = '@';
+
+ 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));
}
}
perm = ZFS_DELEG_PERM_GROUPQUOTA;
} else {
/* USERUSED and GROUPUSED are read-only */
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
}
if ((err = zfs_secpolicy_write_perms(dsname, perm, cr)))
return (0);
}
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
}
if (issnap)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
/*
intval <= ZIO_COMPRESS_GZIP_9 &&
zfs_earlier_version(dsname,
SPA_VERSION_GZIP_COMPRESSION)) {
- return (ENOTSUP);
+ return (SET_ERROR(ENOTSUP));
}
if (intval == ZIO_COMPRESS_ZLE &&
zfs_earlier_version(dsname,
SPA_VERSION_ZLE_COMPRESSION))
- return (ENOTSUP);
+ return (SET_ERROR(ENOTSUP));
if (intval == ZIO_COMPRESS_LZ4) {
zfeature_info_t *feature =
if (!spa_feature_is_enabled(spa, feature)) {
spa_close(spa, FTAG);
- return (ENOTSUP);
+ return (SET_ERROR(ENOTSUP));
}
spa_close(spa, FTAG);
}
*/
if (zfs_is_bootfs(dsname) &&
!BOOTFS_COMPRESS_VALID(intval)) {
- return (ERANGE);
+ return (SET_ERROR(ERANGE));
}
}
break;
case ZFS_PROP_COPIES:
if (zfs_earlier_version(dsname, SPA_VERSION_DITTO_BLOCKS))
- return (ENOTSUP);
+ return (SET_ERROR(ENOTSUP));
break;
case ZFS_PROP_DEDUP:
if (zfs_earlier_version(dsname, SPA_VERSION_DEDUP))
- return (ENOTSUP);
+ return (SET_ERROR(ENOTSUP));
break;
case ZFS_PROP_SHARESMB:
if (zpl_earlier_version(dsname, ZPL_VERSION_FUID))
- return (ENOTSUP);
+ return (SET_ERROR(ENOTSUP));
break;
case ZFS_PROP_ACLINHERIT:
if (intval == ZFS_ACL_PASSTHROUGH_X &&
zfs_earlier_version(dsname,
SPA_VERSION_PASSTHROUGH_X))
- return (ENOTSUP);
+ return (SET_ERROR(ENOTSUP));
}
break;
default:
if (!spa_feature_is_active(spa, feature))
return (0);
else
- return (EBUSY);
+ return (SET_ERROR(EBUSY));
}
/*
if (dataset_namecheck(zc->zc_value, NULL, NULL) != 0 ||
strchr(zc->zc_value, '@') == NULL ||
strchr(zc->zc_value, '%'))
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
(void) strcpy(tofs, zc->zc_value);
tosnap = strchr(tofs, '@');
fp = getf(fd);
if (fp == NULL) {
nvlist_free(props);
- return (EBADF);
+ return (SET_ERROR(EBADF));
}
VERIFY(nvlist_alloc(&errors, NV_UNIQUE_NAME, KM_SLEEP) == 0);
* Caller made zc->zc_nvlist_dst less than the minimum expected
* size or supplied an invalid address.
*/
- props_error = EINVAL;
+ props_error = SET_ERROR(EINVAL);
}
off = fp->f_offset;
* If the suspend fails, then the recv_end will
* likely also fail, and clean up after itself.
*/
- end_err = dmu_recv_end(&drc);
+ end_err = dmu_recv_end(&drc, zsb);
if (error == 0)
error = zfs_resume_fs(zsb, tofs);
error = error ? error : end_err;
deactivate_super(zsb->z_sb);
} else {
- error = dmu_recv_end(&drc);
+ error = dmu_recv_end(&drc, NULL);
}
}
error = 1;
}
#endif
+
+#ifdef _KERNEL
+ if (error == 0)
+ zvol_create_minors(tofs);
+#endif
+
/*
* On error, restore the original props.
*/
} else {
file_t *fp = getf(zc->zc_cookie);
if (fp == NULL)
- return (EBADF);
+ return (SET_ERROR(EBADF));
off = fp->f_offset;
error = dmu_send_obj(zc->zc_name, zc->zc_sendobj,
if (dsp != NULL)
zc->zc_cookie = *(dsp->dsa_off);
else
- error = ENOENT;
+ error = SET_ERROR(ENOENT);
mutex_exit(&ds->ds_sendstream_lock);
dsl_dataset_rele(ds, FTAG);
spa = spa_lookup(zc->zc_name);
if (spa == NULL) {
mutex_exit(&spa_namespace_lock);
- return (EIO);
+ return (SET_ERROR(EIO));
}
if (spa_get_log_state(spa) == SPA_LOG_MISSING) {
/* we need to let spa_open/spa_load clear the chains */
nvlist_t *config = NULL;
if (zc->zc_nvlist_src == 0)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
if ((error = get_nvlist(zc->zc_nvlist_src,
zc->zc_nvlist_src_size, zc->zc_iflags, &policy)) == 0) {
if (vd == NULL) {
(void) spa_vdev_state_exit(spa, NULL, ENODEV);
spa_close(spa, FTAG);
- return (ENODEV);
+ return (SET_ERROR(ENODEV));
}
}
* Resume any suspended I/Os.
*/
if (zio_resume(spa) != 0)
- error = EIO;
+ error = SET_ERROR(EIO);
spa_close(spa, FTAG);
int error;
if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
error = zfs_sb_hold(zc->zc_name, FTAG, &zsb, B_FALSE);
if (error != 0)
void *buf;
if (bufsize <= 0)
- return (ENOMEM);
+ return (SET_ERROR(ENOMEM));
error = zfs_sb_hold(zc->zc_name, FTAG, &zsb, B_FALSE);
if (error != 0)
* objset_phys_t). Suspend/resume the fs will do that.
*/
error = zfs_suspend_fs(zsb);
- if (error == 0)
+ if (error == 0) {
+ dmu_objset_refresh_ownership(zsb->z_os,
+ zsb);
error = zfs_resume_fs(zsb, zc->zc_name);
+ }
}
if (error == 0)
error = dmu_objset_userspace_upgrade(zsb->z_os);
static int
zfs_ioc_share(zfs_cmd_t *zc)
{
- return (ENOSYS);
+ return (SET_ERROR(ENOSYS));
}
ace_t full_access[] = {
fp = getf(zc->zc_cookie);
if (fp == NULL)
- return (EBADF);
+ return (SET_ERROR(EBADF));
off = fp->f_offset;
(strcmp((char *)refstr_value(vp->v_vfsp->vfs_resource),
zc->zc_name) != 0)) {
VN_RELE(vp);
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
}
dzp = VTOZ(vp);
break;
default:
- error = EINVAL;
+ error = SET_ERROR(EINVAL);
break;
}
return (error);
#else
- return (ENOTSUP);
+ return (SET_ERROR(ENOTSUP));
#endif /* HAVE_SMB_SHARE */
}
error = nvlist_lookup_nvlist(args, "holds", &holds);
if (error != 0)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
if (nvlist_lookup_int32(args, "cleanup_fd", &cleanup_fd) == 0) {
error = zfs_onexit_fd_hold(cleanup_fd, &minor);
static int
zfs_ioc_release(const char *pool, nvlist_t *holds, nvlist_t *errlist)
{
- nvpair_t *pair;
-
- /*
- * The release may cause the snapshot to be destroyed; make sure it
- * is not mounted.
- */
- for (pair = nvlist_next_nvpair(holds, NULL); pair != NULL;
- pair = nvlist_next_nvpair(holds, pair))
- zfs_unmount_snap(nvpair_name(pair));
-
return (dsl_dataset_user_release(holds, errlist));
}
zfs_zevent_drain_all(&count);
zc->zc_cookie = count;
- return 0;
+ return (0);
}
/*
uint64_t used, comp, uncomp;
if (nvlist_lookup_string(innvl, "firstsnap", &firstsnap) != 0)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
error = dsl_pool_hold(lastsnap, FTAG, &dp);
if (error != 0)
error = nvlist_lookup_int32(innvl, "fd", &fd);
if (error != 0)
- return (EINVAL);
+ return (SET_ERROR(EINVAL));
(void) nvlist_lookup_string(innvl, "fromsnap", &fromname);
if ((fp = getf(fd)) == NULL)
- return (EBADF);
+ return (SET_ERROR(EBADF));
off = fp->f_offset;
error = dmu_send(snapname, fromname, fd, fp->f_vnode, &off);
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,
error = spa_open(name, &spa, FTAG);
if (error == 0) {
if ((check & POOL_CHECK_SUSPENDED) && spa_suspended(spa))
- error = EAGAIN;
+ error = SET_ERROR(EAGAIN);
else if ((check & POOL_CHECK_READONLY) && !spa_writeable(spa))
- error = EROFS;
+ error = SET_ERROR(EROFS);
spa_close(spa, FTAG);
}
return (error);
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 (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;
if (vecnum >= sizeof (zfs_ioc_vec) / sizeof (zfs_ioc_vec[0]))
- return (-EINVAL);
+ 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) {
- error = EFAULT;
+ error = SET_ERROR(EFAULT);
goto out;
}
switch (vec->zvec_namecheck) {
case POOL_NAME:
if (pool_namecheck(zc->zc_name, NULL, NULL) != 0)
- error = EINVAL;
+ error = SET_ERROR(EINVAL);
else
error = pool_status_check(zc->zc_name,
vec->zvec_namecheck, vec->zvec_pool_check);
case DATASET_NAME:
if (dataset_namecheck(zc->zc_name, NULL, NULL) != 0)
- error = EINVAL;
+ error = SET_ERROR(EINVAL);
else
error = pool_status_check(zc->zc_name,
vec->zvec_namecheck, vec->zvec_pool_check);
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';
nvlist_free(innvl);
rc = ddi_copyout(zc, (void *)arg, sizeof (zfs_cmd_t), flag);
if (error == 0 && rc != 0)
- error = EFAULT;
+ error = SET_ERROR(EFAULT);
if (error == 0 && vec->zvec_allow_log) {
char *s = tsd_get(zfs_allow_log_key);
if (s != NULL)
(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 */