6873727 zfs destroy -d <fs> should fail more gracefully when children are present
--- a/usr/src/cmd/zfs/zfs_main.c Wed Aug 26 10:24:43 2009 -0700
+++ b/usr/src/cmd/zfs/zfs_main.c Wed Aug 26 12:54:24 2009 -0600
@@ -197,9 +197,8 @@
"\tcreate [-ps] [-b blocksize] [-o property=value] ... "
"-V <size> <volume>\n"));
case HELP_DESTROY:
- return (gettext("\tdestroy [-rRf] "
- "<filesystem|volume|snapshot>\n"
- "\tdestroy -d [-r] <filesystem|volume|snapshot>\n"));
+ return (gettext("\tdestroy [-rRf] <filesystem|volume>\n"
+ "\tdestroy [-rRd] <snapshot>\n"));
case HELP_GET:
return (gettext("\tget [-rHp] [-d max] "
"[-o field[,...]] [-s source[,...]]\n"
@@ -785,8 +784,8 @@
}
/*
- * zfs destroy [-rRf] <fs, snap, vol>
- * zfs destroy -d [-r] <fs, snap, vol>
+ * zfs destroy [-rRf] <fs, vol>
+ * zfs destroy [-rRd] <snap>
*
* -r Recursively destroy all children
* -R Recursively destroy all dependents, including clones
@@ -940,12 +939,14 @@
int c;
zfs_handle_t *zhp;
char *cp;
+ zfs_type_t type = ZFS_TYPE_DATASET;
/* check options */
while ((c = getopt(argc, argv, "dfrR")) != -1) {
switch (c) {
case 'd':
cb.cb_defer_destroy = B_TRUE;
+ type = ZFS_TYPE_SNAPSHOT;
break;
case 'f':
cb.cb_force = 1;
@@ -978,9 +979,6 @@
usage(B_FALSE);
}
- if (cb.cb_defer_destroy && cb.cb_doclones)
- usage(B_FALSE);
-
/*
* If we are doing recursive destroy of a snapshot, then the
* named snapshot may not exist. Go straight to libzfs.
@@ -995,11 +993,19 @@
cp++;
if (cb.cb_doclones) {
+ boolean_t defer = cb.cb_defer_destroy;
+
+ /*
+ * Temporarily ignore the defer_destroy setting since
+ * it's not supported for clones.
+ */
+ cb.cb_defer_destroy = B_FALSE;
cb.cb_snapname = cp;
if (destroy_snap_clones(zhp, &cb) != 0) {
zfs_close(zhp);
return (1);
}
+ cb.cb_defer_destroy = defer;
}
ret = zfs_destroy_snaps(zhp, cp, cb.cb_defer_destroy);
@@ -1012,7 +1018,7 @@
}
/* Open the given dataset */
- if ((zhp = zfs_open(g_zfs, argv[0], ZFS_TYPE_DATASET)) == NULL)
+ if ((zhp = zfs_open(g_zfs, argv[0], type)) == NULL)
return (1);
cb.cb_target = zhp;
--- a/usr/src/uts/common/fs/zfs/dsl_dataset.c Wed Aug 26 10:24:43 2009 -0700
+++ b/usr/src/uts/common/fs/zfs/dsl_dataset.c Wed Aug 26 12:54:24 2009 -0600
@@ -1036,13 +1036,15 @@
dmu_objset_evict(ds->ds_objset);
ds->ds_objset = NULL;
}
- /* NOTE: defer is always B_FALSE for non-snapshots */
dsda.defer = defer;
err = dsl_sync_task_do(ds->ds_dir->dd_pool,
dsl_dataset_destroy_check, dsl_dataset_destroy_sync,
&dsda, tag, 0);
ASSERT3P(dsda.rm_origin, ==, NULL);
goto out;
+ } else if (defer) {
+ err = EINVAL;
+ goto out;
}
dd = ds->ds_dir;