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 ----