mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-25 18:59:33 +03:00
zvol: Cleanup set property
zvol_set_volmode() and zvol_set_snapdev() share a common code path. Merge this shared code path into zvol_set_common(). Reviewed-by: Tony Hutter <hutter2@llnl.gov> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Alexander Motin <mav@FreeBSD.org> Signed-off-by: Ameer Hamza <ahamza@ixsystems.com> Closes #15409
This commit is contained in:
parent
799e09f75a
commit
dbe839a9ca
@ -50,8 +50,7 @@ extern int zvol_get_stats(objset_t *, nvlist_t *);
|
||||
extern boolean_t zvol_is_zvol(const char *);
|
||||
extern void zvol_create_cb(objset_t *, void *, cred_t *, dmu_tx_t *);
|
||||
extern int zvol_set_volsize(const char *, uint64_t);
|
||||
extern int zvol_set_snapdev(const char *, zprop_source_t, uint64_t);
|
||||
extern int zvol_set_volmode(const char *, zprop_source_t, uint64_t);
|
||||
extern int zvol_set_common(const char *, zfs_prop_t, zprop_source_t, uint64_t);
|
||||
extern zvol_state_handle_t *zvol_suspend(const char *);
|
||||
extern int zvol_resume(zvol_state_handle_t *);
|
||||
extern void *zvol_tag(zvol_state_handle_t *);
|
||||
|
@ -2523,10 +2523,8 @@ zfs_prop_set_special(const char *dsname, zprop_source_t source,
|
||||
err = zvol_set_volsize(dsname, intval);
|
||||
break;
|
||||
case ZFS_PROP_SNAPDEV:
|
||||
err = zvol_set_snapdev(dsname, source, intval);
|
||||
break;
|
||||
case ZFS_PROP_VOLMODE:
|
||||
err = zvol_set_volmode(dsname, source, intval);
|
||||
err = zvol_set_common(dsname, prop, source, intval);
|
||||
break;
|
||||
case ZFS_PROP_VERSION:
|
||||
{
|
||||
|
@ -1538,6 +1538,7 @@ typedef struct zvol_set_prop_int_arg {
|
||||
const char *zsda_name;
|
||||
uint64_t zsda_value;
|
||||
zprop_source_t zsda_source;
|
||||
zfs_prop_t zsda_prop;
|
||||
dmu_tx_t *zsda_tx;
|
||||
} zvol_set_prop_int_arg_t;
|
||||
|
||||
@ -1546,7 +1547,7 @@ typedef struct zvol_set_prop_int_arg {
|
||||
* conditions are imposed.
|
||||
*/
|
||||
static int
|
||||
zvol_set_snapdev_check(void *arg, dmu_tx_t *tx)
|
||||
zvol_set_common_check(void *arg, dmu_tx_t *tx)
|
||||
{
|
||||
zvol_set_prop_int_arg_t *zsda = arg;
|
||||
dsl_pool_t *dp = dmu_tx_pool(tx);
|
||||
@ -1563,17 +1564,33 @@ zvol_set_snapdev_check(void *arg, dmu_tx_t *tx)
|
||||
}
|
||||
|
||||
static int
|
||||
zvol_set_snapdev_sync_cb(dsl_pool_t *dp, dsl_dataset_t *ds, void *arg)
|
||||
zvol_set_common_sync_cb(dsl_pool_t *dp, dsl_dataset_t *ds, void *arg)
|
||||
{
|
||||
(void) arg;
|
||||
zvol_set_prop_int_arg_t *zsda = arg;
|
||||
char dsname[MAXNAMELEN];
|
||||
zvol_task_t *task;
|
||||
uint64_t snapdev;
|
||||
uint64_t prop;
|
||||
|
||||
const char *prop_name = zfs_prop_to_name(zsda->zsda_prop);
|
||||
dsl_dataset_name(ds, dsname);
|
||||
if (dsl_prop_get_int_ds(ds, "snapdev", &snapdev) != 0)
|
||||
|
||||
if (dsl_prop_get_int_ds(ds, prop_name, &prop) != 0)
|
||||
return (0);
|
||||
task = zvol_task_alloc(ZVOL_ASYNC_SET_SNAPDEV, dsname, NULL, snapdev);
|
||||
|
||||
switch (zsda->zsda_prop) {
|
||||
case ZFS_PROP_VOLMODE:
|
||||
task = zvol_task_alloc(ZVOL_ASYNC_SET_VOLMODE, dsname,
|
||||
NULL, prop);
|
||||
break;
|
||||
case ZFS_PROP_SNAPDEV:
|
||||
task = zvol_task_alloc(ZVOL_ASYNC_SET_SNAPDEV, dsname,
|
||||
NULL, prop);
|
||||
break;
|
||||
default:
|
||||
task = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (task == NULL)
|
||||
return (0);
|
||||
|
||||
@ -1583,14 +1600,14 @@ zvol_set_snapdev_sync_cb(dsl_pool_t *dp, dsl_dataset_t *ds, void *arg)
|
||||
}
|
||||
|
||||
/*
|
||||
* Traverse all child datasets and apply snapdev appropriately.
|
||||
* Traverse all child datasets and apply the property appropriately.
|
||||
* We call dsl_prop_set_sync_impl() here to set the value only on the toplevel
|
||||
* dataset and read the effective "snapdev" on every child in the callback
|
||||
* dataset and read the effective "property" on every child in the callback
|
||||
* function: this is because the value is not guaranteed to be the same in the
|
||||
* whole dataset hierarchy.
|
||||
*/
|
||||
static void
|
||||
zvol_set_snapdev_sync(void *arg, dmu_tx_t *tx)
|
||||
zvol_set_common_sync(void *arg, dmu_tx_t *tx)
|
||||
{
|
||||
zvol_set_prop_int_arg_t *zsda = arg;
|
||||
dsl_pool_t *dp = dmu_tx_pool(tx);
|
||||
@ -1603,115 +1620,31 @@ zvol_set_snapdev_sync(void *arg, dmu_tx_t *tx)
|
||||
|
||||
error = dsl_dataset_hold(dp, zsda->zsda_name, FTAG, &ds);
|
||||
if (error == 0) {
|
||||
dsl_prop_set_sync_impl(ds, zfs_prop_to_name(ZFS_PROP_SNAPDEV),
|
||||
dsl_prop_set_sync_impl(ds, zfs_prop_to_name(zsda->zsda_prop),
|
||||
zsda->zsda_source, sizeof (zsda->zsda_value), 1,
|
||||
&zsda->zsda_value, zsda->zsda_tx);
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
}
|
||||
dmu_objset_find_dp(dp, dd->dd_object, zvol_set_snapdev_sync_cb,
|
||||
|
||||
dmu_objset_find_dp(dp, dd->dd_object, zvol_set_common_sync_cb,
|
||||
zsda, DS_FIND_CHILDREN);
|
||||
|
||||
dsl_dir_rele(dd, FTAG);
|
||||
}
|
||||
|
||||
int
|
||||
zvol_set_snapdev(const char *ddname, zprop_source_t source, uint64_t snapdev)
|
||||
zvol_set_common(const char *ddname, zfs_prop_t prop, zprop_source_t source,
|
||||
uint64_t val)
|
||||
{
|
||||
zvol_set_prop_int_arg_t zsda;
|
||||
|
||||
zsda.zsda_name = ddname;
|
||||
zsda.zsda_source = source;
|
||||
zsda.zsda_value = snapdev;
|
||||
zsda.zsda_value = val;
|
||||
zsda.zsda_prop = prop;
|
||||
|
||||
return (dsl_sync_task(ddname, zvol_set_snapdev_check,
|
||||
zvol_set_snapdev_sync, &zsda, 0, ZFS_SPACE_CHECK_NONE));
|
||||
}
|
||||
|
||||
/*
|
||||
* Sanity check the dataset for safe use by the sync task. No additional
|
||||
* conditions are imposed.
|
||||
*/
|
||||
static int
|
||||
zvol_set_volmode_check(void *arg, dmu_tx_t *tx)
|
||||
{
|
||||
zvol_set_prop_int_arg_t *zsda = arg;
|
||||
dsl_pool_t *dp = dmu_tx_pool(tx);
|
||||
dsl_dir_t *dd;
|
||||
int error;
|
||||
|
||||
error = dsl_dir_hold(dp, zsda->zsda_name, FTAG, &dd, NULL);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
dsl_dir_rele(dd, FTAG);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
zvol_set_volmode_sync_cb(dsl_pool_t *dp, dsl_dataset_t *ds, void *arg)
|
||||
{
|
||||
(void) arg;
|
||||
char dsname[MAXNAMELEN];
|
||||
zvol_task_t *task;
|
||||
uint64_t volmode;
|
||||
|
||||
dsl_dataset_name(ds, dsname);
|
||||
if (dsl_prop_get_int_ds(ds, "volmode", &volmode) != 0)
|
||||
return (0);
|
||||
task = zvol_task_alloc(ZVOL_ASYNC_SET_VOLMODE, dsname, NULL, volmode);
|
||||
if (task == NULL)
|
||||
return (0);
|
||||
|
||||
(void) taskq_dispatch(dp->dp_spa->spa_zvol_taskq, zvol_task_cb,
|
||||
task, TQ_SLEEP);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Traverse all child datasets and apply volmode appropriately.
|
||||
* We call dsl_prop_set_sync_impl() here to set the value only on the toplevel
|
||||
* dataset and read the effective "volmode" on every child in the callback
|
||||
* function: this is because the value is not guaranteed to be the same in the
|
||||
* whole dataset hierarchy.
|
||||
*/
|
||||
static void
|
||||
zvol_set_volmode_sync(void *arg, dmu_tx_t *tx)
|
||||
{
|
||||
zvol_set_prop_int_arg_t *zsda = arg;
|
||||
dsl_pool_t *dp = dmu_tx_pool(tx);
|
||||
dsl_dir_t *dd;
|
||||
dsl_dataset_t *ds;
|
||||
int error;
|
||||
|
||||
VERIFY0(dsl_dir_hold(dp, zsda->zsda_name, FTAG, &dd, NULL));
|
||||
zsda->zsda_tx = tx;
|
||||
|
||||
error = dsl_dataset_hold(dp, zsda->zsda_name, FTAG, &ds);
|
||||
if (error == 0) {
|
||||
dsl_prop_set_sync_impl(ds, zfs_prop_to_name(ZFS_PROP_VOLMODE),
|
||||
zsda->zsda_source, sizeof (zsda->zsda_value), 1,
|
||||
&zsda->zsda_value, zsda->zsda_tx);
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
}
|
||||
|
||||
dmu_objset_find_dp(dp, dd->dd_object, zvol_set_volmode_sync_cb,
|
||||
zsda, DS_FIND_CHILDREN);
|
||||
|
||||
dsl_dir_rele(dd, FTAG);
|
||||
}
|
||||
|
||||
int
|
||||
zvol_set_volmode(const char *ddname, zprop_source_t source, uint64_t volmode)
|
||||
{
|
||||
zvol_set_prop_int_arg_t zsda;
|
||||
|
||||
zsda.zsda_name = ddname;
|
||||
zsda.zsda_source = source;
|
||||
zsda.zsda_value = volmode;
|
||||
|
||||
return (dsl_sync_task(ddname, zvol_set_volmode_check,
|
||||
zvol_set_volmode_sync, &zsda, 0, ZFS_SPACE_CHECK_NONE));
|
||||
return (dsl_sync_task(ddname, zvol_set_common_check,
|
||||
zvol_set_common_sync, &zsda, 0, ZFS_SPACE_CHECK_NONE));
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user