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,10 +18,11 @@
  *
  * 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,12 +38,12 @@
 #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);
-
+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,12 +446,11 @@
 
 /* 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_dir_t *dd = arg1;
         dsl_pool_t *dp = dd->dd_pool;
         objset_t *mos = dp->dp_meta_objset;
         int err;
         uint64_t count;
 

@@ -475,28 +475,23 @@
 }
 
 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;
+        dsl_dir_t *dd = arg1;
         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);
+        /*
+         * 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,13 +1053,12 @@
 
         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);
+        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,40 +1141,46 @@
 
         return (0);
 }
 
 static void
-dsl_dir_set_reservation_sync(void *arg1, void *arg2, dmu_tx_t *tx)
+dsl_dir_set_reservation_sync_impl(dsl_dir_t *dd, uint64_t value, 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;
+        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);
+}
+
 
-        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);
+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,13 +1297,19 @@
         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,12 +1345,10 @@
         /* 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)
 {