68
85
dump_free(struct backuparg *ba, uint64_t object, uint64_t offset,
71
/* write a FREE record */
88
struct drr_free *drrf = &(ba->drr->drr_u.drr_free);
91
* If there is a pending op, but it's not PENDING_FREE, push it out,
92
* since free block aggregation can only be done for blocks of the
93
* same type (i.e., DRR_FREE records can only be aggregated with
94
* other DRR_FREE records. DRR_FREEOBJECTS records can only be
95
* aggregated with other DRR_FREEOBJECTS records.
97
if (ba->pending_op != PENDING_NONE && ba->pending_op != PENDING_FREE) {
98
if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)) != 0)
100
ba->pending_op = PENDING_NONE;
103
if (ba->pending_op == PENDING_FREE) {
105
* There should never be a PENDING_FREE if length is -1
106
* (because dump_dnode is the only place where this
107
* function is called with a -1, and only after flushing
108
* any pending record).
110
ASSERT(length != -1ULL);
112
* Check to see whether this free block can be aggregated
115
if (drrf->drr_object == object && drrf->drr_offset +
116
drrf->drr_length == offset) {
117
drrf->drr_length += length;
120
/* not a continuation. Push out pending record */
121
if (dump_bytes(ba, ba->drr,
122
sizeof (dmu_replay_record_t)) != 0)
124
ba->pending_op = PENDING_NONE;
127
/* create a FREE record and make it pending */
72
128
bzero(ba->drr, sizeof (dmu_replay_record_t));
73
129
ba->drr->drr_type = DRR_FREE;
74
ba->drr->drr_u.drr_free.drr_object = object;
75
ba->drr->drr_u.drr_free.drr_offset = offset;
76
ba->drr->drr_u.drr_free.drr_length = length;
130
drrf->drr_object = object;
131
drrf->drr_offset = offset;
132
drrf->drr_length = length;
133
drrf->drr_toguid = ba->toguid;
134
if (length == -1ULL) {
135
if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)) != 0)
138
ba->pending_op = PENDING_FREE;
78
if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)))
84
145
dump_data(struct backuparg *ba, dmu_object_type_t type,
85
uint64_t object, uint64_t offset, int blksz, void *data)
146
uint64_t object, uint64_t offset, int blksz, const blkptr_t *bp, void *data)
148
struct drr_write *drrw = &(ba->drr->drr_u.drr_write);
152
* If there is any kind of pending aggregation (currently either
153
* a grouping of free objects or free blocks), push it out to
154
* the stream, since aggregation can't be done across operations
155
* of different types.
157
if (ba->pending_op != PENDING_NONE) {
158
if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)) != 0)
160
ba->pending_op = PENDING_NONE;
87
162
/* write a DATA record */
88
163
bzero(ba->drr, sizeof (dmu_replay_record_t));
89
164
ba->drr->drr_type = DRR_WRITE;
90
ba->drr->drr_u.drr_write.drr_object = object;
91
ba->drr->drr_u.drr_write.drr_type = type;
92
ba->drr->drr_u.drr_write.drr_offset = offset;
93
ba->drr->drr_u.drr_write.drr_length = blksz;
165
drrw->drr_object = object;
166
drrw->drr_type = type;
167
drrw->drr_offset = offset;
168
drrw->drr_length = blksz;
169
drrw->drr_toguid = ba->toguid;
170
drrw->drr_checksumtype = BP_GET_CHECKSUM(bp);
171
if (zio_checksum_table[drrw->drr_checksumtype].ci_dedup)
172
drrw->drr_checksumflags |= DRR_CHECKSUM_DEDUP;
173
DDK_SET_LSIZE(&drrw->drr_key, BP_GET_LSIZE(bp));
174
DDK_SET_PSIZE(&drrw->drr_key, BP_GET_PSIZE(bp));
175
DDK_SET_COMPRESS(&drrw->drr_key, BP_GET_COMPRESS(bp));
176
drrw->drr_key.ddk_cksum = bp->blk_cksum;
95
if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)))
178
if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)) != 0)
97
if (dump_bytes(ba, data, blksz))
180
if (dump_bytes(ba, data, blksz) != 0)
103
186
dump_freeobjects(struct backuparg *ba, uint64_t firstobj, uint64_t numobjs)
188
struct drr_freeobjects *drrfo = &(ba->drr->drr_u.drr_freeobjects);
191
* If there is a pending op, but it's not PENDING_FREEOBJECTS,
192
* push it out, since free block aggregation can only be done for
193
* blocks of the same type (i.e., DRR_FREE records can only be
194
* aggregated with other DRR_FREE records. DRR_FREEOBJECTS records
195
* can only be aggregated with other DRR_FREEOBJECTS records.
197
if (ba->pending_op != PENDING_NONE &&
198
ba->pending_op != PENDING_FREEOBJECTS) {
199
if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)) != 0)
201
ba->pending_op = PENDING_NONE;
203
if (ba->pending_op == PENDING_FREEOBJECTS) {
205
* See whether this free object array can be aggregated
208
if (drrfo->drr_firstobj + drrfo->drr_numobjs == firstobj) {
209
drrfo->drr_numobjs += numobjs;
212
/* can't be aggregated. Push out pending record */
213
if (dump_bytes(ba, ba->drr,
214
sizeof (dmu_replay_record_t)) != 0)
216
ba->pending_op = PENDING_NONE;
105
220
/* write a FREEOBJECTS record */
106
221
bzero(ba->drr, sizeof (dmu_replay_record_t));
107
222
ba->drr->drr_type = DRR_FREEOBJECTS;
108
ba->drr->drr_u.drr_freeobjects.drr_firstobj = firstobj;
109
ba->drr->drr_u.drr_freeobjects.drr_numobjs = numobjs;
111
if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)))
223
drrfo->drr_firstobj = firstobj;
224
drrfo->drr_numobjs = numobjs;
225
drrfo->drr_toguid = ba->toguid;
227
ba->pending_op = PENDING_FREEOBJECTS;
117
233
dump_dnode(struct backuparg *ba, uint64_t object, dnode_phys_t *dnp)
235
struct drr_object *drro = &(ba->drr->drr_u.drr_object);
119
237
if (dnp == NULL || dnp->dn_type == DMU_OT_NONE)
120
238
return (dump_freeobjects(ba, object, 1));
240
if (ba->pending_op != PENDING_NONE) {
241
if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)) != 0)
243
ba->pending_op = PENDING_NONE;
122
246
/* write an OBJECT record */
123
247
bzero(ba->drr, sizeof (dmu_replay_record_t));
124
248
ba->drr->drr_type = DRR_OBJECT;
125
ba->drr->drr_u.drr_object.drr_object = object;
126
ba->drr->drr_u.drr_object.drr_type = dnp->dn_type;
127
ba->drr->drr_u.drr_object.drr_bonustype = dnp->dn_bonustype;
128
ba->drr->drr_u.drr_object.drr_blksz =
129
dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT;
130
ba->drr->drr_u.drr_object.drr_bonuslen = dnp->dn_bonuslen;
131
ba->drr->drr_u.drr_object.drr_checksum = dnp->dn_checksum;
132
ba->drr->drr_u.drr_object.drr_compress = dnp->dn_compress;
249
drro->drr_object = object;
250
drro->drr_type = dnp->dn_type;
251
drro->drr_bonustype = dnp->dn_bonustype;
252
drro->drr_blksz = dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT;
253
drro->drr_bonuslen = dnp->dn_bonuslen;
254
drro->drr_checksumtype = dnp->dn_checksum;
255
drro->drr_compress = dnp->dn_compress;
256
drro->drr_toguid = ba->toguid;
134
if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)))
258
if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)) != 0)
137
if (dump_bytes(ba, DN_BONUS(dnp), P2ROUNDUP(dnp->dn_bonuslen, 8)))
261
if (dump_bytes(ba, DN_BONUS(dnp), P2ROUNDUP(dnp->dn_bonuslen, 8)) != 0)
140
264
/* free anything past the end of the file */
321
455
dsl_dataset_t *ds; /* the ds to recv into; returned from the syncfunc */
324
static dsl_dataset_t *
325
recv_full_sync_impl(dsl_pool_t *dp, uint64_t dsobj, dmu_objset_type_t type,
326
cred_t *cr, dmu_tx_t *tx)
330
/* This should always work, since we just created it */
331
/* XXX - create should return an owned ds */
332
VERIFY(0 == dsl_dataset_own_obj(dp, dsobj,
333
DS_MODE_INCONSISTENT, dmu_recv_tag, &ds));
335
if (type != DMU_OST_NONE) {
336
(void) dmu_objset_create_impl(dp->dp_spa,
337
ds, &ds->ds_phys->ds_bp, type, tx);
340
spa_history_internal_log(LOG_DS_REPLAY_FULL_SYNC,
341
dp->dp_spa, tx, cr, "dataset = %lld", dsobj);
348
recv_full_check(void *arg1, void *arg2, dmu_tx_t *tx)
460
recv_new_check(void *arg1, void *arg2, dmu_tx_t *tx)
350
462
dsl_dir_t *dd = arg1;
351
463
struct recvbeginsyncarg *rbsa = arg2;
376
recv_full_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx)
488
recv_new_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx)
378
490
dsl_dir_t *dd = arg1;
379
491
struct recvbeginsyncarg *rbsa = arg2;
380
492
uint64_t flags = DS_FLAG_INCONSISTENT | rbsa->dsflags;
495
/* Create and open new dataset. */
383
496
dsobj = dsl_dataset_create_sync(dd, strrchr(rbsa->tofs, '/') + 1,
384
497
rbsa->origin, flags, cr, tx);
386
rbsa->ds = recv_full_sync_impl(dd->dd_pool, dsobj,
387
rbsa->origin ? DMU_OST_NONE : rbsa->type, cr, tx);
391
recv_full_existing_check(void *arg1, void *arg2, dmu_tx_t *tx)
393
dsl_dataset_t *ds = arg1;
394
struct recvbeginsyncarg *rbsa = arg2;
397
/* must be a head ds */
398
if (ds->ds_phys->ds_next_snap_obj != 0)
401
/* must not be a clone ds */
402
if (dsl_dir_is_clone(ds->ds_dir))
405
err = dsl_dataset_destroy_check(ds, rbsa->tag, tx);
410
/* make sure it's a snap in the same pool */
411
if (rbsa->origin->ds_dir->dd_pool != ds->ds_dir->dd_pool)
413
if (rbsa->origin->ds_phys->ds_num_children == 0)
415
if (rbsa->origin->ds_phys->ds_guid != rbsa->fromguid)
498
VERIFY(0 == dsl_dataset_own_obj(dd->dd_pool, dsobj,
499
B_TRUE, dmu_recv_tag, &rbsa->ds));
501
if (rbsa->origin == NULL) {
502
(void) dmu_objset_create_impl(dd->dd_pool->dp_spa,
503
rbsa->ds, &rbsa->ds->ds_phys->ds_bp, rbsa->type, tx);
423
recv_full_existing_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx)
425
dsl_dataset_t *ds = arg1;
426
struct recvbeginsyncarg *rbsa = arg2;
427
dsl_dir_t *dd = ds->ds_dir;
428
uint64_t flags = DS_FLAG_INCONSISTENT | rbsa->dsflags;
432
* NB: caller must provide an extra hold on the dsl_dir_t, so it
433
* won't go away when dsl_dataset_destroy_sync() closes the
436
dsl_dataset_destroy_sync(ds, rbsa->tag, cr, tx);
438
dsobj = dsl_dataset_create_sync_dd(dd, rbsa->origin, flags, tx);
440
rbsa->ds = recv_full_sync_impl(dd->dd_pool, dsobj,
441
rbsa->origin ? DMU_OST_NONE : rbsa->type, cr, tx);
506
spa_history_internal_log(LOG_DS_REPLAY_FULL_SYNC,
507
dd->dd_pool->dp_spa, tx, cr, "dataset = %lld", dsobj);
446
recv_incremental_check(void *arg1, void *arg2, dmu_tx_t *tx)
512
recv_existing_check(void *arg1, void *arg2, dmu_tx_t *tx)
448
514
dsl_dataset_t *ds = arg1;
449
515
struct recvbeginsyncarg *rbsa = arg2;
454
520
if (!rbsa->force && dsl_dataset_modified_since_lastsnap(ds))
455
521
return (ETXTBSY);
457
/* must already be a snapshot of this fs */
458
if (ds->ds_phys->ds_prev_snap_obj == 0)
523
if (rbsa->fromguid) {
524
/* if incremental, most recent snapshot must match fromguid */
525
if (ds->ds_prev == NULL)
461
/* most recent snapshot must match fromguid */
462
if (ds->ds_prev->ds_phys->ds_guid != rbsa->fromguid)
529
* most recent snapshot must match fromguid, or there are no
530
* changes since the fromguid one
532
if (ds->ds_prev->ds_phys->ds_guid != rbsa->fromguid) {
533
uint64_t birth = ds->ds_prev->ds_phys->ds_bp.blk_birth;
534
uint64_t obj = ds->ds_prev->ds_phys->ds_prev_snap_obj;
537
err = dsl_dataset_hold_obj(ds->ds_dir->dd_pool,
541
if (snap->ds_phys->ds_creation_txg < birth) {
542
dsl_dataset_rele(snap, FTAG);
545
if (snap->ds_phys->ds_guid == rbsa->fromguid) {
546
dsl_dataset_rele(snap, FTAG);
549
obj = snap->ds_phys->ds_prev_snap_obj;
550
dsl_dataset_rele(snap, FTAG);
556
/* if full, most recent snapshot must be $ORIGIN */
557
if (ds->ds_phys->ds_prev_snap_txg >= TXG_INITIAL)
465
561
/* temporary clone name must not exist */
466
562
err = zap_lookup(ds->ds_dir->dd_pool->dp_meta_objset,
486
recv_online_incremental_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx)
582
recv_existing_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx)
488
584
dsl_dataset_t *ohds = arg1;
489
585
struct recvbeginsyncarg *rbsa = arg2;
490
586
dsl_pool_t *dp = ohds->ds_dir->dd_pool;
491
dsl_dataset_t *ods, *cds;
492
588
uint64_t flags = DS_FLAG_INCONSISTENT | rbsa->dsflags;
495
/* create the temporary clone */
496
VERIFY(0 == dsl_dataset_hold_obj(dp, ohds->ds_phys->ds_prev_snap_obj,
498
dsobj = dsl_dataset_create_sync(ohds->ds_dir,
499
rbsa->clonelastname, ods, flags, cr, tx);
500
dsl_dataset_rele(ods, FTAG);
502
/* open the temporary clone */
503
VERIFY(0 == dsl_dataset_own_obj(dp, dsobj,
504
DS_MODE_INCONSISTENT, dmu_recv_tag, &cds));
506
/* copy the refquota from the target fs to the clone */
507
if (ohds->ds_quota > 0)
508
dsl_dataset_set_quota_sync(cds, &ohds->ds_quota, cr, tx);
591
/* create and open the temporary clone */
592
dsobj = dsl_dataset_create_sync(ohds->ds_dir, rbsa->clonelastname,
593
ohds->ds_prev, flags, cr, tx);
594
VERIFY(0 == dsl_dataset_own_obj(dp, dsobj, B_TRUE, dmu_recv_tag, &cds));
597
* If we actually created a non-clone, we need to create the
598
* objset in our new dataset.
600
if (BP_IS_HOLE(dsl_dataset_get_blkptr(cds))) {
601
(void) dmu_objset_create_impl(dp->dp_spa,
602
cds, dsl_dataset_get_blkptr(cds), rbsa->type, tx);
513
608
dp->dp_spa, tx, cr, "dataset = %lld", dsobj);
518
recv_offline_incremental_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx)
520
dsl_dataset_t *ds = arg1;
522
dmu_buf_will_dirty(ds->ds_dbuf, tx);
523
ds->ds_phys->ds_flags |= DS_FLAG_INCONSISTENT;
525
spa_history_internal_log(LOG_DS_REPLAY_INC_SYNC,
526
ds->ds_dir->dd_pool->dp_spa, tx, cr, "dataset = %lld",
531
612
* NB: callers *MUST* call dmu_recv_stream() if dmu_recv_begin()
532
613
* succeeds; otherwise we will leak the holds on the datasets.
535
dmu_recv_begin(char *tofs, char *tosnap, struct drr_begin *drrb,
536
boolean_t force, objset_t *origin, boolean_t online, dmu_recv_cookie_t *drc)
616
dmu_recv_begin(char *tofs, char *tosnap, char *top_ds, struct drr_begin *drrb,
617
boolean_t force, objset_t *origin, dmu_recv_cookie_t *drc)
539
620
boolean_t byteswap;
540
struct recvbeginsyncarg rbsa;
621
struct recvbeginsyncarg rbsa = { 0 };
622
uint64_t versioninfo;
543
624
dsl_dataset_t *ds;
577
658
bzero(drc, sizeof (dmu_recv_cookie_t));
578
659
drc->drc_drrb = drrb;
579
660
drc->drc_tosnap = tosnap;
661
drc->drc_top_ds = top_ds;
580
662
drc->drc_force = force;
583
665
* Process the begin in syncing context.
585
if (rbsa.fromguid && !(flags & DRR_FLAG_CLONE) && !online) {
586
/* offline incremental receive */
587
err = dsl_dataset_own(tofs, 0, dmu_recv_tag, &ds);
592
* Only do the rollback if the most recent snapshot
593
* matches the incremental source
596
if (ds->ds_prev == NULL ||
597
ds->ds_prev->ds_phys->ds_guid !=
599
dsl_dataset_disown(ds, dmu_recv_tag);
602
(void) dsl_dataset_rollback(ds, DMU_OST_NONE);
604
rbsa.force = B_FALSE;
605
err = dsl_sync_task_do(ds->ds_dir->dd_pool,
606
recv_incremental_check,
607
recv_offline_incremental_sync, ds, &rbsa, 1);
609
dsl_dataset_disown(ds, dmu_recv_tag);
612
drc->drc_logical_ds = drc->drc_real_ds = ds;
613
} else if (rbsa.fromguid && !(flags & DRR_FLAG_CLONE)) {
614
/* online incremental receive */
668
/* open the dataset we are logically receiving into */
669
err = dsl_dataset_hold(tofs, dmu_recv_tag, &ds);
671
/* target fs already exists; recv into temp clone */
673
/* Can't recv a clone into an existing fs */
674
if (flags & DRR_FLAG_CLONE) {
675
dsl_dataset_rele(ds, dmu_recv_tag);
679
/* must not have an incremental recv already in progress */
680
if (!mutex_tryenter(&ds->ds_recvlock)) {
681
dsl_dataset_rele(ds, dmu_recv_tag);
616
685
/* tmp clone name is: tofs/%tosnap" */
617
686
(void) snprintf(rbsa.clonelastname, sizeof (rbsa.clonelastname),
620
/* open the dataset we are logically receiving into */
621
err = dsl_dataset_hold(tofs, dmu_recv_tag, &ds);
625
688
rbsa.force = force;
626
689
err = dsl_sync_task_do(ds->ds_dir->dd_pool,
627
recv_incremental_check,
628
recv_online_incremental_sync, ds, &rbsa, 5);
690
recv_existing_check, recv_existing_sync, ds, &rbsa, 5);
692
mutex_exit(&ds->ds_recvlock);
630
693
dsl_dataset_rele(ds, dmu_recv_tag);
633
696
drc->drc_logical_ds = ds;
634
697
drc->drc_real_ds = rbsa.ds;
636
/* create new fs -- full backup or clone */
637
dsl_dir_t *dd = NULL;
640
err = dsl_dir_open(tofs, FTAG, &dd, &tail);
698
} else if (err == ENOENT) {
699
/* target fs does not exist; must be a full backup or clone */
703
* If it's a non-clone incremental, we are missing the
704
* target fs, so fail the recv.
706
if (rbsa.fromguid && !(flags & DRR_FLAG_CLONE))
709
/* Open the parent of tofs */
710
cp = strrchr(tofs, '/');
712
err = dsl_dataset_hold(tofs, FTAG, &ds);
645
dsl_dir_close(dd, FTAG);
649
rw_enter(&dd->dd_pool->dp_config_rwlock, RW_READER);
650
err = dsl_dataset_own_obj(dd->dd_pool,
651
dd->dd_phys->dd_head_dataset_obj,
652
DS_MODE_INCONSISTENT, FTAG, &ds);
653
rw_exit(&dd->dd_pool->dp_config_rwlock);
655
dsl_dir_close(dd, FTAG);
659
dsl_dataset_make_exclusive(ds, FTAG);
660
err = dsl_sync_task_do(dd->dd_pool,
661
recv_full_existing_check,
662
recv_full_existing_sync, ds, &rbsa, 5);
663
dsl_dataset_disown(ds, FTAG);
665
err = dsl_sync_task_do(dd->dd_pool, recv_full_check,
666
recv_full_sync, dd, &rbsa, 5);
668
dsl_dir_close(dd, FTAG);
717
err = dsl_sync_task_do(ds->ds_dir->dd_pool,
718
recv_new_check, recv_new_sync, ds->ds_dir, &rbsa, 5);
719
dsl_dataset_rele(ds, FTAG);
671
722
drc->drc_logical_ds = drc->drc_real_ds = rbsa.ds;
672
723
drc->drc_newfs = B_TRUE;
678
729
struct restorearg {
684
735
int bufsize; /* amount of memory allocated for buf */
685
736
zio_cksum_t cksum;
737
avl_tree_t guid_to_ds_map;
740
typedef struct guid_map_entry {
742
dsl_dataset_t *gme_ds;
747
guid_compare(const void *arg1, const void *arg2)
749
const guid_map_entry_t *gmep1 = arg1;
750
const guid_map_entry_t *gmep2 = arg2;
752
if (gmep1->guid < gmep2->guid)
754
else if (gmep1->guid > gmep2->guid)
760
* This function is a callback used by dmu_objset_find() (which
761
* enumerates the object sets) to build an avl tree that maps guids
762
* to datasets. The resulting table is used when processing DRR_WRITE_BYREF
763
* send stream records. These records, which are used in dedup'ed
764
* streams, do not contain data themselves, but refer to a copy
765
* of the data block that has already been written because it was
766
* earlier in the stream. That previous copy is identified by the
767
* guid of the dataset with the referenced data.
770
find_ds_by_guid(const char *name, void *arg)
772
avl_tree_t *guid_map = arg;
773
dsl_dataset_t *ds, *snapds;
774
guid_map_entry_t *gmep;
777
uint64_t lastobj, firstobj;
779
if (dsl_dataset_hold(name, FTAG, &ds) != 0)
782
dp = ds->ds_dir->dd_pool;
783
rw_enter(&dp->dp_config_rwlock, RW_READER);
784
firstobj = ds->ds_dir->dd_phys->dd_origin_obj;
785
lastobj = ds->ds_phys->ds_prev_snap_obj;
787
while (lastobj != firstobj) {
788
err = dsl_dataset_hold_obj(dp, lastobj, guid_map, &snapds);
791
* Skip this snapshot and move on. It's not
792
* clear why this would ever happen, but the
793
* remainder of the snapshot streadm can be
796
rw_exit(&dp->dp_config_rwlock);
797
dsl_dataset_rele(ds, FTAG);
801
gmep = kmem_alloc(sizeof (guid_map_entry_t), KM_SLEEP);
802
gmep->guid = snapds->ds_phys->ds_guid;
803
gmep->gme_ds = snapds;
804
avl_add(guid_map, gmep);
805
lastobj = snapds->ds_phys->ds_prev_snap_obj;
808
rw_exit(&dp->dp_config_rwlock);
809
dsl_dataset_rele(ds, FTAG);
689
815
restore_read(struct restorearg *ra, int len)
743
869
DO32(drr_object.drr_bonustype);
744
870
DO32(drr_object.drr_blksz);
745
871
DO32(drr_object.drr_bonuslen);
872
DO64(drr_object.drr_toguid);
747
874
case DRR_FREEOBJECTS:
748
875
DO64(drr_freeobjects.drr_firstobj);
749
876
DO64(drr_freeobjects.drr_numobjs);
877
DO64(drr_freeobjects.drr_toguid);
752
880
DO64(drr_write.drr_object);
753
881
DO32(drr_write.drr_type);
754
882
DO64(drr_write.drr_offset);
755
883
DO64(drr_write.drr_length);
884
DO64(drr_write.drr_toguid);
885
DO64(drr_write.drr_key.ddk_cksum.zc_word[0]);
886
DO64(drr_write.drr_key.ddk_cksum.zc_word[1]);
887
DO64(drr_write.drr_key.ddk_cksum.zc_word[2]);
888
DO64(drr_write.drr_key.ddk_cksum.zc_word[3]);
889
DO64(drr_write.drr_key.ddk_prop);
891
case DRR_WRITE_BYREF:
892
DO64(drr_write_byref.drr_object);
893
DO64(drr_write_byref.drr_offset);
894
DO64(drr_write_byref.drr_length);
895
DO64(drr_write_byref.drr_toguid);
896
DO64(drr_write_byref.drr_refguid);
897
DO64(drr_write_byref.drr_refobject);
898
DO64(drr_write_byref.drr_refoffset);
899
DO64(drr_write_byref.drr_key.ddk_cksum.zc_word[0]);
900
DO64(drr_write_byref.drr_key.ddk_cksum.zc_word[1]);
901
DO64(drr_write_byref.drr_key.ddk_cksum.zc_word[2]);
902
DO64(drr_write_byref.drr_key.ddk_cksum.zc_word[3]);
903
DO64(drr_write_byref.drr_key.ddk_prop);
758
906
DO64(drr_free.drr_object);
759
907
DO64(drr_free.drr_offset);
760
908
DO64(drr_free.drr_length);
909
DO64(drr_free.drr_toguid);
763
912
DO64(drr_end.drr_checksum.zc_word[0]);
764
913
DO64(drr_end.drr_checksum.zc_word[1]);
765
914
DO64(drr_end.drr_checksum.zc_word[2]);
766
915
DO64(drr_end.drr_checksum.zc_word[3]);
916
DO64(drr_end.drr_toguid);
1067
* Handle a DRR_WRITE_BYREF record. This record is used in dedup'ed
1068
* streams to refer to a copy of the data that is already on the
1069
* system because it came in earlier in the stream. This function
1070
* finds the earlier copy of the data, and uses that copy instead of
1071
* data from the stream to fulfill this write.
1074
restore_write_byref(struct restorearg *ra, objset_t *os,
1075
struct drr_write_byref *drrwbr)
1079
guid_map_entry_t gmesrch;
1080
guid_map_entry_t *gmep;
1082
objset_t *ref_os = NULL;
1085
if (drrwbr->drr_offset + drrwbr->drr_length < drrwbr->drr_offset)
1089
* If the GUID of the referenced dataset is different from the
1090
* GUID of the target dataset, find the referenced dataset.
1092
if (drrwbr->drr_toguid != drrwbr->drr_refguid) {
1093
gmesrch.guid = drrwbr->drr_refguid;
1094
if ((gmep = avl_find(&ra->guid_to_ds_map, &gmesrch,
1098
if (dmu_objset_from_ds(gmep->gme_ds, &ref_os))
1104
if (err = dmu_buf_hold(ref_os, drrwbr->drr_refobject,
1105
drrwbr->drr_refoffset, FTAG, &dbp))
1108
tx = dmu_tx_create(os);
1110
dmu_tx_hold_write(tx, drrwbr->drr_object,
1111
drrwbr->drr_offset, drrwbr->drr_length);
1112
err = dmu_tx_assign(tx, TXG_WAIT);
1117
dmu_write(os, drrwbr->drr_object,
1118
drrwbr->drr_offset, drrwbr->drr_length, dbp->db_data, tx);
1119
dmu_buf_rele(dbp, FTAG);
917
1126
restore_free(struct restorearg *ra, objset_t *os,
998
1189
ra.buf = kmem_alloc(ra.bufsize, KM_SLEEP);
1000
1191
/* these were verified in dmu_recv_begin */
1001
ASSERT(drc->drc_drrb->drr_version == DMU_BACKUP_STREAM_VERSION);
1192
ASSERT(DMU_GET_STREAM_HDRTYPE(drc->drc_drrb->drr_versioninfo) ==
1002
1194
ASSERT(drc->drc_drrb->drr_type < DMU_OST_NUMTYPES);
1005
1197
* Open the objset we are modifying.
1007
VERIFY(dmu_objset_open_ds(drc->drc_real_ds, DMU_OST_ANY, &os) == 0);
1199
VERIFY(dmu_objset_from_ds(drc->drc_real_ds, &os) == 0);
1009
1201
ASSERT(drc->drc_real_ds->ds_phys->ds_flags & DS_FLAG_INCONSISTENT);
1203
featureflags = DMU_GET_FEATUREFLAGS(drc->drc_drrb->drr_versioninfo);
1205
/* if this stream is dedup'ed, set up the avl tree for guid mapping */
1206
if (featureflags & DMU_BACKUP_FEATURE_DEDUP) {
1207
avl_create(&ra.guid_to_ds_map, guid_compare,
1208
sizeof (guid_map_entry_t),
1209
offsetof(guid_map_entry_t, avlnode));
1210
(void) dmu_objset_find(drc->drc_top_ds, find_ds_by_guid,
1211
(void *)&ra.guid_to_ds_map,
1012
1216
* Read records and process them.
1074
1285
ASSERT(ra.err != 0);
1077
dmu_objset_close(os);
1079
1288
if (ra.err != 0) {
1081
* rollback or destroy what we created, so we don't
1082
* leave it in the restoring state.
1290
* destroy what we created, so we don't leave it in the
1291
* inconsistent restoring state.
1084
1293
txg_wait_synced(drc->drc_real_ds->ds_dir->dd_pool, 0);
1085
dmu_recv_abort_cleanup(drc);
1295
(void) dsl_dataset_destroy(drc->drc_real_ds, dmu_recv_tag,
1297
if (drc->drc_real_ds != drc->drc_logical_ds) {
1298
mutex_exit(&drc->drc_logical_ds->ds_recvlock);
1299
dsl_dataset_rele(drc->drc_logical_ds, dmu_recv_tag);
1303
if (featureflags & DMU_BACKUP_FEATURE_DEDUP) {
1304
void *cookie = NULL;
1306
while (gmep = avl_destroy_nodes(&ra.guid_to_ds_map, &cookie)) {
1307
dsl_dataset_rele(gmep->gme_ds, &ra.guid_to_ds_map);
1308
kmem_free(gmep, sizeof (guid_map_entry_t));
1310
avl_destroy(&ra.guid_to_ds_map);
1088
1313
kmem_free(ra.buf, ra.bufsize);
1123
1348
ds->ds_phys->ds_flags &= ~DS_FLAG_INCONSISTENT;
1352
dmu_recv_existing_end(dmu_recv_cookie_t *drc)
1354
struct recvendsyncarg resa;
1355
dsl_dataset_t *ds = drc->drc_logical_ds;
1359
* XXX hack; seems the ds is still dirty and dsl_pool_zil_clean()
1360
* expects it to have a ds_user_ptr (and zil), but clone_swap()
1363
txg_wait_synced(ds->ds_dir->dd_pool, 0);
1365
if (dsl_dataset_tryown(ds, FALSE, dmu_recv_tag)) {
1366
err = dsl_dataset_clone_swap(drc->drc_real_ds, ds,
1371
mutex_exit(&ds->ds_recvlock);
1372
dsl_dataset_rele(ds, dmu_recv_tag);
1373
(void) dsl_dataset_destroy(drc->drc_real_ds, dmu_recv_tag,
1378
resa.creation_time = drc->drc_drrb->drr_creation_time;
1379
resa.toguid = drc->drc_drrb->drr_toguid;
1380
resa.tosnap = drc->drc_tosnap;
1382
err = dsl_sync_task_do(ds->ds_dir->dd_pool,
1383
recv_end_check, recv_end_sync, ds, &resa, 3);
1386
(void) dsl_dataset_clone_swap(drc->drc_real_ds, ds, B_TRUE);
1390
mutex_exit(&ds->ds_recvlock);
1391
dsl_dataset_disown(ds, dmu_recv_tag);
1392
(void) dsl_dataset_destroy(drc->drc_real_ds, dmu_recv_tag, B_FALSE);
1397
dmu_recv_new_end(dmu_recv_cookie_t *drc)
1399
struct recvendsyncarg resa;
1400
dsl_dataset_t *ds = drc->drc_logical_ds;
1404
* XXX hack; seems the ds is still dirty and dsl_pool_zil_clean()
1405
* expects it to have a ds_user_ptr (and zil), but clone_swap()
1408
txg_wait_synced(ds->ds_dir->dd_pool, 0);
1410
resa.creation_time = drc->drc_drrb->drr_creation_time;
1411
resa.toguid = drc->drc_drrb->drr_toguid;
1412
resa.tosnap = drc->drc_tosnap;
1414
err = dsl_sync_task_do(ds->ds_dir->dd_pool,
1415
recv_end_check, recv_end_sync, ds, &resa, 3);
1417
/* clean up the fs we just recv'd into */
1418
(void) dsl_dataset_destroy(ds, dmu_recv_tag, B_FALSE);
1420
/* release the hold from dmu_recv_begin */
1421
dsl_dataset_disown(ds, dmu_recv_tag);
1127
1427
dmu_recv_end(dmu_recv_cookie_t *drc)
1129
struct recvendsyncarg resa;
1130
dsl_dataset_t *ds = drc->drc_logical_ds;
1134
* XXX hack; seems the ds is still dirty and
1135
* dsl_pool_zil_clean() expects it to have a ds_user_ptr
1136
* (and zil), but clone_swap() can close it.
1138
txg_wait_synced(ds->ds_dir->dd_pool, 0);
1140
if (ds != drc->drc_real_ds) {
1141
/* we are doing an online recv */
1142
if (dsl_dataset_tryown(ds, FALSE, dmu_recv_tag)) {
1143
err = dsl_dataset_clone_swap(drc->drc_real_ds, ds,
1146
dsl_dataset_disown(ds, dmu_recv_tag);
1149
dsl_dataset_rele(ds, dmu_recv_tag);
1151
/* dsl_dataset_destroy() will disown the ds */
1152
(void) dsl_dataset_destroy(drc->drc_real_ds, dmu_recv_tag);
1157
resa.creation_time = drc->drc_drrb->drr_creation_time;
1158
resa.toguid = drc->drc_drrb->drr_toguid;
1159
resa.tosnap = drc->drc_tosnap;
1161
err = dsl_sync_task_do(ds->ds_dir->dd_pool,
1162
recv_end_check, recv_end_sync, ds, &resa, 3);
1164
if (drc->drc_newfs) {
1165
ASSERT(ds == drc->drc_real_ds);
1166
(void) dsl_dataset_destroy(ds, dmu_recv_tag);
1169
(void) dsl_dataset_rollback(ds, DMU_OST_NONE);
1173
/* release the hold from dmu_recv_begin */
1174
dsl_dataset_disown(ds, dmu_recv_tag);
1429
if (drc->drc_logical_ds != drc->drc_real_ds)
1430
return (dmu_recv_existing_end(drc));
1432
return (dmu_recv_new_end(drc));