From owner-svn-src-all@FreeBSD.ORG Fri Mar 1 21:01:48 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 975BA5E6; Fri, 1 Mar 2013 21:01:48 +0000 (UTC) (envelope-from mm@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 79AD517C8; Fri, 1 Mar 2013 21:01:48 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id r21L1m70090775; Fri, 1 Mar 2013 21:01:48 GMT (envelope-from mm@svn.freebsd.org) Received: (from mm@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id r21L1lBk090765; Fri, 1 Mar 2013 21:01:47 GMT (envelope-from mm@svn.freebsd.org) Message-Id: <201303012101.r21L1lBk090765@svn.freebsd.org> From: Martin Matuska Date: Fri, 1 Mar 2013 21:01:47 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org Subject: svn commit: r247580 - vendor-sys/illumos/dist/common/nvpair vendor-sys/illumos/dist/uts/common vendor-sys/illumos/dist/uts/common/fs/zfs vendor-sys/illumos/dist/uts/common/fs/zfs/sys vendor-sys/ill... X-SVN-Group: vendor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 01 Mar 2013 21:01:48 -0000 Author: mm Date: Fri Mar 1 21:01:45 2013 New Revision: 247580 URL: http://svnweb.freebsd.org/changeset/base/247580 Log: Update vendor/illumos/dist and vendor-sys/illumos/dist to illumos-gate 13973:4972ab336f54 Illumos ZFS issues: 3464 zfs synctask code needs restructuring Modified: vendor/illumos/dist/cmd/zdb/zdb.c vendor/illumos/dist/cmd/zfs/zfs_main.c vendor/illumos/dist/cmd/zhack/zhack.c vendor/illumos/dist/cmd/ztest/ztest.c vendor/illumos/dist/lib/libzfs/common/libzfs.h vendor/illumos/dist/lib/libzfs/common/libzfs_dataset.c vendor/illumos/dist/lib/libzfs/common/libzfs_sendrecv.c vendor/illumos/dist/lib/libzfs_core/common/libzfs_core.c vendor/illumos/dist/lib/libzfs_core/common/libzfs_core.h vendor/illumos/dist/lib/libzpool/common/kernel.c vendor/illumos/dist/lib/libzpool/common/sys/zfs_context.h vendor/illumos/dist/man/man1m/zfs.1m Changes in other areas also in this revision: Added: vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_destroy.c vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_userhold.c vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dmu_send.h vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dsl_destroy.h vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dsl_userhold.h Modified: vendor-sys/illumos/dist/common/nvpair/fnvpair.c vendor-sys/illumos/dist/uts/common/Makefile.files vendor-sys/illumos/dist/uts/common/fs/zfs/arc.c vendor-sys/illumos/dist/uts/common/fs/zfs/bplist.c vendor-sys/illumos/dist/uts/common/fs/zfs/bpobj.c vendor-sys/illumos/dist/uts/common/fs/zfs/dbuf.c vendor-sys/illumos/dist/uts/common/fs/zfs/dmu.c vendor-sys/illumos/dist/uts/common/fs/zfs/dmu_diff.c vendor-sys/illumos/dist/uts/common/fs/zfs/dmu_objset.c vendor-sys/illumos/dist/uts/common/fs/zfs/dmu_send.c vendor-sys/illumos/dist/uts/common/fs/zfs/dmu_traverse.c vendor-sys/illumos/dist/uts/common/fs/zfs/dmu_tx.c vendor-sys/illumos/dist/uts/common/fs/zfs/dnode.c vendor-sys/illumos/dist/uts/common/fs/zfs/dnode_sync.c vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_dataset.c vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_deleg.c vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_dir.c vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_pool.c vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_prop.c vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_scan.c vendor-sys/illumos/dist/uts/common/fs/zfs/dsl_synctask.c vendor-sys/illumos/dist/uts/common/fs/zfs/metaslab.c vendor-sys/illumos/dist/uts/common/fs/zfs/refcount.c vendor-sys/illumos/dist/uts/common/fs/zfs/rrwlock.c vendor-sys/illumos/dist/uts/common/fs/zfs/sa.c vendor-sys/illumos/dist/uts/common/fs/zfs/spa.c vendor-sys/illumos/dist/uts/common/fs/zfs/spa_history.c vendor-sys/illumos/dist/uts/common/fs/zfs/spa_misc.c vendor-sys/illumos/dist/uts/common/fs/zfs/space_map.c vendor-sys/illumos/dist/uts/common/fs/zfs/sys/arc.h vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dbuf.h vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dmu.h vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dmu_objset.h vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dmu_tx.h vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dsl_dataset.h vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dsl_dir.h vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dsl_pool.h vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dsl_prop.h vendor-sys/illumos/dist/uts/common/fs/zfs/sys/dsl_synctask.h vendor-sys/illumos/dist/uts/common/fs/zfs/sys/metaslab.h vendor-sys/illumos/dist/uts/common/fs/zfs/sys/refcount.h vendor-sys/illumos/dist/uts/common/fs/zfs/sys/rrwlock.h vendor-sys/illumos/dist/uts/common/fs/zfs/sys/space_map.h vendor-sys/illumos/dist/uts/common/fs/zfs/sys/txg.h vendor-sys/illumos/dist/uts/common/fs/zfs/sys/zfeature.h vendor-sys/illumos/dist/uts/common/fs/zfs/sys/zfs_debug.h vendor-sys/illumos/dist/uts/common/fs/zfs/sys/zfs_ioctl.h vendor-sys/illumos/dist/uts/common/fs/zfs/sys/zfs_znode.h vendor-sys/illumos/dist/uts/common/fs/zfs/sys/zil.h vendor-sys/illumos/dist/uts/common/fs/zfs/txg.c vendor-sys/illumos/dist/uts/common/fs/zfs/zfs_ctldir.c vendor-sys/illumos/dist/uts/common/fs/zfs/zfs_ioctl.c vendor-sys/illumos/dist/uts/common/fs/zfs/zfs_vfsops.c vendor-sys/illumos/dist/uts/common/fs/zfs/zil.c vendor-sys/illumos/dist/uts/common/fs/zfs/zio.c vendor-sys/illumos/dist/uts/common/fs/zfs/zvol.c vendor-sys/illumos/dist/uts/common/sys/nvpair.h Modified: vendor/illumos/dist/cmd/zdb/zdb.c ============================================================================== --- vendor/illumos/dist/cmd/zdb/zdb.c Fri Mar 1 20:51:53 2013 (r247579) +++ vendor/illumos/dist/cmd/zdb/zdb.c Fri Mar 1 21:01:45 2013 (r247580) @@ -1658,7 +1658,9 @@ dump_dir(objset_t *os) int print_header = 1; int i, error; + dsl_pool_config_enter(dmu_objset_pool(os), FTAG); dmu_objset_fast_stat(os, &dds); + dsl_pool_config_exit(dmu_objset_pool(os), FTAG); if (dds.dds_type < DMU_OST_NUMTYPES) type = objset_types[dds.dds_type]; @@ -2109,7 +2111,6 @@ zdb_blkptr_cb(spa_t *spa, zilog_t *zilog zio_nowait(zio_read(NULL, spa, bp, data, size, zdb_blkptr_done, zcb, ZIO_PRIORITY_ASYNC_READ, flags, zb)); - } zcb->zcb_readfails = 0; @@ -2297,8 +2298,10 @@ dump_block_stats(spa_t *spa) */ (void) bpobj_iterate_nofree(&spa->spa_deferred_bpobj, count_block_cb, &zcb, NULL); - (void) bpobj_iterate_nofree(&spa->spa_dsl_pool->dp_free_bpobj, - count_block_cb, &zcb, NULL); + if (spa_version(spa) >= SPA_VERSION_DEADLISTS) { + (void) bpobj_iterate_nofree(&spa->spa_dsl_pool->dp_free_bpobj, + count_block_cb, &zcb, NULL); + } if (spa_feature_is_active(spa, &spa_feature_table[SPA_FEATURE_ASYNC_DESTROY])) { VERIFY3U(0, ==, bptree_iterate(spa->spa_meta_objset, Modified: vendor/illumos/dist/cmd/zfs/zfs_main.c ============================================================================== --- vendor/illumos/dist/cmd/zfs/zfs_main.c Fri Mar 1 20:51:53 2013 (r247579) +++ vendor/illumos/dist/cmd/zfs/zfs_main.c Fri Mar 1 21:01:45 2013 (r247580) @@ -898,6 +898,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; @@ -994,9 +995,27 @@ destroy_callback(zfs_handle_t *zhp, void zfs_close(zhp); return (0); } + if (cb->cb_dryrun) { + zfs_close(zhp); + return (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 (!cb->cb_dryrun) { - if (zfs_unmount(zhp, NULL, cb->cb_force ? MS_FORCE : 0) != 0 || + 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); @@ -1152,8 +1171,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; @@ -1207,11 +1228,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], @@ -1222,17 +1241,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) { @@ -1251,18 +1268,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) @@ -1283,8 +1308,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; } /* @@ -1294,30 +1319,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 @@ -5052,28 +5089,12 @@ cleanup2: return (error); } -/* - * zfs allow [-r] [-t] ... - * - * -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] ... - * - * -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) { @@ -5087,7 +5108,6 @@ zfs_do_hold_rele_impl(int argc, char **a int i; const char *tag; boolean_t recursive = B_FALSE; - boolean_t temphold = B_FALSE; const char *opts = holding ? "rt" : "r"; int c; @@ -5097,9 +5117,6 @@ zfs_do_hold_rele_impl(int argc, char **a case 'r': recursive = B_TRUE; break; - case 't': - temphold = B_TRUE; - break; case '?': (void) fprintf(stderr, gettext("invalid option '%c'\n"), optopt); @@ -5148,7 +5165,7 @@ zfs_do_hold_rele_impl(int argc, char **a } 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) @@ -5164,7 +5181,6 @@ zfs_do_hold_rele_impl(int argc, char **a * zfs hold [-r] [-t] ... * * -r Recursively hold - * -t Temporary hold (hidden option) * * Apply a user-hold with the given tag to the list of snapshots. */ Modified: vendor/illumos/dist/cmd/zhack/zhack.c ============================================================================== --- vendor/illumos/dist/cmd/zhack/zhack.c Fri Mar 1 20:51:53 2013 (r247579) +++ vendor/illumos/dist/cmd/zhack/zhack.c Fri Mar 1 21:01:45 2013 (r247580) @@ -46,6 +46,7 @@ #include #include #include +#include #undef ZFS_MAXNAMELEN #undef verify #include @@ -273,10 +274,10 @@ zhack_do_feature_stat(int argc, char **a } static void -feature_enable_sync(void *arg1, void *arg2, dmu_tx_t *tx) +feature_enable_sync(void *arg, dmu_tx_t *tx) { - spa_t *spa = arg1; - zfeature_info_t *feature = arg2; + spa_t *spa = dmu_tx_pool(tx)->dp_spa; + zfeature_info_t *feature = arg; spa_feature_enable(spa, feature, tx); spa_history_log_internal(spa, "zhack enable feature", tx, @@ -344,8 +345,8 @@ zhack_do_feature_enable(int argc, char * if (0 == zap_contains(mos, spa->spa_feat_desc_obj, feature.fi_guid)) fatal("feature already enabled: %s", feature.fi_guid); - VERIFY3U(0, ==, dsl_sync_task_do(spa->spa_dsl_pool, NULL, - feature_enable_sync, spa, &feature, 5)); + VERIFY0(dsl_sync_task(spa_name(spa), NULL, + feature_enable_sync, &feature, 5)); spa_close(spa, FTAG); @@ -353,10 +354,10 @@ zhack_do_feature_enable(int argc, char * } static void -feature_incr_sync(void *arg1, void *arg2, dmu_tx_t *tx) +feature_incr_sync(void *arg, dmu_tx_t *tx) { - spa_t *spa = arg1; - zfeature_info_t *feature = arg2; + spa_t *spa = dmu_tx_pool(tx)->dp_spa; + zfeature_info_t *feature = arg; spa_feature_incr(spa, feature, tx); spa_history_log_internal(spa, "zhack feature incr", tx, @@ -364,10 +365,10 @@ feature_incr_sync(void *arg1, void *arg2 } static void -feature_decr_sync(void *arg1, void *arg2, dmu_tx_t *tx) +feature_decr_sync(void *arg, dmu_tx_t *tx) { - spa_t *spa = arg1; - zfeature_info_t *feature = arg2; + spa_t *spa = dmu_tx_pool(tx)->dp_spa; + zfeature_info_t *feature = arg; spa_feature_decr(spa, feature, tx); spa_history_log_internal(spa, "zhack feature decr", tx, @@ -442,8 +443,8 @@ zhack_do_feature_ref(int argc, char **ar if (decr && !spa_feature_is_active(spa, &feature)) fatal("feature refcount already 0: %s", feature.fi_guid); - VERIFY3U(0, ==, dsl_sync_task_do(spa->spa_dsl_pool, NULL, - decr ? feature_decr_sync : feature_incr_sync, spa, &feature, 5)); + VERIFY0(dsl_sync_task(spa_name(spa), NULL, + decr ? feature_decr_sync : feature_incr_sync, &feature, 5)); spa_close(spa, FTAG); } Modified: vendor/illumos/dist/cmd/ztest/ztest.c ============================================================================== --- vendor/illumos/dist/cmd/ztest/ztest.c Fri Mar 1 20:51:53 2013 (r247579) +++ vendor/illumos/dist/cmd/ztest/ztest.c Fri Mar 1 21:01:45 2013 (r247580) @@ -103,10 +103,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -365,7 +367,7 @@ ztest_info_t ztest_info[] = { { ztest_scrub, 1, &zopt_rarely }, { ztest_spa_upgrade, 1, &zopt_rarely }, { ztest_dsl_dataset_promote_busy, 1, &zopt_rarely }, - { ztest_vdev_attach_detach, 1, &zopt_rarely }, + { ztest_vdev_attach_detach, 1, &zopt_sometimes }, { ztest_vdev_LUN_growth, 1, &zopt_rarely }, { ztest_vdev_add_remove, 1, &ztest_opts.zo_vdevtime }, @@ -1006,9 +1008,8 @@ ztest_dsl_prop_set_uint64(char *osname, uint64_t curval; int error; - error = dsl_prop_set(osname, propname, - (inherit ? ZPROP_SRC_NONE : ZPROP_SRC_LOCAL), - sizeof (value), 1, &value); + error = dsl_prop_set_int(osname, propname, + (inherit ? ZPROP_SRC_NONE : ZPROP_SRC_LOCAL), value); if (error == ENOSPC) { ztest_record_enospc(FTAG); @@ -1016,8 +1017,7 @@ ztest_dsl_prop_set_uint64(char *osname, } ASSERT0(error); - VERIFY3U(dsl_prop_get(osname, propname, sizeof (curval), - 1, &curval, setpoint), ==, 0); + VERIFY0(dsl_prop_get_integer(osname, propname, &curval, setpoint)); if (ztest_opts.zo_verbose >= 6) { VERIFY(zfs_prop_index_to_string(prop, curval, &valname) == 0); @@ -2479,8 +2479,7 @@ ztest_vdev_add_remove(ztest_ds_t *zd, ui int error; VERIFY(mutex_lock(&ztest_vdev_lock) == 0); - leaves = - MAX(zs->zs_mirrors + zs->zs_splits, 1) * ztest_opts.zo_raidz; + leaves = MAX(zs->zs_mirrors + zs->zs_splits, 1) * ztest_opts.zo_raidz; spa_config_enter(spa, SCL_VDEV, FTAG, RW_READER); @@ -3180,7 +3179,7 @@ ztest_objset_destroy_cb(const char *name /* * Verify that the dataset contains a directory object. */ - VERIFY3U(0, ==, dmu_objset_hold(name, FTAG, &os)); + VERIFY0(dmu_objset_own(name, DMU_OST_OTHER, B_TRUE, FTAG, &os)); error = dmu_object_info(os, ZTEST_DIROBJ, &doi); if (error != ENOENT) { /* We could have crashed in the middle of destroying it */ @@ -3188,12 +3187,16 @@ ztest_objset_destroy_cb(const char *name ASSERT3U(doi.doi_type, ==, DMU_OT_ZAP_OTHER); ASSERT3S(doi.doi_physical_blocks_512, >=, 0); } - dmu_objset_rele(os, FTAG); + dmu_objset_disown(os, FTAG); /* * Destroy the dataset. */ - VERIFY3U(0, ==, dmu_objset_destroy(name, B_FALSE)); + if (strchr(name, '@') != NULL) { + VERIFY0(dsl_destroy_snapshot(name, B_FALSE)); + } else { + VERIFY0(dsl_destroy_head(name)); + } return (0); } @@ -3203,16 +3206,17 @@ ztest_snapshot_create(char *osname, uint char snapname[MAXNAMELEN]; int error; - (void) snprintf(snapname, MAXNAMELEN, "%s@%llu", osname, - (u_longlong_t)id); + (void) snprintf(snapname, sizeof (snapname), "%llu", (u_longlong_t)id); - error = dmu_objset_snapshot_one(osname, strchr(snapname, '@') + 1); + error = dmu_objset_snapshot_one(osname, snapname); if (error == ENOSPC) { ztest_record_enospc(FTAG); return (B_FALSE); } - if (error != 0 && error != EEXIST) - fatal(0, "ztest_snapshot_create(%s) = %d", snapname, error); + if (error != 0 && error != EEXIST) { + fatal(0, "ztest_snapshot_create(%s@%s) = %d", osname, + snapname, error); + } return (B_TRUE); } @@ -3225,7 +3229,7 @@ ztest_snapshot_destroy(char *osname, uin (void) snprintf(snapname, MAXNAMELEN, "%s@%llu", osname, (u_longlong_t)id); - error = dmu_objset_destroy(snapname, B_FALSE); + error = dsl_destroy_snapshot(snapname, B_FALSE); if (error != 0 && error != ENOENT) fatal(0, "ztest_snapshot_destroy(%s) = %d", snapname, error); return (B_TRUE); @@ -3271,7 +3275,8 @@ ztest_dmu_objset_create_destroy(ztest_ds /* * Verify that the destroyed dataset is no longer in the namespace. */ - VERIFY3U(ENOENT, ==, dmu_objset_hold(name, FTAG, &os)); + VERIFY3U(ENOENT, ==, dmu_objset_own(name, DMU_OST_OTHER, B_TRUE, + FTAG, &os)); /* * Verify that we can create a new dataset. @@ -3286,8 +3291,7 @@ ztest_dmu_objset_create_destroy(ztest_ds fatal(0, "dmu_objset_create(%s) = %d", name, error); } - VERIFY3U(0, ==, - dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, FTAG, &os)); + VERIFY0(dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, FTAG, &os)); ztest_zd_init(&zdtmp, NULL, os); @@ -3363,21 +3367,21 @@ ztest_dsl_dataset_cleanup(char *osname, (void) snprintf(clone2name, MAXNAMELEN, "%s/c2_%llu", osname, id); (void) snprintf(snap3name, MAXNAMELEN, "%s@s3_%llu", clone1name, id); - error = dmu_objset_destroy(clone2name, B_FALSE); + error = dsl_destroy_head(clone2name); if (error && error != ENOENT) - fatal(0, "dmu_objset_destroy(%s) = %d", clone2name, error); - error = dmu_objset_destroy(snap3name, B_FALSE); + fatal(0, "dsl_destroy_head(%s) = %d", clone2name, error); + error = dsl_destroy_snapshot(snap3name, B_FALSE); if (error && error != ENOENT) - fatal(0, "dmu_objset_destroy(%s) = %d", snap3name, error); - error = dmu_objset_destroy(snap2name, B_FALSE); + fatal(0, "dsl_destroy_snapshot(%s) = %d", snap3name, error); + error = dsl_destroy_snapshot(snap2name, B_FALSE); if (error && error != ENOENT) - fatal(0, "dmu_objset_destroy(%s) = %d", snap2name, error); - error = dmu_objset_destroy(clone1name, B_FALSE); + fatal(0, "dsl_destroy_snapshot(%s) = %d", snap2name, error); + error = dsl_destroy_head(clone1name); if (error && error != ENOENT) - fatal(0, "dmu_objset_destroy(%s) = %d", clone1name, error); - error = dmu_objset_destroy(snap1name, B_FALSE); + fatal(0, "dsl_destroy_head(%s) = %d", clone1name, error); + error = dsl_destroy_snapshot(snap1name, B_FALSE); if (error && error != ENOENT) - fatal(0, "dmu_objset_destroy(%s) = %d", snap1name, error); + fatal(0, "dsl_destroy_snapshot(%s) = %d", snap1name, error); } /* @@ -3386,8 +3390,7 @@ ztest_dsl_dataset_cleanup(char *osname, void ztest_dsl_dataset_promote_busy(ztest_ds_t *zd, uint64_t id) { - objset_t *clone; - dsl_dataset_t *ds; + objset_t *os; char snap1name[MAXNAMELEN]; char clone1name[MAXNAMELEN]; char snap2name[MAXNAMELEN]; @@ -3415,12 +3418,7 @@ ztest_dsl_dataset_promote_busy(ztest_ds_ fatal(0, "dmu_take_snapshot(%s) = %d", snap1name, error); } - error = dmu_objset_hold(snap1name, FTAG, &clone); - if (error) - fatal(0, "dmu_open_snapshot(%s) = %d", snap1name, error); - - error = dmu_objset_clone(clone1name, dmu_objset_ds(clone), 0); - dmu_objset_rele(clone, FTAG); + error = dmu_objset_clone(clone1name, snap1name); if (error) { if (error == ENOSPC) { ztest_record_enospc(FTAG); @@ -3447,12 +3445,7 @@ ztest_dsl_dataset_promote_busy(ztest_ds_ fatal(0, "dmu_open_snapshot(%s) = %d", snap3name, error); } - error = dmu_objset_hold(snap3name, FTAG, &clone); - if (error) - fatal(0, "dmu_open_snapshot(%s) = %d", snap3name, error); - - error = dmu_objset_clone(clone2name, dmu_objset_ds(clone), 0); - dmu_objset_rele(clone, FTAG); + error = dmu_objset_clone(clone2name, snap3name); if (error) { if (error == ENOSPC) { ztest_record_enospc(FTAG); @@ -3461,14 +3454,14 @@ ztest_dsl_dataset_promote_busy(ztest_ds_ fatal(0, "dmu_objset_create(%s) = %d", clone2name, error); } - error = dsl_dataset_own(snap2name, B_FALSE, FTAG, &ds); + error = dmu_objset_own(snap2name, DMU_OST_ANY, B_TRUE, FTAG, &os); if (error) - fatal(0, "dsl_dataset_own(%s) = %d", snap2name, error); + fatal(0, "dmu_objset_own(%s) = %d", snap2name, error); error = dsl_dataset_promote(clone2name, NULL); if (error != EBUSY) fatal(0, "dsl_dataset_promote(%s), %d, not EBUSY", clone2name, error); - dsl_dataset_disown(ds, FTAG); + dmu_objset_disown(os, FTAG); out: ztest_dsl_dataset_cleanup(osname, id); @@ -4280,7 +4273,7 @@ ztest_zap_parallel(ztest_ds_t *zd, uint6 } count = -1ULL; - VERIFY(zap_count(os, object, &count) == 0); + VERIFY0(zap_count(os, object, &count)); ASSERT(count != -1ULL); /* @@ -4591,6 +4584,22 @@ ztest_spa_prop_get_set(ztest_ds_t *zd, u (void) rw_unlock(&ztest_name_lock); } +static int +user_release_one(const char *snapname, const char *holdname) +{ + nvlist_t *snaps, *holds; + int error; + + snaps = fnvlist_alloc(); + holds = fnvlist_alloc(); + fnvlist_add_boolean(holds, holdname); + fnvlist_add_nvlist(snaps, snapname, holds); + fnvlist_free(holds); + error = dsl_dataset_user_release(snaps, NULL); + fnvlist_free(snaps); + return (error); +} + /* * Test snapshot hold/release and deferred destroy. */ @@ -4605,22 +4614,30 @@ ztest_dmu_snapshot_hold(ztest_ds_t *zd, char clonename[100]; char tag[100]; char osname[MAXNAMELEN]; + nvlist_t *holds; (void) rw_rdlock(&ztest_name_lock); dmu_objset_name(os, osname); - (void) snprintf(snapname, 100, "sh1_%llu", id); - (void) snprintf(fullname, 100, "%s@%s", osname, snapname); - (void) snprintf(clonename, 100, "%s/ch1_%llu", osname, id); - (void) snprintf(tag, 100, "%tag_%llu", id); + (void) snprintf(snapname, sizeof (snapname), "sh1_%llu", id); + (void) snprintf(fullname, sizeof (fullname), "%s@%s", osname, snapname); + (void) snprintf(clonename, sizeof (clonename), + "%s/ch1_%llu", osname, id); + (void) snprintf(tag, sizeof (tag), "tag_%llu", id); /* * Clean up from any previous run. */ - (void) dmu_objset_destroy(clonename, B_FALSE); - (void) dsl_dataset_user_release(osname, snapname, tag, B_FALSE); - (void) dmu_objset_destroy(fullname, B_FALSE); + error = dsl_destroy_head(clonename); + if (error != ENOENT) + ASSERT0(error); + error = user_release_one(fullname, tag); + if (error != ESRCH && error != ENOENT) + ASSERT0(error); + error = dsl_destroy_snapshot(fullname, B_FALSE); + if (error != ENOENT) + ASSERT0(error); /* * Create snapshot, clone it, mark snap for deferred destroy, @@ -4635,12 +4652,7 @@ ztest_dmu_snapshot_hold(ztest_ds_t *zd, fatal(0, "dmu_objset_snapshot(%s) = %d", fullname, error); } - error = dmu_objset_hold(fullname, FTAG, &origin); - if (error) - fatal(0, "dmu_objset_hold(%s) = %d", fullname, error); - - error = dmu_objset_clone(clonename, dmu_objset_ds(origin), 0); - dmu_objset_rele(origin, FTAG); + error = dmu_objset_clone(clonename, fullname); if (error) { if (error == ENOSPC) { ztest_record_enospc("dmu_objset_clone"); @@ -4649,15 +4661,15 @@ ztest_dmu_snapshot_hold(ztest_ds_t *zd, fatal(0, "dmu_objset_clone(%s) = %d", clonename, error); } - error = dmu_objset_destroy(fullname, B_TRUE); + error = dsl_destroy_snapshot(fullname, B_TRUE); if (error) { - fatal(0, "dmu_objset_destroy(%s, B_TRUE) = %d", + fatal(0, "dsl_destroy_snapshot(%s, B_TRUE) = %d", fullname, error); } - error = dmu_objset_destroy(clonename, B_FALSE); + error = dsl_destroy_head(clonename); if (error) - fatal(0, "dmu_objset_destroy(%s) = %d", clonename, error); + fatal(0, "dsl_destroy_head(%s) = %d", clonename, error); error = dmu_objset_hold(fullname, FTAG, &origin); if (error != ENOENT) @@ -4677,28 +4689,31 @@ ztest_dmu_snapshot_hold(ztest_ds_t *zd, fatal(0, "dmu_objset_snapshot(%s) = %d", fullname, error); } - error = dsl_dataset_user_hold(osname, snapname, tag, B_FALSE, - B_TRUE, -1); + holds = fnvlist_alloc(); + fnvlist_add_string(holds, fullname, tag); + error = dsl_dataset_user_hold(holds, 0, NULL); + fnvlist_free(holds); + if (error) fatal(0, "dsl_dataset_user_hold(%s)", fullname, tag); - error = dmu_objset_destroy(fullname, B_FALSE); + error = dsl_destroy_snapshot(fullname, B_FALSE); if (error != EBUSY) { - fatal(0, "dmu_objset_destroy(%s, B_FALSE) = %d", + fatal(0, "dsl_destroy_snapshot(%s, B_FALSE) = %d", fullname, error); } - error = dmu_objset_destroy(fullname, B_TRUE); + error = dsl_destroy_snapshot(fullname, B_TRUE); if (error) { - fatal(0, "dmu_objset_destroy(%s, B_TRUE) = %d", + fatal(0, "dsl_destroy_snapshot(%s, B_TRUE) = %d", fullname, error); } - error = dsl_dataset_user_release(osname, snapname, tag, B_FALSE); + error = user_release_one(fullname, tag); if (error) - fatal(0, "dsl_dataset_user_release(%s)", fullname, tag); + fatal(0, "user_release_one(%s)", fullname, tag); - VERIFY(dmu_objset_hold(fullname, FTAG, &origin) == ENOENT); + VERIFY3U(dmu_objset_hold(fullname, FTAG, &origin), ==, ENOENT); out: (void) rw_unlock(&ztest_name_lock); @@ -4952,8 +4967,12 @@ ztest_ddt_repair(ztest_ds_t *zd, uint64_ */ for (int i = 0; i < copies; i++) { uint64_t offset = i * blocksize; - VERIFY0(dmu_buf_hold(os, object, offset, FTAG, &db, - DMU_READ_NO_PREFETCH)); + int error = dmu_buf_hold(os, object, offset, FTAG, &db, + DMU_READ_NO_PREFETCH); + if (error != 0) { + fatal(B_FALSE, "dmu_buf_hold(%p, %llu, %llu) = %u", + os, (long long)object, (long long) offset, error); + } ASSERT(db->db_offset == offset); ASSERT(db->db_size == blocksize); ASSERT(ztest_pattern_match(db->db_data, db->db_size, pattern) || @@ -5163,6 +5182,7 @@ ztest_spa_import_export(char *oldname, c nvlist_t *config, *newconfig; uint64_t pool_guid; spa_t *spa; + int error; if (ztest_opts.zo_verbose >= 4) { (void) printf("import/export: old = %s, new = %s\n", @@ -5207,7 +5227,12 @@ ztest_spa_import_export(char *oldname, c /* * Import it under the new name. */ - VERIFY3U(0, ==, spa_import(newname, config, NULL, 0)); + error = spa_import(newname, config, NULL, 0); + if (error != 0) { + dump_nvlist(config, 0); + fatal(B_FALSE, "couldn't import pool %s as %s: error %u", + oldname, newname, error); + } ztest_walk_pool_directory("pools after import"); @@ -5414,7 +5439,7 @@ ztest_dataset_open(int d) } ASSERT(error == 0 || error == EEXIST); - VERIFY0(dmu_objset_hold(name, zd, &os)); + VERIFY0(dmu_objset_own(name, DMU_OST_OTHER, B_FALSE, zd, &os)); (void) rw_unlock(&ztest_name_lock); ztest_zd_init(zd, ZTEST_GET_SHARED_DS(d), os); @@ -5455,7 +5480,7 @@ ztest_dataset_close(int d) ztest_ds_t *zd = &ztest_ds[d]; zil_close(zd->zd_zilog); - dmu_objset_rele(zd->zd_os, zd); + dmu_objset_disown(zd->zd_os, zd); ztest_zd_fini(zd); } @@ -5499,13 +5524,14 @@ ztest_run(ztest_shared_t *zs) * Open our pool. */ kernel_init(FREAD | FWRITE); - VERIFY(spa_open(ztest_opts.zo_pool, &spa, FTAG) == 0); + VERIFY0(spa_open(ztest_opts.zo_pool, &spa, FTAG)); spa->spa_debug = B_TRUE; ztest_spa = spa; - VERIFY3U(0, ==, dmu_objset_hold(ztest_opts.zo_pool, FTAG, &os)); + VERIFY0(dmu_objset_own(ztest_opts.zo_pool, + DMU_OST_ANY, B_TRUE, FTAG, &os)); zs->zs_guid = dmu_objset_fsid_guid(os); - dmu_objset_rele(os, FTAG); + dmu_objset_disown(os, FTAG); spa->spa_dedup_ditto = 2 * ZIO_DEDUPDITTO_MIN; Modified: vendor/illumos/dist/lib/libzfs/common/libzfs.h ============================================================================== --- vendor/illumos/dist/lib/libzfs/common/libzfs.h Fri Mar 1 20:51:53 2013 (r247579) +++ vendor/illumos/dist/lib/libzfs/common/libzfs.h Fri Mar 1 21:01:45 2013 (r247580) @@ -550,7 +550,7 @@ extern int zfs_create(libzfs_handle_t *, extern int zfs_create_ancestors(libzfs_handle_t *, const char *); extern int zfs_destroy(zfs_handle_t *, boolean_t); extern int zfs_destroy_snaps(zfs_handle_t *, char *, boolean_t); -extern int zfs_destroy_snaps_nvl(zfs_handle_t *, nvlist_t *, boolean_t); +extern int zfs_destroy_snaps_nvl(libzfs_handle_t *, nvlist_t *, boolean_t); extern int zfs_clone(zfs_handle_t *, const char *, nvlist_t *); extern int zfs_snapshot(libzfs_handle_t *, const char *, boolean_t, nvlist_t *); extern int zfs_snapshot_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, @@ -593,8 +593,8 @@ extern int zfs_send(zfs_handle_t *, cons sendflags_t *, int, snapfilter_cb_t, void *, nvlist_t **); extern int zfs_promote(zfs_handle_t *); -extern int zfs_hold(zfs_handle_t *, const char *, const char *, boolean_t, - boolean_t, boolean_t, int, uint64_t, uint64_t); +extern int zfs_hold(zfs_handle_t *, const char *, const char *, + boolean_t, boolean_t, int); extern int zfs_release(zfs_handle_t *, const char *, const char *, boolean_t); extern int zfs_get_holds(zfs_handle_t *, nvlist_t **); extern uint64_t zvol_volsize_to_reservation(uint64_t, nvlist_t *); Modified: vendor/illumos/dist/lib/libzfs/common/libzfs_dataset.c ============================================================================== --- vendor/illumos/dist/lib/libzfs/common/libzfs_dataset.c Fri Mar 1 20:51:53 2013 (r247579) +++ vendor/illumos/dist/lib/libzfs/common/libzfs_dataset.c Fri Mar 1 21:01:45 2013 (r247580) @@ -1973,10 +1973,7 @@ get_clones_cb(zfs_handle_t *zhp, void *a NULL, NULL, 0, B_TRUE) != 0) goto out; if (strcmp(gca->buf, gca->origin) == 0) { - if (nvlist_add_boolean(gca->value, zfs_get_name(zhp)) != 0) { - zfs_close(zhp); - return (no_memory(zhp->zfs_hdl)); - } + fnvlist_add_boolean(gca->value, zfs_get_name(zhp)); gca->numclones--; } @@ -3142,45 +3139,49 @@ zfs_destroy_snaps(zfs_handle_t *zhp, cha dgettext(TEXT_DOMAIN, "cannot destroy '%s@%s'"), zhp->zfs_name, snapname); } else { - ret = zfs_destroy_snaps_nvl(zhp, dd.nvl, defer); + ret = zfs_destroy_snaps_nvl(zhp->zfs_hdl, dd.nvl, defer); } nvlist_free(dd.nvl); return (ret); } /* - * Destroys all the snapshots named in the nvlist. They must be underneath - * the zhp (either snapshots of it, or snapshots of its descendants). + * Destroys all the snapshots named in the nvlist. */ int -zfs_destroy_snaps_nvl(zfs_handle_t *zhp, nvlist_t *snaps, boolean_t defer) +zfs_destroy_snaps_nvl(libzfs_handle_t *hdl, nvlist_t *snaps, boolean_t defer) { int ret; nvlist_t *errlist; ret = lzc_destroy_snaps(snaps, defer, &errlist); - if (ret != 0) { - for (nvpair_t *pair = nvlist_next_nvpair(errlist, NULL); - pair != NULL; pair = nvlist_next_nvpair(errlist, pair)) { - char errbuf[1024]; - (void) snprintf(errbuf, sizeof (errbuf), - dgettext(TEXT_DOMAIN, "cannot destroy snapshot %s"), - nvpair_name(pair)); + if (ret == 0) + return (0); - switch (fnvpair_value_int32(pair)) { - case EEXIST: - zfs_error_aux(zhp->zfs_hdl, - dgettext(TEXT_DOMAIN, - "snapshot is cloned")); - ret = zfs_error(zhp->zfs_hdl, EZFS_EXISTS, - errbuf); - break; - default: - ret = zfs_standard_error(zhp->zfs_hdl, errno, - errbuf); - break; - } + if (nvlist_next_nvpair(errlist, NULL) == NULL) { + char errbuf[1024]; + (void) snprintf(errbuf, sizeof (errbuf), + dgettext(TEXT_DOMAIN, "cannot destroy snapshots")); + + ret = zfs_standard_error(hdl, ret, errbuf); + } + for (nvpair_t *pair = nvlist_next_nvpair(errlist, NULL); + pair != NULL; pair = nvlist_next_nvpair(errlist, pair)) { + char errbuf[1024]; + (void) snprintf(errbuf, sizeof (errbuf), + dgettext(TEXT_DOMAIN, "cannot destroy snapshot %s"), + nvpair_name(pair)); + + switch (fnvpair_value_int32(pair)) { + case EEXIST: + zfs_error_aux(hdl, + dgettext(TEXT_DOMAIN, "snapshot is cloned")); + ret = zfs_error(hdl, EZFS_EXISTS, errbuf); + break; + default: + ret = zfs_standard_error(hdl, errno, errbuf); + break; } } @@ -4047,7 +4048,7 @@ zfs_userspace(zfs_handle_t *zhp, zfs_use zc.zc_nvlist_dst_size = sizeof (buf); if (zfs_ioctl(hdl, ZFS_IOC_USERSPACE_MANY, &zc) != 0) { - char errbuf[ZFS_MAXNAMELEN + 32]; + char errbuf[1024]; (void) snprintf(errbuf, sizeof (errbuf), dgettext(TEXT_DOMAIN, @@ -4069,37 +4070,83 @@ zfs_userspace(zfs_handle_t *zhp, zfs_use return (0); } +struct holdarg { + nvlist_t *nvl; + const char *snapname; + const char *tag; + boolean_t recursive; +}; + +static int +zfs_hold_one(zfs_handle_t *zhp, void *arg) +{ + struct holdarg *ha = arg; + zfs_handle_t *szhp; + char name[ZFS_MAXNAMELEN]; + int rv = 0; + + (void) snprintf(name, sizeof (name), + "%s@%s", zhp->zfs_name, ha->snapname); + + szhp = make_dataset_handle(zhp->zfs_hdl, name); + if (szhp) { + fnvlist_add_string(ha->nvl, name, ha->tag); + zfs_close(szhp); + } + + if (ha->recursive) + rv = zfs_iter_filesystems(zhp, zfs_hold_one, ha); + zfs_close(zhp); + return (rv); +} + int zfs_hold(zfs_handle_t *zhp, const char *snapname, const char *tag, - boolean_t recursive, boolean_t temphold, boolean_t enoent_ok, - int cleanup_fd, uint64_t dsobj, uint64_t createtxg) + boolean_t recursive, boolean_t enoent_ok, int cleanup_fd) { - zfs_cmd_t zc = { 0 }; + int ret; + struct holdarg ha; + nvlist_t *errors; libzfs_handle_t *hdl = zhp->zfs_hdl; + char errbuf[1024]; + nvpair_t *elem; - ASSERT(!recursive || dsobj == 0); + ha.nvl = fnvlist_alloc(); + ha.snapname = snapname; + ha.tag = tag; + ha.recursive = recursive; + (void) zfs_hold_one(zfs_handle_dup(zhp), &ha); + ret = lzc_hold(ha.nvl, cleanup_fd, &errors); + fnvlist_free(ha.nvl); - (void) strlcpy(zc.zc_name, zhp->zfs_name, sizeof (zc.zc_name)); - (void) strlcpy(zc.zc_value, snapname, sizeof (zc.zc_value)); - if (strlcpy(zc.zc_string, tag, sizeof (zc.zc_string)) - >= sizeof (zc.zc_string)) - return (zfs_error(hdl, EZFS_TAGTOOLONG, tag)); - zc.zc_cookie = recursive; - zc.zc_temphold = temphold; - zc.zc_cleanup_fd = cleanup_fd; - zc.zc_sendobj = dsobj; - zc.zc_createtxg = createtxg; + if (ret == 0) + return (0); - if (zfs_ioctl(hdl, ZFS_IOC_HOLD, &zc) != 0) { - char errbuf[ZFS_MAXNAMELEN+32]; + if (nvlist_next_nvpair(errors, NULL) == NULL) { + /* no hold-specific errors */ + (void) snprintf(errbuf, sizeof (errbuf), + dgettext(TEXT_DOMAIN, "cannot hold")); + switch (ret) { + case ENOTSUP: + zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, + "pool must be upgraded")); + (void) zfs_error(hdl, EZFS_BADVERSION, errbuf); + break; + case EINVAL: + (void) zfs_error(hdl, EZFS_BADTYPE, errbuf); + break; + default: *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***