Print this page
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>

*** 18,27 **** --- 18,28 ---- * * CDDL HEADER END */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012 by Delphix. All rights reserved. */ #include <sys/dmu.h> #include <sys/dmu_objset.h> #include <sys/dmu_tx.h>
*** 37,48 **** #include <sys/arc.h> #include <sys/sunddi.h> #include "zfs_namecheck.h" static uint64_t dsl_dir_space_towrite(dsl_dir_t *dd); ! static void dsl_dir_set_reservation_sync(void *arg1, void *arg2, dmu_tx_t *tx); ! /* ARGSUSED */ static void dsl_dir_evict(dmu_buf_t *db, void *arg) { --- 38,49 ---- #include <sys/arc.h> #include <sys/sunddi.h> #include "zfs_namecheck.h" static uint64_t dsl_dir_space_towrite(dsl_dir_t *dd); ! static void dsl_dir_set_reservation_sync_impl(dsl_dir_t *dd, ! uint64_t value, dmu_tx_t *tx); /* ARGSUSED */ static void dsl_dir_evict(dmu_buf_t *db, void *arg) {
*** 445,456 **** /* ARGSUSED */ int dsl_dir_destroy_check(void *arg1, void *arg2, dmu_tx_t *tx) { ! dsl_dataset_t *ds = arg1; ! dsl_dir_t *dd = ds->ds_dir; dsl_pool_t *dp = dd->dd_pool; objset_t *mos = dp->dp_meta_objset; int err; uint64_t count; --- 446,456 ---- /* ARGSUSED */ int dsl_dir_destroy_check(void *arg1, void *arg2, dmu_tx_t *tx) { ! dsl_dir_t *dd = arg1; dsl_pool_t *dp = dd->dd_pool; objset_t *mos = dp->dp_meta_objset; int err; uint64_t count;
*** 475,502 **** } void dsl_dir_destroy_sync(void *arg1, void *tag, dmu_tx_t *tx) { ! dsl_dataset_t *ds = arg1; ! dsl_dir_t *dd = ds->ds_dir; objset_t *mos = dd->dd_pool->dp_meta_objset; - dsl_prop_setarg_t psa; - uint64_t value = 0; uint64_t obj; dd_used_t t; ASSERT(RW_WRITE_HELD(&dd->dd_pool->dp_config_rwlock)); ASSERT(dd->dd_phys->dd_head_dataset_obj == 0); ! /* Remove our reservation. */ ! dsl_prop_setarg_init_uint64(&psa, "reservation", ! (ZPROP_SRC_NONE | ZPROP_SRC_LOCAL | ZPROP_SRC_RECEIVED), ! &value); ! psa.psa_effective_value = 0; /* predict default value */ ! ! dsl_dir_set_reservation_sync(ds, &psa, tx); ASSERT3U(dd->dd_phys->dd_used_bytes, ==, 0); ASSERT3U(dd->dd_phys->dd_reserved, ==, 0); for (t = 0; t < DD_USED_NUM; t++) ASSERT3U(dd->dd_phys->dd_used_breakdown[t], ==, 0); --- 475,497 ---- } void dsl_dir_destroy_sync(void *arg1, void *tag, dmu_tx_t *tx) { ! dsl_dir_t *dd = arg1; objset_t *mos = dd->dd_pool->dp_meta_objset; uint64_t obj; dd_used_t t; ASSERT(RW_WRITE_HELD(&dd->dd_pool->dp_config_rwlock)); ASSERT(dd->dd_phys->dd_head_dataset_obj == 0); ! /* ! * Remove our reservation. The impl() routine avoids setting the ! * actual property, which would require the (already destroyed) ds. ! */ ! dsl_dir_set_reservation_sync_impl(dd, 0, tx); ASSERT3U(dd->dd_phys->dd_used_bytes, ==, 0); ASSERT3U(dd->dd_phys->dd_reserved, ==, 0); for (t = 0; t < DD_USED_NUM; t++) ASSERT3U(dd->dd_phys->dd_used_breakdown[t], ==, 0);
*** 1058,1070 **** mutex_enter(&dd->dd_lock); dd->dd_phys->dd_quota = effective_value; mutex_exit(&dd->dd_lock); ! spa_history_log_internal(LOG_DS_QUOTA, dd->dd_pool->dp_spa, ! tx, "%lld dataset = %llu ", ! (longlong_t)effective_value, dd->dd_phys->dd_head_dataset_obj); } int dsl_dir_set_quota(const char *ddname, zprop_source_t source, uint64_t quota) { --- 1053,1064 ---- mutex_enter(&dd->dd_lock); dd->dd_phys->dd_quota = effective_value; mutex_exit(&dd->dd_lock); ! spa_history_log_internal_dd(dd, "set quota", tx, ! "quota=%lld", (longlong_t)effective_value); } int dsl_dir_set_quota(const char *ddname, zprop_source_t source, uint64_t quota) {
*** 1147,1186 **** return (0); } static void ! dsl_dir_set_reservation_sync(void *arg1, void *arg2, dmu_tx_t *tx) { - dsl_dataset_t *ds = arg1; - dsl_dir_t *dd = ds->ds_dir; - dsl_prop_setarg_t *psa = arg2; - uint64_t effective_value = psa->psa_effective_value; uint64_t used; int64_t delta; - dsl_prop_set_sync(ds, psa, tx); - DSL_PROP_CHECK_PREDICTION(dd, psa); - dmu_buf_will_dirty(dd->dd_dbuf, tx); mutex_enter(&dd->dd_lock); used = dd->dd_phys->dd_used_bytes; ! delta = MAX(used, effective_value) - ! MAX(used, dd->dd_phys->dd_reserved); ! dd->dd_phys->dd_reserved = effective_value; if (dd->dd_parent != NULL) { /* Roll up this additional usage into our ancestors */ dsl_dir_diduse_space(dd->dd_parent, DD_USED_CHILD_RSRV, delta, 0, 0, tx); } mutex_exit(&dd->dd_lock); ! spa_history_log_internal(LOG_DS_RESERVATION, dd->dd_pool->dp_spa, ! tx, "%lld dataset = %llu", ! (longlong_t)effective_value, dd->dd_phys->dd_head_dataset_obj); } int dsl_dir_set_reservation(const char *ddname, zprop_source_t source, uint64_t reservation) --- 1141,1186 ---- return (0); } static void ! dsl_dir_set_reservation_sync_impl(dsl_dir_t *dd, uint64_t value, dmu_tx_t *tx) { uint64_t used; int64_t delta; dmu_buf_will_dirty(dd->dd_dbuf, tx); mutex_enter(&dd->dd_lock); used = dd->dd_phys->dd_used_bytes; ! delta = MAX(used, value) - MAX(used, dd->dd_phys->dd_reserved); ! dd->dd_phys->dd_reserved = value; if (dd->dd_parent != NULL) { /* Roll up this additional usage into our ancestors */ dsl_dir_diduse_space(dd->dd_parent, DD_USED_CHILD_RSRV, delta, 0, 0, tx); } mutex_exit(&dd->dd_lock); + } + ! static void ! dsl_dir_set_reservation_sync(void *arg1, void *arg2, dmu_tx_t *tx) ! { ! dsl_dataset_t *ds = arg1; ! dsl_dir_t *dd = ds->ds_dir; ! dsl_prop_setarg_t *psa = arg2; ! uint64_t value = psa->psa_effective_value; ! ! dsl_prop_set_sync(ds, psa, tx); ! DSL_PROP_CHECK_PREDICTION(dd, psa); ! ! dsl_dir_set_reservation_sync_impl(dd, value, tx); ! ! spa_history_log_internal_dd(dd, "set reservation", tx, ! "reservation=%lld", (longlong_t)value); } int dsl_dir_set_reservation(const char *ddname, zprop_source_t source, uint64_t reservation)
*** 1297,1309 **** --- 1297,1315 ---- dsl_dir_t *dd = arg1; struct renamearg *ra = arg2; dsl_pool_t *dp = dd->dd_pool; objset_t *mos = dp->dp_meta_objset; int err; + char namebuf[MAXNAMELEN]; ASSERT(dmu_buf_refcount(dd->dd_dbuf) <= 2); + /* Log this before we change the name. */ + dsl_dir_name(ra->newparent, namebuf); + spa_history_log_internal_dd(dd, "rename", tx, + "-> %s/%s", namebuf, ra->mynewname); + if (ra->newparent != dd->dd_parent) { dsl_dir_diduse_space(dd->dd_parent, DD_USED_CHILD, -dd->dd_phys->dd_used_bytes, -dd->dd_phys->dd_compressed_bytes, -dd->dd_phys->dd_uncompressed_bytes, tx);
*** 1339,1350 **** /* add to new parent zapobj */ err = zap_add(mos, ra->newparent->dd_phys->dd_child_dir_zapobj, dd->dd_myname, 8, 1, &dd->dd_object, tx); ASSERT3U(err, ==, 0); - spa_history_log_internal(LOG_DS_RENAME, dd->dd_pool->dp_spa, - tx, "dataset = %llu", dd->dd_phys->dd_head_dataset_obj); } int dsl_dir_rename(dsl_dir_t *dd, const char *newname) { --- 1345,1354 ----