Mercurial > illumos > illumos-gate
changeset 10385:21cb6e67d108
6873727 zfs destroy -d <fs> should fail more gracefully when children are present
author | Chris Kirby <chris.kirby@sun.com> |
---|---|
date | Wed, 26 Aug 2009 12:54:24 -0600 |
parents | 73bb2903cf6f |
children | 935ab057bcbb |
files | usr/src/cmd/zfs/zfs_main.c usr/src/uts/common/fs/zfs/dsl_dataset.c |
diffstat | 2 files changed, 18 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- 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;