summaryrefslogtreecommitdiffstats
path: root/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2012-09-23 20:12:10 +0000
committerpjd <pjd@FreeBSD.org>2012-09-23 20:12:10 +0000
commit212634d921b6016d77a964b0299d6df7a93aacc1 (patch)
tree0772e4df508e44f9ca88d1971c54fb2acb4e2d85 /sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
parent462a1240363ef90831d9b6cf6d345fc3c6e2ee0d (diff)
downloadFreeBSD-src-212634d921b6016d77a964b0299d6df7a93aacc1.zip
FreeBSD-src-212634d921b6016d77a964b0299d6df7a93aacc1.tar.gz
It is possible to recursively destroy snapshots even if the snapshot
doesn't exist on a dataset we are starting from. For example if we have the following configuration: tank tank/foo tank/foo@snap tank/bar tank/bar@snap We can execute: # zfs destroy -t tank@snap eventhough tank@snap doesn't exit. Unfortunately it is not possible to do the same with recursive rename: # zfs rename -r tank@snap tank@pans cannot open 'tank@snap': dataset does not exist ...until now. This change allows to recursively rename snapshots even if snapshot doesn't exist on the starting dataset. Sponsored by: rsync.net MFC after: 2 weeks
Diffstat (limited to 'sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c')
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
index ccbaa5e..85b035b 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c
@@ -2520,6 +2520,7 @@ struct renamesnaparg {
char failed[MAXPATHLEN];
char *oldsnap;
char *newsnap;
+ int error;
};
static int
@@ -2557,6 +2558,9 @@ dsl_snapshot_rename_one(const char *name, void *arg)
dsl_sync_task_create(ra->dstg, dsl_dataset_snapshot_rename_check,
dsl_dataset_snapshot_rename_sync, ds, ra->newsnap, 0);
+ /* First successful rename clears the error. */
+ ra->error = 0;
+
return (0);
}
@@ -2585,14 +2589,16 @@ dsl_recursive_rename(char *oldname, const char *newname)
ra->oldsnap = strchr(oldname, '@') + 1;
ra->newsnap = strchr(newname, '@') + 1;
*ra->failed = '\0';
+ ra->error = ENOENT;
err = dmu_objset_find(fsname, dsl_snapshot_rename_one, ra,
DS_FIND_CHILDREN);
kmem_free(fsname, len);
+ if (err == 0)
+ err = ra->error;
- if (err == 0) {
+ if (err == 0)
err = dsl_sync_task_group_wait(ra->dstg);
- }
for (dst = list_head(&ra->dstg->dstg_tasks); dst;
dst = list_next(&ra->dstg->dstg_tasks, dst)) {
OpenPOWER on IntegriCloud