Mercurial > illumos > illumos-gate
diff usr/src/uts/common/fs/zfs/dsl_dataset.c @ 13743:95aba6e49b9f
2882 implement libzfs_core
2883 changing "canmount" property to "on" should not always remount dataset
2900 "zfs snapshot" should be able to create multiple, arbitrary snapshots at once
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Chris Siden <christopher.siden@delphix.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Bill Pijewski <wdp@joyent.com>
Reviewed by: Dan Kruchinin <dan.kruchinin@gmail.com>
Approved by: Eric Schrock <Eric.Schrock@delphix.com>
author | Matthew Ahrens <mahrens@delphix.com> |
---|---|
date | Sat, 30 Jun 2012 13:00:47 -0700 |
parents | 2889e2596bd6 |
children | 38b4aca480b3 |
line wrap: on
line diff
--- a/usr/src/uts/common/fs/zfs/dsl_dataset.c Thu Jun 14 12:09:31 2012 +0400 +++ b/usr/src/uts/common/fs/zfs/dsl_dataset.c Sat Jun 30 13:00:47 2012 -0700 @@ -914,7 +914,8 @@ * The snapshots must all be in the same pool. */ int -dmu_snapshots_destroy_nvl(nvlist_t *snaps, boolean_t defer, char *failed) +dmu_snapshots_destroy_nvl(nvlist_t *snaps, boolean_t defer, + nvlist_t *errlist) { int err; dsl_sync_task_t *dst; @@ -949,7 +950,7 @@ } else if (err == ENOENT) { err = 0; } else { - (void) strcpy(failed, nvpair_name(pair)); + fnvlist_add_int32(errlist, nvpair_name(pair), err); break; } } @@ -963,10 +964,12 @@ dsl_dataset_t *ds = dsda->ds; /* - * Return the file system name that triggered the error + * Return the snapshots that triggered the error. */ - if (dst->dst_err) { - dsl_dataset_name(ds, failed); + if (dst->dst_err != 0) { + char name[ZFS_MAXNAMELEN]; + dsl_dataset_name(ds, name); + fnvlist_add_int32(errlist, name, dst->dst_err); } ASSERT3P(dsda->rm_origin, ==, NULL); dsl_dataset_disown(ds, dstg); @@ -1045,7 +1048,6 @@ dsl_dir_t *dd; uint64_t obj; struct dsl_ds_destroyarg dsda = { 0 }; - dsl_dataset_t dummy_ds = { 0 }; dsda.ds = ds; @@ -1065,8 +1067,6 @@ } dd = ds->ds_dir; - dummy_ds.ds_dir = dd; - dummy_ds.ds_object = ds->ds_object; /* * Check for errors and mark this ds as inconsistent, in @@ -1153,7 +1153,7 @@ dsl_sync_task_create(dstg, dsl_dataset_destroy_check, dsl_dataset_destroy_sync, &dsda, tag, 0); dsl_sync_task_create(dstg, dsl_dir_destroy_check, - dsl_dir_destroy_sync, &dummy_ds, FTAG, 0); + dsl_dir_destroy_sync, dd, FTAG, 0); err = dsl_sync_task_group_wait(dstg); dsl_sync_task_group_destroy(dstg); @@ -1328,14 +1328,12 @@ dsl_dataset_destroy_begin_sync(void *arg1, void *arg2, dmu_tx_t *tx) { dsl_dataset_t *ds = arg1; - dsl_pool_t *dp = ds->ds_dir->dd_pool; /* Mark it as inconsistent on-disk, in case we crash */ dmu_buf_will_dirty(ds->ds_dbuf, tx); ds->ds_phys->ds_flags |= DS_FLAG_INCONSISTENT; - spa_history_log_internal(LOG_DS_DESTROY_BEGIN, dp->dp_spa, tx, - "dataset = %llu", ds->ds_object); + spa_history_log_internal_ds(ds, "destroy begin", tx, ""); } static int @@ -1660,9 +1658,13 @@ ASSERT(spa_version(dp->dp_spa) >= SPA_VERSION_USERREFS); dmu_buf_will_dirty(ds->ds_dbuf, tx); ds->ds_phys->ds_flags |= DS_FLAG_DEFER_DESTROY; + spa_history_log_internal_ds(ds, "defer_destroy", tx, ""); return; } + /* We need to log before removing it from the namespace. */ + spa_history_log_internal_ds(ds, "destroy", tx, ""); + /* signal any waiters that this dataset is going away */ mutex_enter(&ds->ds_lock); ds->ds_owner = dsl_reaper; @@ -1957,8 +1959,6 @@ dsl_dataset_rele(ds_prev, FTAG); spa_prop_clear_bootfs(dp->dp_spa, ds->ds_object, tx); - spa_history_log_internal(LOG_DS_DESTROY, dp->dp_spa, tx, - "dataset = %llu", ds->ds_object); if (ds->ds_phys->ds_next_clones_obj != 0) { uint64_t count; @@ -2006,7 +2006,7 @@ return (ENOSPC); /* - * Propogate any reserved space for this snapshot to other + * Propagate any reserved space for this snapshot to other * snapshot checks in this sync group. */ if (asize > 0) @@ -2016,10 +2016,9 @@ } int -dsl_dataset_snapshot_check(void *arg1, void *arg2, dmu_tx_t *tx) +dsl_dataset_snapshot_check(dsl_dataset_t *ds, const char *snapname, + dmu_tx_t *tx) { - dsl_dataset_t *ds = arg1; - const char *snapname = arg2; int err; uint64_t value; @@ -2031,7 +2030,7 @@ return (EAGAIN); /* - * Check for conflicting name snapshot name. + * Check for conflicting snapshot name. */ err = dsl_dataset_snap_lookup(ds, snapname, &value); if (err == 0) @@ -2055,10 +2054,9 @@ } void -dsl_dataset_snapshot_sync(void *arg1, void *arg2, dmu_tx_t *tx) +dsl_dataset_snapshot_sync(dsl_dataset_t *ds, const char *snapname, + dmu_tx_t *tx) { - dsl_dataset_t *ds = arg1; - const char *snapname = arg2; dsl_pool_t *dp = ds->ds_dir->dd_pool; dmu_buf_t *dbuf; dsl_dataset_phys_t *dsphys; @@ -2164,8 +2162,7 @@ dsl_dir_snap_cmtime_update(ds->ds_dir); - spa_history_log_internal(LOG_DS_SNAPSHOT, dp->dp_spa, tx, - "dataset = %llu", dsobj); + spa_history_log_internal_ds(ds->ds_prev, "snapshot", tx, ""); } void @@ -2252,7 +2249,20 @@ { uint64_t refd, avail, uobjs, aobjs, ratio; - dsl_dir_stats(ds->ds_dir, nv); + ratio = ds->ds_phys->ds_compressed_bytes == 0 ? 100 : + (ds->ds_phys->ds_uncompressed_bytes * 100 / + ds->ds_phys->ds_compressed_bytes); + + dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFRATIO, ratio); + + if (dsl_dataset_is_snapshot(ds)) { + dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_COMPRESSRATIO, ratio); + dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USED, + ds->ds_phys->ds_unique_bytes); + get_clones_stat(ds, nv); + } else { + dsl_dir_stats(ds->ds_dir, nv); + } dsl_dataset_space(ds, &refd, &avail, &uobjs, &aobjs); dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_AVAILABLE, avail); @@ -2297,22 +2307,6 @@ } } - ratio = ds->ds_phys->ds_compressed_bytes == 0 ? 100 : - (ds->ds_phys->ds_uncompressed_bytes * 100 / - ds->ds_phys->ds_compressed_bytes); - dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_REFRATIO, ratio); - - if (ds->ds_phys->ds_next_snap_obj) { - /* - * This is a snapshot; override the dd's space used with - * our unique space and compression ratio. - */ - dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_USED, - ds->ds_phys->ds_unique_bytes); - dsl_prop_nvlist_add_uint64(nv, ZFS_PROP_COMPRESSRATIO, ratio); - - get_clones_stat(ds, nv); - } } void @@ -2321,27 +2315,25 @@ stat->dds_creation_txg = ds->ds_phys->ds_creation_txg; stat->dds_inconsistent = ds->ds_phys->ds_flags & DS_FLAG_INCONSISTENT; stat->dds_guid = ds->ds_phys->ds_guid; - if (ds->ds_phys->ds_next_snap_obj) { + stat->dds_origin[0] = '\0'; + if (dsl_dataset_is_snapshot(ds)) { stat->dds_is_snapshot = B_TRUE; stat->dds_num_clones = ds->ds_phys->ds_num_children - 1; } else { stat->dds_is_snapshot = B_FALSE; stat->dds_num_clones = 0; + + rw_enter(&ds->ds_dir->dd_pool->dp_config_rwlock, RW_READER); + if (dsl_dir_is_clone(ds->ds_dir)) { + dsl_dataset_t *ods; + + VERIFY(0 == dsl_dataset_get_ref(ds->ds_dir->dd_pool, + ds->ds_dir->dd_phys->dd_origin_obj, FTAG, &ods)); + dsl_dataset_name(ods, stat->dds_origin); + dsl_dataset_drop_ref(ods, FTAG); + } + rw_exit(&ds->ds_dir->dd_pool->dp_config_rwlock); } - - /* clone origin is really a dsl_dir thing... */ - rw_enter(&ds->ds_dir->dd_pool->dp_config_rwlock, RW_READER); - if (dsl_dir_is_clone(ds->ds_dir)) { - dsl_dataset_t *ods; - - VERIFY(0 == dsl_dataset_get_ref(ds->ds_dir->dd_pool, - ds->ds_dir->dd_phys->dd_origin_obj, FTAG, &ods)); - dsl_dataset_name(ods, stat->dds_origin); - dsl_dataset_drop_ref(ods, FTAG); - } else { - stat->dds_origin[0] = '\0'; - } - rw_exit(&ds->ds_dir->dd_pool->dp_config_rwlock); } uint64_t @@ -2458,8 +2450,8 @@ ds->ds_snapname, 8, 1, &ds->ds_object, tx); ASSERT3U(err, ==, 0); - spa_history_log_internal(LOG_DS_RENAME, dd->dd_pool->dp_spa, tx, - "dataset = %llu", ds->ds_object); + spa_history_log_internal_ds(ds, "rename", tx, + "-> @%s", newsnapname); dsl_dataset_rele(hds, FTAG); } @@ -2939,8 +2931,7 @@ origin_ds->ds_phys->ds_unique_bytes = pa->unique; /* log history record */ - spa_history_log_internal(LOG_DS_PROMOTE, dd->dd_pool->dp_spa, tx, - "dataset = %llu", hds->ds_object); + spa_history_log_internal_ds(hds, "promote", tx, ""); dsl_dir_close(odd, FTAG); } @@ -3298,6 +3289,9 @@ csa->ohds->ds_phys->ds_deadlist_obj); dsl_scan_ds_clone_swapped(csa->ohds, csa->cds, tx); + + spa_history_log_internal_ds(csa->cds, "clone swap", tx, + "parent=%s", csa->ohds->ds_dir->dd_myname); } /* @@ -3454,9 +3448,8 @@ dmu_buf_will_dirty(ds->ds_dbuf, tx); ds->ds_quota = effective_value; - spa_history_log_internal(LOG_DS_REFQUOTA, - ds->ds_dir->dd_pool->dp_spa, tx, "%lld dataset = %llu ", - (longlong_t)ds->ds_quota, ds->ds_object); + spa_history_log_internal_ds(ds, "set refquota", tx, + "refquota=%lld", (longlong_t)ds->ds_quota); } } @@ -3561,9 +3554,8 @@ dsl_dir_diduse_space(ds->ds_dir, DD_USED_REFRSRV, delta, 0, 0, tx); mutex_exit(&ds->ds_dir->dd_lock); - spa_history_log_internal(LOG_DS_REFRESERV, - ds->ds_dir->dd_pool->dp_spa, tx, "%lld dataset = %llu", - (longlong_t)effective_value, ds->ds_object); + spa_history_log_internal_ds(ds, "set refreservation", tx, + "refreservation=%lld", (longlong_t)effective_value); } int @@ -3629,7 +3621,7 @@ { dsl_dataset_t *ds = arg1; struct dsl_ds_holdarg *ha = arg2; - char *htag = ha->htag; + const char *htag = ha->htag; objset_t *mos = ds->ds_dir->dd_pool->dp_meta_objset; int error = 0; @@ -3663,7 +3655,7 @@ { dsl_dataset_t *ds = arg1; struct dsl_ds_holdarg *ha = arg2; - char *htag = ha->htag; + const char *htag = ha->htag; dsl_pool_t *dp = ds->ds_dir->dd_pool; objset_t *mos = dp->dp_meta_objset; uint64_t now = gethrestime_sec(); @@ -3691,9 +3683,9 @@ htag, &now, tx)); } - spa_history_log_internal(LOG_DS_USER_HOLD, - dp->dp_spa, tx, "<%s> temp = %d dataset = %llu", htag, - (int)ha->temphold, ds->ds_object); + spa_history_log_internal_ds(ds, "hold", tx, + "tag = %s temp = %d holds now = %llu", + htag, (int)ha->temphold, ds->ds_userrefs); } static int @@ -3900,7 +3892,6 @@ dsl_pool_t *dp = ds->ds_dir->dd_pool; objset_t *mos = dp->dp_meta_objset; uint64_t zapobj; - uint64_t dsobj = ds->ds_object; uint64_t refs; int error; @@ -3923,9 +3914,8 @@ dsl_dataset_destroy_sync(&dsda, tag, tx); } - spa_history_log_internal(LOG_DS_USER_RELEASE, - dp->dp_spa, tx, "<%s> %lld dataset = %llu", - ra->htag, (longlong_t)refs, dsobj); + spa_history_log_internal_ds(ds, "release", tx, + "tag = %s refs now = %lld", ra->htag, (longlong_t)refs); } static int