--- a/usr/src/uts/common/fs/zfs/dmu_objset.c Fri Jul 30 14:57:39 2010 +0100
+++ b/usr/src/uts/common/fs/zfs/dmu_objset.c Fri Jul 30 09:40:31 2010 -0600
@@ -422,7 +422,7 @@
*osp = ds->ds_objset;
if (*osp == NULL) {
err = dmu_objset_open_impl(dsl_dataset_get_spa(ds),
- ds, &ds->ds_phys->ds_bp, osp);
+ ds, dsl_dataset_get_blkptr(ds), osp);
}
mutex_exit(&ds->ds_opening_lock);
return (err);
@@ -602,11 +602,11 @@
dnode_t *mdn;
ASSERT(dmu_tx_is_syncing(tx));
- if (ds)
- mutex_enter(&ds->ds_opening_lock);
- VERIFY(0 == dmu_objset_open_impl(spa, ds, bp, &os));
- if (ds)
- mutex_exit(&ds->ds_opening_lock);
+ if (ds != NULL)
+ VERIFY(0 == dmu_objset_from_ds(ds, &os));
+ else
+ VERIFY(0 == dmu_objset_open_impl(spa, NULL, bp, &os));
+
mdn = DMU_META_DNODE(os);
dnode_allocate(mdn, DMU_OT_DNODE, 1 << DNODE_BLOCK_SHIFT,
@@ -695,38 +695,33 @@
dmu_objset_create_sync(void *arg1, void *arg2, dmu_tx_t *tx)
{
dsl_dir_t *dd = arg1;
+ spa_t *spa = dd->dd_pool->dp_spa;
struct oscarg *oa = arg2;
- uint64_t dsobj;
- dsl_dataset_t *ds;
- objset_t *os;
+ uint64_t obj;
ASSERT(dmu_tx_is_syncing(tx));
- dsobj = dsl_dataset_create_sync(dd, oa->lastname,
+ obj = dsl_dataset_create_sync(dd, oa->lastname,
oa->clone_origin, oa->flags, oa->cr, tx);
- VERIFY(0 == dsl_dataset_hold_obj(dd->dd_pool, dsobj, FTAG, &ds));
+ if (oa->clone_origin == NULL) {
+ dsl_pool_t *dp = dd->dd_pool;
+ dsl_dataset_t *ds;
+ blkptr_t *bp;
+ objset_t *os;
- if (oa->clone_origin == NULL) {
- blkptr_t *bp;
-
+ VERIFY3U(0, ==, dsl_dataset_hold_obj(dp, obj, FTAG, &ds));
bp = dsl_dataset_get_blkptr(ds);
ASSERT(BP_IS_HOLE(bp));
- os = dmu_objset_create_impl(dsl_dataset_get_spa(ds),
- ds, bp, oa->type, tx);
+ os = dmu_objset_create_impl(spa, ds, bp, oa->type, tx);
if (oa->userfunc)
oa->userfunc(os, oa->userarg, oa->cr, tx);
- } else {
- VERIFY3U(0, ==, dmu_objset_from_ds(ds, &os));
- bzero(&os->os_zil_header, sizeof (os->os_zil_header));
- dsl_dataset_dirty(ds, tx);
+ dsl_dataset_rele(ds, FTAG);
}
- dsl_dataset_rele(ds, FTAG);
- spa_history_log_internal(LOG_DS_CREATE, dd->dd_pool->dp_spa,
- tx, "dataset = %llu", dsobj);
+ spa_history_log_internal(LOG_DS_CREATE, spa, tx, "dataset = %llu", obj);
}
int
@@ -794,18 +789,8 @@
dsl_dataset_t *ds;
int error;
- /*
- * dsl_dataset_destroy() can free any claimed-but-unplayed
- * intent log, but if there is an active log, it has blocks that
- * are allocated, but may not yet be reflected in the on-disk
- * structure. Only the ZIL knows how to free them, so we have
- * to call into it here.
- */
error = dsl_dataset_own(name, B_TRUE, FTAG, &ds);
if (error == 0) {
- objset_t *os;
- if (dmu_objset_from_ds(ds, &os) == 0)
- zil_destroy(dmu_objset_zil(os), B_FALSE);
error = dsl_dataset_destroy(ds, FTAG, defer);
/* dsl_dataset_destroy() closes the ds. */
}
--- a/usr/src/uts/common/fs/zfs/dmu_send.c Fri Jul 30 14:57:39 2010 +0100
+++ b/usr/src/uts/common/fs/zfs/dmu_send.c Fri Jul 30 09:40:31 2010 -0600
@@ -574,6 +574,14 @@
if (!rbsa->force && dsl_dataset_modified_since_lastsnap(ds))
return (ETXTBSY);
+ /* new snapshot name must not exist */
+ err = zap_lookup(ds->ds_dir->dd_pool->dp_meta_objset,
+ ds->ds_phys->ds_snapnames_zapobj, rbsa->tosnap, 8, 1, &val);
+ if (err == 0)
+ return (EEXIST);
+ if (err != ENOENT)
+ return (err);
+
if (rbsa->fromguid) {
/* if incremental, most recent snapshot must match fromguid */
if (ds->ds_prev == NULL)
@@ -621,13 +629,6 @@
if (err != ENOENT)
return (err);
- /* new snapshot name must not exist */
- err = zap_lookup(ds->ds_dir->dd_pool->dp_meta_objset,
- ds->ds_phys->ds_snapnames_zapobj, rbsa->tosnap, 8, 1, &val);
- if (err == 0)
- return (EEXIST);
- if (err != ENOENT)
- return (err);
return (0);
}
--- a/usr/src/uts/common/fs/zfs/dsl_dataset.c Fri Jul 30 14:57:39 2010 +0100
+++ b/usr/src/uts/common/fs/zfs/dsl_dataset.c Fri Jul 30 09:40:31 2010 -0600
@@ -883,6 +883,21 @@
dsl_dir_close(dd, FTAG);
+ /*
+ * If we are creating a clone, make sure we zero out any stale
+ * data from the origin snapshots zil header.
+ */
+ if (origin != NULL) {
+ dsl_dataset_t *ds;
+ objset_t *os;
+
+ VERIFY3U(0, ==, dsl_dataset_hold_obj(dp, dsobj, FTAG, &ds));
+ VERIFY3U(0, ==, dmu_objset_from_ds(ds, &os));
+ bzero(&os->os_zil_header, sizeof (os->os_zil_header));
+ dsl_dataset_dirty(ds, tx);
+ dsl_dataset_rele(ds, FTAG);
+ }
+
return (dsobj);
}
@@ -1083,11 +1098,16 @@
*/
(void) dmu_free_object(os, obj);
}
+ if (err != ESRCH)
+ goto out;
/*
- * We need to sync out all in-flight IO before we try to evict
- * (the dataset evict func is trying to clear the cached entries
- * for this dataset in the ARC).
+ * Only the ZIL knows how to free log blocks.
+ */
+ zil_destroy(dmu_objset_zil(os), B_FALSE);
+
+ /*
+ * Sync out all in-flight IO.
*/
txg_wait_synced(dd->dd_pool, 0);
@@ -1105,9 +1125,6 @@
count == 0);
}
- if (err != ESRCH)
- goto out;
-
rw_enter(&dd->dd_pool->dp_config_rwlock, RW_READER);
err = dsl_dir_open_obj(dd->dd_pool, dd->dd_object, NULL, FTAG, &dd);
rw_exit(&dd->dd_pool->dp_config_rwlock);