mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2025-08-05 06:27:40 +03:00
dsl_dataset: rename dmu_objset_clone* to dsl_dataset_clone*
And make its check and sync functions visible, so I can hook them up to zcp_synctask. Rename not strictly necessary, but it definitely looks more like a dsl_dataset thing than a dmu_objset thing, to the extent that those things even have a meaningful distinction. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Alexander Motin <mav@FreeBSD.org> Signed-off-by: Rob Norris <robn@despairlabs.com> Sponsored-by: https://despairlabs.com/sponsor/ Closes #17426
This commit is contained in:
parent
ba227e2cc2
commit
560e3170ef
10
cmd/ztest.c
10
cmd/ztest.c
@ -4916,7 +4916,7 @@ ztest_dsl_dataset_promote_busy(ztest_ds_t *zd, uint64_t id)
|
||||
fatal(B_FALSE, "dmu_take_snapshot(%s) = %d", snap1name, error);
|
||||
}
|
||||
|
||||
error = dmu_objset_clone(clone1name, snap1name);
|
||||
error = dsl_dataset_clone(clone1name, snap1name);
|
||||
if (error) {
|
||||
if (error == ENOSPC) {
|
||||
ztest_record_enospc(FTAG);
|
||||
@ -4943,7 +4943,7 @@ ztest_dsl_dataset_promote_busy(ztest_ds_t *zd, uint64_t id)
|
||||
fatal(B_FALSE, "dmu_open_snapshot(%s) = %d", snap3name, error);
|
||||
}
|
||||
|
||||
error = dmu_objset_clone(clone2name, snap3name);
|
||||
error = dsl_dataset_clone(clone2name, snap3name);
|
||||
if (error) {
|
||||
if (error == ENOSPC) {
|
||||
ztest_record_enospc(FTAG);
|
||||
@ -6334,13 +6334,13 @@ ztest_dmu_snapshot_hold(ztest_ds_t *zd, uint64_t id)
|
||||
fatal(B_FALSE, "dmu_objset_snapshot(%s) = %d", fullname, error);
|
||||
}
|
||||
|
||||
error = dmu_objset_clone(clonename, fullname);
|
||||
error = dsl_dataset_clone(clonename, fullname);
|
||||
if (error) {
|
||||
if (error == ENOSPC) {
|
||||
ztest_record_enospc("dmu_objset_clone");
|
||||
ztest_record_enospc("dsl_dataset_clone");
|
||||
goto out;
|
||||
}
|
||||
fatal(B_FALSE, "dmu_objset_clone(%s) = %d", clonename, error);
|
||||
fatal(B_FALSE, "dsl_dataset_clone(%s) = %d", clonename, error);
|
||||
}
|
||||
|
||||
error = dsl_destroy_snapshot(fullname, B_TRUE);
|
||||
|
@ -360,7 +360,6 @@ void dmu_objset_evict_dbufs(objset_t *os);
|
||||
int dmu_objset_create(const char *name, dmu_objset_type_t type, uint64_t flags,
|
||||
struct dsl_crypto_params *dcp, dmu_objset_create_sync_func_t func,
|
||||
void *arg);
|
||||
int dmu_objset_clone(const char *name, const char *origin);
|
||||
int dsl_destroy_snapshots_nvl(struct nvlist *snaps, boolean_t defer,
|
||||
struct nvlist *errlist);
|
||||
int dmu_objset_snapshot_one(const char *fsname, const char *snapname);
|
||||
|
@ -276,6 +276,12 @@ dsl_dataset_phys(dsl_dataset_t *ds)
|
||||
return ((dsl_dataset_phys_t *)ds->ds_dbuf->db_data);
|
||||
}
|
||||
|
||||
typedef struct dsl_dataset_clone_arg_t {
|
||||
const char *ddca_clone;
|
||||
const char *ddca_origin;
|
||||
cred_t *ddca_cred;
|
||||
} dsl_dataset_clone_arg_t;
|
||||
|
||||
typedef struct dsl_dataset_promote_arg {
|
||||
const char *ddpa_clonename;
|
||||
dsl_dataset_t *ddpa_clone;
|
||||
@ -364,6 +370,9 @@ uint64_t dsl_dataset_create_sync_dd(dsl_dir_t *dd, dsl_dataset_t *origin,
|
||||
void dsl_dataset_snapshot_sync(void *arg, dmu_tx_t *tx);
|
||||
int dsl_dataset_snapshot_check(void *arg, dmu_tx_t *tx);
|
||||
int dsl_dataset_snapshot(nvlist_t *snaps, nvlist_t *props, nvlist_t *errors);
|
||||
void dsl_dataset_clone_sync(void *arg, dmu_tx_t *tx);
|
||||
int dsl_dataset_clone_check(void *arg, dmu_tx_t *tx);
|
||||
int dsl_dataset_clone(const char *clone, const char *origin);
|
||||
void dsl_dataset_promote_sync(void *arg, dmu_tx_t *tx);
|
||||
int dsl_dataset_promote_check(void *arg, dmu_tx_t *tx);
|
||||
int dsl_dataset_promote(const char *name, char *conflsnap);
|
||||
|
@ -1383,112 +1383,6 @@ dmu_objset_create(const char *name, dmu_objset_type_t type, uint64_t flags,
|
||||
return (rv);
|
||||
}
|
||||
|
||||
typedef struct dmu_objset_clone_arg {
|
||||
const char *doca_clone;
|
||||
const char *doca_origin;
|
||||
cred_t *doca_cred;
|
||||
} dmu_objset_clone_arg_t;
|
||||
|
||||
static int
|
||||
dmu_objset_clone_check(void *arg, dmu_tx_t *tx)
|
||||
{
|
||||
dmu_objset_clone_arg_t *doca = arg;
|
||||
dsl_dir_t *pdd;
|
||||
const char *tail;
|
||||
int error;
|
||||
dsl_dataset_t *origin;
|
||||
dsl_pool_t *dp = dmu_tx_pool(tx);
|
||||
|
||||
if (strchr(doca->doca_clone, '@') != NULL)
|
||||
return (SET_ERROR(EINVAL));
|
||||
|
||||
if (strlen(doca->doca_clone) >= ZFS_MAX_DATASET_NAME_LEN)
|
||||
return (SET_ERROR(ENAMETOOLONG));
|
||||
|
||||
error = dsl_dir_hold(dp, doca->doca_clone, FTAG, &pdd, &tail);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
if (tail == NULL) {
|
||||
dsl_dir_rele(pdd, FTAG);
|
||||
return (SET_ERROR(EEXIST));
|
||||
}
|
||||
|
||||
error = dsl_fs_ss_limit_check(pdd, 1, ZFS_PROP_FILESYSTEM_LIMIT, NULL,
|
||||
doca->doca_cred);
|
||||
if (error != 0) {
|
||||
dsl_dir_rele(pdd, FTAG);
|
||||
return (SET_ERROR(EDQUOT));
|
||||
}
|
||||
|
||||
error = dsl_dataset_hold(dp, doca->doca_origin, FTAG, &origin);
|
||||
if (error != 0) {
|
||||
dsl_dir_rele(pdd, FTAG);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/* You can only clone snapshots, not the head datasets. */
|
||||
if (!origin->ds_is_snapshot) {
|
||||
dsl_dataset_rele(origin, FTAG);
|
||||
dsl_dir_rele(pdd, FTAG);
|
||||
return (SET_ERROR(EINVAL));
|
||||
}
|
||||
|
||||
dsl_dataset_rele(origin, FTAG);
|
||||
dsl_dir_rele(pdd, FTAG);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
dmu_objset_clone_sync(void *arg, dmu_tx_t *tx)
|
||||
{
|
||||
dmu_objset_clone_arg_t *doca = arg;
|
||||
dsl_pool_t *dp = dmu_tx_pool(tx);
|
||||
dsl_dir_t *pdd;
|
||||
const char *tail;
|
||||
dsl_dataset_t *origin, *ds;
|
||||
uint64_t obj;
|
||||
char namebuf[ZFS_MAX_DATASET_NAME_LEN];
|
||||
|
||||
VERIFY0(dsl_dir_hold(dp, doca->doca_clone, FTAG, &pdd, &tail));
|
||||
VERIFY0(dsl_dataset_hold(dp, doca->doca_origin, FTAG, &origin));
|
||||
|
||||
obj = dsl_dataset_create_sync(pdd, tail, origin, 0,
|
||||
doca->doca_cred, NULL, tx);
|
||||
|
||||
VERIFY0(dsl_dataset_hold_obj(pdd->dd_pool, obj, FTAG, &ds));
|
||||
dsl_dataset_name(origin, namebuf);
|
||||
spa_history_log_internal_ds(ds, "clone", tx,
|
||||
"origin=%s (%llu)", namebuf, (u_longlong_t)origin->ds_object);
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
dsl_dataset_rele(origin, FTAG);
|
||||
dsl_dir_rele(pdd, FTAG);
|
||||
}
|
||||
|
||||
int
|
||||
dmu_objset_clone(const char *clone, const char *origin)
|
||||
{
|
||||
dmu_objset_clone_arg_t doca;
|
||||
|
||||
cred_t *cr = CRED();
|
||||
crhold(cr);
|
||||
|
||||
doca.doca_clone = clone;
|
||||
doca.doca_origin = origin;
|
||||
doca.doca_cred = cr;
|
||||
|
||||
int rv = dsl_sync_task(clone,
|
||||
dmu_objset_clone_check, dmu_objset_clone_sync, &doca,
|
||||
6, ZFS_SPACE_CHECK_NORMAL);
|
||||
|
||||
if (rv == 0)
|
||||
zvol_create_minor(clone);
|
||||
|
||||
crfree(cr);
|
||||
|
||||
return (rv);
|
||||
}
|
||||
|
||||
int
|
||||
dmu_objset_snapshot_one(const char *fsname, const char *snapname)
|
||||
{
|
||||
@ -3165,7 +3059,6 @@ EXPORT_SYMBOL(dmu_objset_rele_flags);
|
||||
EXPORT_SYMBOL(dmu_objset_disown);
|
||||
EXPORT_SYMBOL(dmu_objset_from_ds);
|
||||
EXPORT_SYMBOL(dmu_objset_create);
|
||||
EXPORT_SYMBOL(dmu_objset_clone);
|
||||
EXPORT_SYMBOL(dmu_objset_stats);
|
||||
EXPORT_SYMBOL(dmu_objset_fast_stat);
|
||||
EXPORT_SYMBOL(dmu_objset_spa);
|
||||
|
@ -3320,6 +3320,106 @@ dsl_dataset_rollback(const char *fsname, const char *tosnap, void *owner,
|
||||
1, ZFS_SPACE_CHECK_RESERVED));
|
||||
}
|
||||
|
||||
int
|
||||
dsl_dataset_clone_check(void *arg, dmu_tx_t *tx)
|
||||
{
|
||||
dsl_dataset_clone_arg_t *ddca = arg;
|
||||
dsl_dir_t *pdd;
|
||||
const char *tail;
|
||||
int error;
|
||||
dsl_dataset_t *origin;
|
||||
dsl_pool_t *dp = dmu_tx_pool(tx);
|
||||
|
||||
if (strchr(ddca->ddca_clone, '@') != NULL)
|
||||
return (SET_ERROR(EINVAL));
|
||||
|
||||
if (strlen(ddca->ddca_clone) >= ZFS_MAX_DATASET_NAME_LEN)
|
||||
return (SET_ERROR(ENAMETOOLONG));
|
||||
|
||||
error = dsl_dir_hold(dp, ddca->ddca_clone, FTAG, &pdd, &tail);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
if (tail == NULL) {
|
||||
dsl_dir_rele(pdd, FTAG);
|
||||
return (SET_ERROR(EEXIST));
|
||||
}
|
||||
|
||||
error = dsl_fs_ss_limit_check(pdd, 1, ZFS_PROP_FILESYSTEM_LIMIT, NULL,
|
||||
ddca->ddca_cred);
|
||||
if (error != 0) {
|
||||
dsl_dir_rele(pdd, FTAG);
|
||||
return (SET_ERROR(EDQUOT));
|
||||
}
|
||||
|
||||
error = dsl_dataset_hold(dp, ddca->ddca_origin, FTAG, &origin);
|
||||
if (error != 0) {
|
||||
dsl_dir_rele(pdd, FTAG);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/* You can only clone snapshots, not the head datasets. */
|
||||
if (!origin->ds_is_snapshot) {
|
||||
dsl_dataset_rele(origin, FTAG);
|
||||
dsl_dir_rele(pdd, FTAG);
|
||||
return (SET_ERROR(EINVAL));
|
||||
}
|
||||
|
||||
dsl_dataset_rele(origin, FTAG);
|
||||
dsl_dir_rele(pdd, FTAG);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
dsl_dataset_clone_sync(void *arg, dmu_tx_t *tx)
|
||||
{
|
||||
dsl_dataset_clone_arg_t *ddca = arg;
|
||||
dsl_pool_t *dp = dmu_tx_pool(tx);
|
||||
dsl_dir_t *pdd;
|
||||
const char *tail;
|
||||
dsl_dataset_t *origin, *ds;
|
||||
uint64_t obj;
|
||||
char namebuf[ZFS_MAX_DATASET_NAME_LEN];
|
||||
|
||||
VERIFY0(dsl_dir_hold(dp, ddca->ddca_clone, FTAG, &pdd, &tail));
|
||||
VERIFY0(dsl_dataset_hold(dp, ddca->ddca_origin, FTAG, &origin));
|
||||
|
||||
obj = dsl_dataset_create_sync(pdd, tail, origin, 0,
|
||||
ddca->ddca_cred, NULL, tx);
|
||||
|
||||
VERIFY0(dsl_dataset_hold_obj(pdd->dd_pool, obj, FTAG, &ds));
|
||||
dsl_dataset_name(origin, namebuf);
|
||||
spa_history_log_internal_ds(ds, "clone", tx,
|
||||
"origin=%s (%llu)", namebuf, (u_longlong_t)origin->ds_object);
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
dsl_dataset_rele(origin, FTAG);
|
||||
dsl_dir_rele(pdd, FTAG);
|
||||
}
|
||||
|
||||
int
|
||||
dsl_dataset_clone(const char *clone, const char *origin)
|
||||
{
|
||||
dsl_dataset_clone_arg_t ddca;
|
||||
|
||||
cred_t *cr = CRED();
|
||||
crhold(cr);
|
||||
|
||||
ddca.ddca_clone = clone;
|
||||
ddca.ddca_origin = origin;
|
||||
ddca.ddca_cred = cr;
|
||||
|
||||
int rv = dsl_sync_task(clone,
|
||||
dsl_dataset_clone_check, dsl_dataset_clone_sync, &ddca,
|
||||
6, ZFS_SPACE_CHECK_NORMAL);
|
||||
|
||||
if (rv == 0)
|
||||
zvol_create_minor(clone);
|
||||
|
||||
crfree(cr);
|
||||
|
||||
return (rv);
|
||||
}
|
||||
|
||||
struct promotenode {
|
||||
list_node_t link;
|
||||
dsl_dataset_t *ds;
|
||||
|
@ -3730,7 +3730,7 @@ zfs_ioc_clone(const char *fsname, nvlist_t *innvl, nvlist_t *outnvl)
|
||||
if (dataset_namecheck(origin_name, NULL, NULL) != 0)
|
||||
return (SET_ERROR(EINVAL));
|
||||
|
||||
error = dmu_objset_clone(fsname, origin_name);
|
||||
error = dsl_dataset_clone(fsname, origin_name);
|
||||
|
||||
/*
|
||||
* It would be nice to do this atomically.
|
||||
|
Loading…
Reference in New Issue
Block a user