mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 02:27:36 +03:00
Illumos #3464
3464 zfs synctask code needs restructuring Reviewed by: Dan Kimmel <dan.kimmel@delphix.com> Reviewed by: Adam Leventhal <ahl@delphix.com> Reviewed by: George Wilson <george.wilson@delphix.com> Reviewed by: Christopher Siden <christopher.siden@delphix.com> Approved by: Garrett D'Amore <garrett@damore.org> References: https://www.illumos.org/issues/3464 illumos/illumos-gate@3b2aab1880 Ported-by: Tim Chase <tim@chase2k.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #1495
This commit is contained in:
committed by
Brian Behlendorf
parent
6f1ffb0665
commit
13fe019870
+66
-50
@@ -892,6 +892,7 @@ typedef struct destroy_cbdata {
|
||||
boolean_t cb_parsable;
|
||||
boolean_t cb_dryrun;
|
||||
nvlist_t *cb_nvl;
|
||||
nvlist_t *cb_batchedsnaps;
|
||||
|
||||
/* first snap in contiguous run */
|
||||
char *cb_firstsnap;
|
||||
@@ -988,9 +989,27 @@ destroy_callback(zfs_handle_t *zhp, void *data)
|
||||
zfs_close(zhp);
|
||||
return (0);
|
||||
}
|
||||
if (cb->cb_dryrun) {
|
||||
zfs_close(zhp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (!cb->cb_dryrun) {
|
||||
if (zfs_unmount(zhp, NULL, cb->cb_force ? MS_FORCE : 0) != 0 ||
|
||||
/*
|
||||
* We batch up all contiguous snapshots (even of different
|
||||
* filesystems) and destroy them with one ioctl. We can't
|
||||
* simply do all snap deletions and then all fs deletions,
|
||||
* because we must delete a clone before its origin.
|
||||
*/
|
||||
if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) {
|
||||
fnvlist_add_boolean(cb->cb_batchedsnaps, name);
|
||||
} else {
|
||||
int error = zfs_destroy_snaps_nvl(g_zfs,
|
||||
cb->cb_batchedsnaps, B_FALSE);
|
||||
fnvlist_free(cb->cb_batchedsnaps);
|
||||
cb->cb_batchedsnaps = fnvlist_alloc();
|
||||
|
||||
if (error != 0 ||
|
||||
zfs_unmount(zhp, NULL, cb->cb_force ? MS_FORCE : 0) != 0 ||
|
||||
zfs_destroy(zhp, cb->cb_defer_destroy) != 0) {
|
||||
zfs_close(zhp);
|
||||
return (-1);
|
||||
@@ -1146,8 +1165,10 @@ static int
|
||||
zfs_do_destroy(int argc, char **argv)
|
||||
{
|
||||
destroy_cbdata_t cb = { 0 };
|
||||
int rv = 0;
|
||||
int err = 0;
|
||||
int c;
|
||||
zfs_handle_t *zhp;
|
||||
zfs_handle_t *zhp = NULL;
|
||||
char *at;
|
||||
zfs_type_t type = ZFS_TYPE_DATASET;
|
||||
|
||||
@@ -1201,11 +1222,9 @@ zfs_do_destroy(int argc, char **argv)
|
||||
|
||||
at = strchr(argv[0], '@');
|
||||
if (at != NULL) {
|
||||
int err = 0;
|
||||
|
||||
/* Build the list of snaps to destroy in cb_nvl. */
|
||||
if (nvlist_alloc(&cb.cb_nvl, NV_UNIQUE_NAME, 0) != 0)
|
||||
nomem();
|
||||
cb.cb_nvl = fnvlist_alloc();
|
||||
|
||||
*at = '\0';
|
||||
zhp = zfs_open(g_zfs, argv[0],
|
||||
@@ -1216,17 +1235,15 @@ zfs_do_destroy(int argc, char **argv)
|
||||
cb.cb_snapspec = at + 1;
|
||||
if (gather_snapshots(zfs_handle_dup(zhp), &cb) != 0 ||
|
||||
cb.cb_error) {
|
||||
zfs_close(zhp);
|
||||
nvlist_free(cb.cb_nvl);
|
||||
return (1);
|
||||
rv = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (nvlist_empty(cb.cb_nvl)) {
|
||||
(void) fprintf(stderr, gettext("could not find any "
|
||||
"snapshots to destroy; check snapshot names.\n"));
|
||||
zfs_close(zhp);
|
||||
nvlist_free(cb.cb_nvl);
|
||||
return (1);
|
||||
rv = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (cb.cb_verbose) {
|
||||
@@ -1245,18 +1262,26 @@ zfs_do_destroy(int argc, char **argv)
|
||||
}
|
||||
|
||||
if (!cb.cb_dryrun) {
|
||||
if (cb.cb_doclones)
|
||||
if (cb.cb_doclones) {
|
||||
cb.cb_batchedsnaps = fnvlist_alloc();
|
||||
err = destroy_clones(&cb);
|
||||
if (err == 0) {
|
||||
err = zfs_destroy_snaps_nvl(g_zfs,
|
||||
cb.cb_batchedsnaps, B_FALSE);
|
||||
}
|
||||
if (err != 0) {
|
||||
rv = 1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (err == 0) {
|
||||
err = zfs_destroy_snaps_nvl(zhp, cb.cb_nvl,
|
||||
err = zfs_destroy_snaps_nvl(g_zfs, cb.cb_nvl,
|
||||
cb.cb_defer_destroy);
|
||||
}
|
||||
}
|
||||
|
||||
zfs_close(zhp);
|
||||
nvlist_free(cb.cb_nvl);
|
||||
if (err != 0)
|
||||
return (1);
|
||||
rv = 1;
|
||||
} else {
|
||||
/* Open the given dataset */
|
||||
if ((zhp = zfs_open(g_zfs, argv[0], type)) == NULL)
|
||||
@@ -1277,8 +1302,8 @@ zfs_do_destroy(int argc, char **argv)
|
||||
zfs_get_name(zhp));
|
||||
(void) fprintf(stderr, gettext("use 'zpool destroy %s' "
|
||||
"to destroy the pool itself\n"), zfs_get_name(zhp));
|
||||
zfs_close(zhp);
|
||||
return (1);
|
||||
rv = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1288,30 +1313,42 @@ zfs_do_destroy(int argc, char **argv)
|
||||
if (!cb.cb_doclones &&
|
||||
zfs_iter_dependents(zhp, B_TRUE, destroy_check_dependent,
|
||||
&cb) != 0) {
|
||||
zfs_close(zhp);
|
||||
return (1);
|
||||
rv = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (cb.cb_error) {
|
||||
zfs_close(zhp);
|
||||
return (1);
|
||||
rv = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
cb.cb_batchedsnaps = fnvlist_alloc();
|
||||
if (zfs_iter_dependents(zhp, B_FALSE, destroy_callback,
|
||||
&cb) != 0) {
|
||||
zfs_close(zhp);
|
||||
return (1);
|
||||
rv = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the real thing. The callback will close the
|
||||
* handle regardless of whether it succeeds or not.
|
||||
*/
|
||||
if (destroy_callback(zhp, &cb) != 0)
|
||||
return (1);
|
||||
err = destroy_callback(zhp, &cb);
|
||||
zhp = NULL;
|
||||
if (err == 0) {
|
||||
err = zfs_destroy_snaps_nvl(g_zfs,
|
||||
cb.cb_batchedsnaps, cb.cb_defer_destroy);
|
||||
}
|
||||
if (err != 0)
|
||||
rv = 1;
|
||||
}
|
||||
|
||||
return (0);
|
||||
out:
|
||||
fnvlist_free(cb.cb_batchedsnaps);
|
||||
fnvlist_free(cb.cb_nvl);
|
||||
if (zhp != NULL)
|
||||
zfs_close(zhp);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
static boolean_t
|
||||
@@ -5081,28 +5118,12 @@ cleanup2:
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* zfs allow [-r] [-t] <tag> <snap> ...
|
||||
*
|
||||
* -r Recursively hold
|
||||
* -t Temporary hold (hidden option)
|
||||
*
|
||||
* Apply a user-hold with the given tag to the list of snapshots.
|
||||
*/
|
||||
static int
|
||||
zfs_do_allow(int argc, char **argv)
|
||||
{
|
||||
return (zfs_do_allow_unallow_impl(argc, argv, B_FALSE));
|
||||
}
|
||||
|
||||
/*
|
||||
* zfs unallow [-r] [-t] <tag> <snap> ...
|
||||
*
|
||||
* -r Recursively hold
|
||||
* -t Temporary hold (hidden option)
|
||||
*
|
||||
* Apply a user-hold with the given tag to the list of snapshots.
|
||||
*/
|
||||
static int
|
||||
zfs_do_unallow(int argc, char **argv)
|
||||
{
|
||||
@@ -5116,7 +5137,6 @@ zfs_do_hold_rele_impl(int argc, char **argv, boolean_t holding)
|
||||
int i;
|
||||
const char *tag;
|
||||
boolean_t recursive = B_FALSE;
|
||||
boolean_t temphold = B_FALSE;
|
||||
const char *opts = holding ? "rt" : "r";
|
||||
int c;
|
||||
|
||||
@@ -5126,9 +5146,6 @@ zfs_do_hold_rele_impl(int argc, char **argv, boolean_t holding)
|
||||
case 'r':
|
||||
recursive = B_TRUE;
|
||||
break;
|
||||
case 't':
|
||||
temphold = B_TRUE;
|
||||
break;
|
||||
case '?':
|
||||
(void) fprintf(stderr, gettext("invalid option '%c'\n"),
|
||||
optopt);
|
||||
@@ -5177,7 +5194,7 @@ zfs_do_hold_rele_impl(int argc, char **argv, boolean_t holding)
|
||||
}
|
||||
if (holding) {
|
||||
if (zfs_hold(zhp, delim+1, tag, recursive,
|
||||
temphold, B_FALSE, -1, 0, 0) != 0)
|
||||
B_FALSE, -1) != 0)
|
||||
++errors;
|
||||
} else {
|
||||
if (zfs_release(zhp, delim+1, tag, recursive) != 0)
|
||||
@@ -5193,7 +5210,6 @@ zfs_do_hold_rele_impl(int argc, char **argv, boolean_t holding)
|
||||
* zfs hold [-r] [-t] <tag> <snap> ...
|
||||
*
|
||||
* -r Recursively hold
|
||||
* -t Temporary hold (hidden option)
|
||||
*
|
||||
* Apply a user-hold with the given tag to the list of snapshots.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user