Mercurial > illumos > illumos-gate
changeset 10693:aaa91fcac595
6871683 ztest should exercise deferred destroy
author | Chris Kirby <chris.kirby@sun.com> |
---|---|
date | Wed, 30 Sep 2009 11:27:15 -0600 |
parents | ab0b8119c0e1 |
children | 584d721decf9 |
files | usr/src/cmd/ztest/ztest.c usr/src/uts/common/fs/zfs/zfs_ioctl.c usr/src/uts/common/fs/zfs/zvol.c |
diffstat | 3 files changed, 117 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/ztest/ztest.c Wed Sep 30 12:12:33 2009 -0400 +++ b/usr/src/cmd/ztest/ztest.c Wed Sep 30 11:27:15 2009 -0600 @@ -185,6 +185,7 @@ ztest_func_t ztest_vdev_add_remove; ztest_func_t ztest_vdev_aux_add_remove; ztest_func_t ztest_scrub; +ztest_func_t ztest_dmu_snapshot_hold; typedef struct ztest_info { ztest_func_t *zi_func; /* test function */ @@ -215,6 +216,7 @@ { ztest_dmu_snapshot_create_destroy, 1, &zopt_sometimes }, { ztest_spa_create_destroy, 1, &zopt_sometimes }, { ztest_fault_inject, 1, &zopt_sometimes }, + { ztest_dmu_snapshot_hold, 1, &zopt_sometimes }, { ztest_spa_rename, 1, &zopt_rarely }, { ztest_vdev_attach_detach, 1, &zopt_rarely }, { ztest_vdev_LUN_growth, 1, &zopt_rarely }, @@ -3468,6 +3470,119 @@ } /* + * Test snapshot hold/release and deferred destroy. + */ +void +ztest_dmu_snapshot_hold(ztest_args_t *za) +{ + int error; + objset_t *os = za->za_os; + objset_t *origin; + uint64_t curval = za->za_instance; + char snapname[100]; + char fullname[100]; + char clonename[100]; + char tag[100]; + char osname[MAXNAMELEN]; + + (void) rw_rdlock(&ztest_shared->zs_name_lock); + + dmu_objset_name(os, osname); + + (void) snprintf(snapname, 100, "sh1_%llu", curval); + (void) snprintf(fullname, 100, "%s@%s", osname, snapname); + (void) snprintf(clonename, 100, "%s/ch1_%llu", osname, curval); + (void) snprintf(tag, 100, "%tag_%llu", curval); + + /* + * 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); + + /* + * Create snapshot, clone it, mark snap for deferred destroy, + * destroy clone, verify snap was also destroyed. + */ + error = dmu_objset_snapshot(osname, snapname, NULL, FALSE); + if (error) { + if (error == ENOSPC) { + ztest_record_enospc("dmu_objset_snapshot"); + goto out; + } + 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); + if (error) { + if (error == ENOSPC) { + ztest_record_enospc("dmu_objset_clone"); + goto out; + } + fatal(0, "dmu_objset_clone(%s) = %d", clonename, error); + } + + error = dmu_objset_destroy(fullname, B_TRUE); + if (error) { + fatal(0, "dmu_objset_destroy(%s, B_TRUE) = %d", + fullname, error); + } + + error = dmu_objset_destroy(clonename, B_FALSE); + if (error) + fatal(0, "dmu_objset_destroy(%s) = %d", clonename, error); + + error = dmu_objset_hold(fullname, FTAG, &origin); + if (error != ENOENT) + fatal(0, "dmu_objset_hold(%s) = %d", fullname, error); + + /* + * Create snapshot, add temporary hold, verify that we can't + * destroy a held snapshot, mark for deferred destroy, + * release hold, verify snapshot was destroyed. + */ + error = dmu_objset_snapshot(osname, snapname, NULL, FALSE); + if (error) { + if (error == ENOSPC) { + ztest_record_enospc("dmu_objset_snapshot"); + goto out; + } + fatal(0, "dmu_objset_snapshot(%s) = %d", fullname, error); + } + + error = dsl_dataset_user_hold(osname, snapname, tag, B_FALSE, B_TRUE); + if (error) + fatal(0, "dsl_dataset_user_hold(%s)", fullname, tag); + + error = dmu_objset_destroy(fullname, B_FALSE); + if (error != EBUSY) { + fatal(0, "dmu_objset_destroy(%s, B_FALSE) = %d", + fullname, error); + } + + error = dmu_objset_destroy(fullname, B_TRUE); + if (error) { + fatal(0, "dmu_objset_destroy(%s, B_TRUE) = %d", + fullname, error); + } + + error = dsl_dataset_user_release(osname, snapname, tag, B_FALSE); + if (error) + fatal(0, "dsl_dataset_user_release(%s)", fullname, tag); + + VERIFY(dmu_objset_hold(fullname, FTAG, &origin) == ENOENT); + +out: + (void) rw_unlock(&ztest_shared->zs_name_lock); +} + +/* * Inject random faults into the on-disk data. */ void
--- a/usr/src/uts/common/fs/zfs/zfs_ioctl.c Wed Sep 30 12:12:33 2009 -0400 +++ b/usr/src/uts/common/fs/zfs/zfs_ioctl.c Wed Sep 30 11:27:15 2009 -0600 @@ -2567,7 +2567,7 @@ err = dmu_objset_destroy(zc->zc_name, zc->zc_defer_destroy); if (zc->zc_objset_type == DMU_OST_ZVOL && err == 0) - zvol_remove_minor(zc->zc_name); + (void) zvol_remove_minor(zc->zc_name); return (err); }
--- a/usr/src/uts/common/fs/zfs/zvol.c Wed Sep 30 12:12:33 2009 -0400 +++ b/usr/src/uts/common/fs/zfs/zvol.c Wed Sep 30 11:27:15 2009 -0600 @@ -1771,7 +1771,7 @@ dmu_tx_abort(tx); return (error); } - dmu_object_set_blocksize(os, ZVOL_OBJ, vbs, 0, tx); + (void) dmu_object_set_blocksize(os, ZVOL_OBJ, vbs, 0, tx); dmu_tx_commit(tx); return (0);