~ubuntu-branches/ubuntu/quantal/zfs-fuse/quantal

« back to all changes in this revision

Viewing changes to src/lib/libzpool/dmu_send.c

  • Committer: Bazaar Package Importer
  • Author(s): Mike Hommey, Mike Hommey, Seth Heeren
  • Date: 2010-06-30 18:03:52 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20100630180352-d3jq25ytbcl23q3y
Tags: 0.6.9-1
* New upstream release.

[ Mike Hommey ]
* debian/control:
  - Build depend on libssl-dev and libattr1-dev, now required to build.
  - Build depend on docbook-xml to avoid xsltproc I/O error loading
    docbook DTD.
  - Add suggestions for a NFS server and kpartx.
* debian/man/*, debian/copyright, debian/rules: Remove manual pages, they
  are now shipped upstream.
* debian/copyright: Change download link.
* src/SConstruct:
  - Add an optim option to the build system.
  - Add support for DESTDIR.
  - Force debug=1 to mean optim, no strip, no debug.
  - Use -ffunction-sections, -fdata-sections, and --gc-sections flags to
    reduce the binary sizes.
* src/lib/libumem/SConscript: Cleanup src/lib/libumem when cleaning up
  build directory.
* src/cmd/*/SConscript: Don't link zfs, zpool and zdb against libssl.
* src/lib/libumem/SConscript: Only build static libumem.
* src/lib/libumem/sol_compat.h:
  - Add atomic cas support for sparc.
  - Use atomic functions from libsolcompat in libumem on unsupported
    platforms.
* debian/rules:
  - Set optimization level in build system according to DEB_BUILD_OPTIONS.
  - Build with debug=1 to have unstripped binaries ; dh_strip will do the
    right thing.
  - Don't depend on the local location of the docbook XSLT stylesheets.
    Use the catalogged url in place of the full path.
  - Don't clean src/.sconsign.dblite and src/path.pyc.
  - Set all destination directories when installing with scons.
  - Install bash completion and zfsrc files.
  - Don't use scons cache when building.
* debian/prerm: Remove /var/lib/zfs/zpool.cache in prerm.
* debian/dirs: Create /etc/bash_completion.d.
* debian/watch: Fix watch file.
* debian/rules, debian/control, debian/compat: Switch to dh.
* debian/README.Debian: Update README.Debian.
* debian/zfs-fuse.man.xml: Update zfs-fuse manual page.
* debian/zfs-fuse.init: Start sharing datasets marked as such at daemon
  startup.
* debian/rules, debian/control: Use config.guess and config.sub from
  autotools-dev.

[ Seth Heeren ]
* debian/zfs-fuse.man.xml:
  Added notes on the precedence, zfsrc, commandline, initscript vs.
  /etc/default/zfs-fuse on some systems.
* debian/zfs-fuse.init, debian/zfs-fuse.default: Deprecating DAEMON_OPTS.
* debian/zfs-fuse.init:
  - Removing import -a -f.
  - Removing the now unnecessary 'sleep 2'.
  - Extended shutdown wait to allow for zfs-fuse daemon's own shutdown
    timeouts.
  - Re-ordered dubious PATH setting.
* debian/zfs-fuse.init: Move existing zpool.cache to new location if
  possible.

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
#include <sys/dmu_traverse.h>
34
34
#include <sys/dsl_dataset.h>
35
35
#include <sys/dsl_dir.h>
 
36
#include <sys/dsl_prop.h>
36
37
#include <sys/dsl_pool.h>
37
38
#include <sys/dsl_synctask.h>
38
39
#include <sys/zfs_ioctl.h>
39
40
#include <sys/zap.h>
40
41
#include <sys/zio_checksum.h>
 
42
#include <sys/avl.h>
 
43
#include <sys/ddt.h>
41
44
 
42
45
static char *dmu_recv_tag = "dmu_recv_tag";
43
46
 
 
47
/*
 
48
 * The list of data whose inclusion in a send stream can be pending from
 
49
 * one call to backup_cb to another.  Multiple calls to dump_free() and
 
50
 * dump_freeobjects() can be aggregated into a single DRR_FREE or
 
51
 * DRR_FREEOBJECTS replay record.
 
52
 */
 
53
typedef enum {
 
54
        PENDING_NONE,
 
55
        PENDING_FREE,
 
56
        PENDING_FREEOBJECTS
 
57
} pendop_t;
 
58
 
44
59
struct backuparg {
45
60
        dmu_replay_record_t *drr;
46
61
        vnode_t *vp;
47
62
        offset_t *off;
48
63
        objset_t *os;
49
64
        zio_cksum_t zc;
 
65
        uint64_t toguid;
50
66
        int err;
 
67
        pendop_t pending_op;
51
68
};
52
69
 
53
70
static int
68
85
dump_free(struct backuparg *ba, uint64_t object, uint64_t offset,
69
86
    uint64_t length)
70
87
{
71
 
        /* write a FREE record */
 
88
        struct drr_free *drrf = &(ba->drr->drr_u.drr_free);
 
89
 
 
90
        /*
 
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.
 
96
         */
 
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)
 
99
                        return (EINTR);
 
100
                ba->pending_op = PENDING_NONE;
 
101
        }
 
102
 
 
103
        if (ba->pending_op == PENDING_FREE) {
 
104
                /*
 
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).
 
109
                 */
 
110
                ASSERT(length != -1ULL);
 
111
                /*
 
112
                 * Check to see whether this free block can be aggregated
 
113
                 * with pending one.
 
114
                 */
 
115
                if (drrf->drr_object == object && drrf->drr_offset +
 
116
                    drrf->drr_length == offset) {
 
117
                        drrf->drr_length += length;
 
118
                        return (0);
 
119
                } else {
 
120
                        /* not a continuation.  Push out pending record */
 
121
                        if (dump_bytes(ba, ba->drr,
 
122
                            sizeof (dmu_replay_record_t)) != 0)
 
123
                                return (EINTR);
 
124
                        ba->pending_op = PENDING_NONE;
 
125
                }
 
126
        }
 
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)
 
136
                        return (EINTR);
 
137
        } else {
 
138
                ba->pending_op = PENDING_FREE;
 
139
        }
77
140
 
78
 
        if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)))
79
 
                return (EINTR);
80
141
        return (0);
81
142
}
82
143
 
83
144
static int
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)
86
147
{
 
148
        struct drr_write *drrw = &(ba->drr->drr_u.drr_write);
 
149
 
 
150
 
 
151
        /*
 
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.
 
156
         */
 
157
        if (ba->pending_op != PENDING_NONE) {
 
158
                if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)) != 0)
 
159
                        return (EINTR);
 
160
                ba->pending_op = PENDING_NONE;
 
161
        }
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;
94
177
 
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)
96
179
                return (EINTR);
97
 
        if (dump_bytes(ba, data, blksz))
 
180
        if (dump_bytes(ba, data, blksz) != 0)
98
181
                return (EINTR);
99
182
        return (0);
100
183
}
102
185
static int
103
186
dump_freeobjects(struct backuparg *ba, uint64_t firstobj, uint64_t numobjs)
104
187
{
 
188
        struct drr_freeobjects *drrfo = &(ba->drr->drr_u.drr_freeobjects);
 
189
 
 
190
        /*
 
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.
 
196
         */
 
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)
 
200
                        return (EINTR);
 
201
                ba->pending_op = PENDING_NONE;
 
202
        }
 
203
        if (ba->pending_op == PENDING_FREEOBJECTS) {
 
204
                /*
 
205
                 * See whether this free object array can be aggregated
 
206
                 * with pending one
 
207
                 */
 
208
                if (drrfo->drr_firstobj + drrfo->drr_numobjs == firstobj) {
 
209
                        drrfo->drr_numobjs += numobjs;
 
210
                        return (0);
 
211
                } else {
 
212
                        /* can't be aggregated.  Push out pending record */
 
213
                        if (dump_bytes(ba, ba->drr,
 
214
                            sizeof (dmu_replay_record_t)) != 0)
 
215
                                return (EINTR);
 
216
                        ba->pending_op = PENDING_NONE;
 
217
                }
 
218
        }
 
219
 
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;
110
 
 
111
 
        if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)))
112
 
                return (EINTR);
 
223
        drrfo->drr_firstobj = firstobj;
 
224
        drrfo->drr_numobjs = numobjs;
 
225
        drrfo->drr_toguid = ba->toguid;
 
226
 
 
227
        ba->pending_op = PENDING_FREEOBJECTS;
 
228
 
113
229
        return (0);
114
230
}
115
231
 
116
232
static int
117
233
dump_dnode(struct backuparg *ba, uint64_t object, dnode_phys_t *dnp)
118
234
{
 
235
        struct drr_object *drro = &(ba->drr->drr_u.drr_object);
 
236
 
119
237
        if (dnp == NULL || dnp->dn_type == DMU_OT_NONE)
120
238
                return (dump_freeobjects(ba, object, 1));
121
239
 
 
240
        if (ba->pending_op != PENDING_NONE) {
 
241
                if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)) != 0)
 
242
                        return (EINTR);
 
243
                ba->pending_op = PENDING_NONE;
 
244
        }
 
245
 
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;
133
257
 
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)
135
259
                return (EINTR);
136
260
 
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)
138
262
                return (EINTR);
139
263
 
140
264
        /* free anything past the end of the file */
150
274
        (((uint64_t)dnp->dn_datablkszsec) << (SPA_MINBLOCKSHIFT + \
151
275
        (level) * (dnp->dn_indblkshift - SPA_BLKPTRSHIFT)))
152
276
 
 
277
/* ARGSUSED */
153
278
static int
154
 
backup_cb(spa_t *spa, blkptr_t *bp, const zbookmark_t *zb,
155
 
    const dnode_phys_t *dnp, void *arg)
 
279
backup_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
 
280
    const zbookmark_t *zb, const dnode_phys_t *dnp, void *arg)
156
281
{
157
282
        struct backuparg *ba = arg;
158
283
        dmu_object_type_t type = bp ? BP_GET_TYPE(bp) : DMU_OT_NONE;
161
286
        if (issig(JUSTLOOKING) && issig(FORREAL))
162
287
                return (EINTR);
163
288
 
164
 
        if (zb->zb_object != 0 && DMU_OBJECT_IS_SPECIAL(zb->zb_object)) {
 
289
        if (zb->zb_object != DMU_META_DNODE_OBJECT &&
 
290
            DMU_OBJECT_IS_SPECIAL(zb->zb_object)) {
165
291
                return (0);
166
 
        } else if (bp == NULL && zb->zb_object == 0) {
 
292
        } else if (bp == NULL && zb->zb_object == DMU_META_DNODE_OBJECT) {
167
293
                uint64_t span = BP_SPAN(dnp, zb->zb_level);
168
294
                uint64_t dnobj = (zb->zb_blkid * span) >> DNODE_SHIFT;
169
295
                err = dump_freeobjects(ba, dnobj, span >> DNODE_SHIFT);
204
330
                        return (EIO);
205
331
 
206
332
                err = dump_data(ba, type, zb->zb_object, zb->zb_blkid * blksz,
207
 
                    blksz, abuf->b_data);
 
333
                    blksz, bp, abuf->b_data);
208
334
                (void) arc_buf_remove_ref(abuf, &abuf);
209
335
        }
210
336
 
216
342
dmu_sendbackup(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,
217
343
    vnode_t *vp, offset_t *off)
218
344
{
219
 
        dsl_dataset_t *ds = tosnap->os->os_dsl_dataset;
220
 
        dsl_dataset_t *fromds = fromsnap ? fromsnap->os->os_dsl_dataset : NULL;
 
345
        dsl_dataset_t *ds = tosnap->os_dsl_dataset;
 
346
        dsl_dataset_t *fromds = fromsnap ? fromsnap->os_dsl_dataset : NULL;
221
347
        dmu_replay_record_t *drr;
222
348
        struct backuparg ba;
223
349
        int err;
254
380
        drr = kmem_zalloc(sizeof (dmu_replay_record_t), KM_SLEEP);
255
381
        drr->drr_type = DRR_BEGIN;
256
382
        drr->drr_u.drr_begin.drr_magic = DMU_BACKUP_MAGIC;
257
 
        drr->drr_u.drr_begin.drr_version = DMU_BACKUP_STREAM_VERSION;
 
383
        DMU_SET_STREAM_HDRTYPE(drr->drr_u.drr_begin.drr_versioninfo,
 
384
            DMU_SUBSTREAM);
258
385
        drr->drr_u.drr_begin.drr_creation_time =
259
386
            ds->ds_phys->ds_creation_time;
260
 
        drr->drr_u.drr_begin.drr_type = tosnap->os->os_phys->os_type;
 
387
        drr->drr_u.drr_begin.drr_type = tosnap->os_phys->os_type;
261
388
        if (fromorigin)
262
389
                drr->drr_u.drr_begin.drr_flags |= DRR_FLAG_CLONE;
263
390
        drr->drr_u.drr_begin.drr_toguid = ds->ds_phys->ds_guid;
277
404
        ba.vp = vp;
278
405
        ba.os = tosnap;
279
406
        ba.off = off;
 
407
        ba.toguid = ds->ds_phys->ds_guid;
280
408
        ZIO_SET_CHECKSUM(&ba.zc, 0, 0, 0, 0);
 
409
        ba.pending_op = PENDING_NONE;
281
410
 
282
 
        if (dump_bytes(&ba, drr, sizeof (dmu_replay_record_t))) {
 
411
        if (dump_bytes(&ba, drr, sizeof (dmu_replay_record_t)) != 0) {
283
412
                kmem_free(drr, sizeof (dmu_replay_record_t));
284
413
                return (ba.err);
285
414
        }
287
416
        err = traverse_dataset(ds, fromtxg, TRAVERSE_PRE | TRAVERSE_PREFETCH,
288
417
            backup_cb, &ba);
289
418
 
 
419
        if (ba.pending_op != PENDING_NONE)
 
420
                if (dump_bytes(&ba, drr, sizeof (dmu_replay_record_t)) != 0)
 
421
                        err = EINTR;
 
422
 
290
423
        if (err) {
291
424
                if (err == EINTR && ba.err)
292
425
                        err = ba.err;
297
430
        bzero(drr, sizeof (dmu_replay_record_t));
298
431
        drr->drr_type = DRR_END;
299
432
        drr->drr_u.drr_end.drr_checksum = ba.zc;
 
433
        drr->drr_u.drr_end.drr_toguid = ba.toguid;
300
434
 
301
 
        if (dump_bytes(&ba, drr, sizeof (dmu_replay_record_t))) {
 
435
        if (dump_bytes(&ba, drr, sizeof (dmu_replay_record_t)) != 0) {
302
436
                kmem_free(drr, sizeof (dmu_replay_record_t));
303
437
                return (ba.err);
304
438
        }
321
455
        dsl_dataset_t *ds; /* the ds to recv into; returned from the syncfunc */
322
456
};
323
457
 
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)
327
 
{
328
 
        dsl_dataset_t *ds;
329
 
 
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));
334
 
 
335
 
        if (type != DMU_OST_NONE) {
336
 
                (void) dmu_objset_create_impl(dp->dp_spa,
337
 
                    ds, &ds->ds_phys->ds_bp, type, tx);
338
 
        }
339
 
 
340
 
        spa_history_internal_log(LOG_DS_REPLAY_FULL_SYNC,
341
 
            dp->dp_spa, tx, cr, "dataset = %lld", dsobj);
342
 
 
343
 
        return (ds);
344
 
}
345
 
 
346
458
/* ARGSUSED */
347
459
static int
348
 
recv_full_check(void *arg1, void *arg2, dmu_tx_t *tx)
 
460
recv_new_check(void *arg1, void *arg2, dmu_tx_t *tx)
349
461
{
350
462
        dsl_dir_t *dd = arg1;
351
463
        struct recvbeginsyncarg *rbsa = arg2;
363
475
                /* make sure it's a snap in the same pool */
364
476
                if (rbsa->origin->ds_dir->dd_pool != dd->dd_pool)
365
477
                        return (EXDEV);
366
 
                if (rbsa->origin->ds_phys->ds_num_children == 0)
 
478
                if (!dsl_dataset_is_snapshot(rbsa->origin))
367
479
                        return (EINVAL);
368
480
                if (rbsa->origin->ds_phys->ds_guid != rbsa->fromguid)
369
481
                        return (ENODEV);
373
485
}
374
486
 
375
487
static void
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)
377
489
{
378
490
        dsl_dir_t *dd = arg1;
379
491
        struct recvbeginsyncarg *rbsa = arg2;
380
492
        uint64_t flags = DS_FLAG_INCONSISTENT | rbsa->dsflags;
381
493
        uint64_t dsobj;
382
494
 
 
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);
385
 
 
386
 
        rbsa->ds = recv_full_sync_impl(dd->dd_pool, dsobj,
387
 
            rbsa->origin ? DMU_OST_NONE : rbsa->type, cr, tx);
388
 
}
389
 
 
390
 
static int
391
 
recv_full_existing_check(void *arg1, void *arg2, dmu_tx_t *tx)
392
 
{
393
 
        dsl_dataset_t *ds = arg1;
394
 
        struct recvbeginsyncarg *rbsa = arg2;
395
 
        int err;
396
 
 
397
 
        /* must be a head ds */
398
 
        if (ds->ds_phys->ds_next_snap_obj != 0)
399
 
                return (EINVAL);
400
 
 
401
 
        /* must not be a clone ds */
402
 
        if (dsl_dir_is_clone(ds->ds_dir))
403
 
                return (EINVAL);
404
 
 
405
 
        err = dsl_dataset_destroy_check(ds, rbsa->tag, tx);
406
 
        if (err)
407
 
                return (err);
408
 
 
409
 
        if (rbsa->origin) {
410
 
                /* make sure it's a snap in the same pool */
411
 
                if (rbsa->origin->ds_dir->dd_pool != ds->ds_dir->dd_pool)
412
 
                        return (EXDEV);
413
 
                if (rbsa->origin->ds_phys->ds_num_children == 0)
414
 
                        return (EINVAL);
415
 
                if (rbsa->origin->ds_phys->ds_guid != rbsa->fromguid)
416
 
                        return (ENODEV);
 
498
        VERIFY(0 == dsl_dataset_own_obj(dd->dd_pool, dsobj,
 
499
            B_TRUE, dmu_recv_tag, &rbsa->ds));
 
500
 
 
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);
417
504
        }
418
505
 
419
 
        return (0);
420
 
}
421
 
 
422
 
static void
423
 
recv_full_existing_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx)
424
 
{
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;
429
 
        uint64_t dsobj;
430
 
 
431
 
        /*
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
434
 
         * dataset.
435
 
         */
436
 
        dsl_dataset_destroy_sync(ds, rbsa->tag, cr, tx);
437
 
 
438
 
        dsobj = dsl_dataset_create_sync_dd(dd, rbsa->origin, flags, tx);
439
 
 
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);
442
508
}
443
509
 
444
510
/* ARGSUSED */
445
511
static int
446
 
recv_incremental_check(void *arg1, void *arg2, dmu_tx_t *tx)
 
512
recv_existing_check(void *arg1, void *arg2, dmu_tx_t *tx)
447
513
{
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);
456
522
 
457
 
        /* must already be a snapshot of this fs */
458
 
        if (ds->ds_phys->ds_prev_snap_obj == 0)
459
 
                return (ENODEV);
 
523
        if (rbsa->fromguid) {
 
524
                /* if incremental, most recent snapshot must match fromguid */
 
525
                if (ds->ds_prev == NULL)
 
526
                        return (ENODEV);
460
527
 
461
 
        /* most recent snapshot must match fromguid */
462
 
        if (ds->ds_prev->ds_phys->ds_guid != rbsa->fromguid)
463
 
                return (ENODEV);
 
528
                /*
 
529
                 * most recent snapshot must match fromguid, or there are no
 
530
                 * changes since the fromguid one
 
531
                 */
 
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;
 
535
                        while (obj != 0) {
 
536
                                dsl_dataset_t *snap;
 
537
                                err = dsl_dataset_hold_obj(ds->ds_dir->dd_pool,
 
538
                                    obj, FTAG, &snap);
 
539
                                if (err)
 
540
                                        return (ENODEV);
 
541
                                if (snap->ds_phys->ds_creation_txg < birth) {
 
542
                                        dsl_dataset_rele(snap, FTAG);
 
543
                                        return (ENODEV);
 
544
                                }
 
545
                                if (snap->ds_phys->ds_guid == rbsa->fromguid) {
 
546
                                        dsl_dataset_rele(snap, FTAG);
 
547
                                        break; /* it's ok */
 
548
                                }
 
549
                                obj = snap->ds_phys->ds_prev_snap_obj;
 
550
                                dsl_dataset_rele(snap, FTAG);
 
551
                        }
 
552
                        if (obj == 0)
 
553
                                return (ENODEV);
 
554
                }
 
555
        } else {
 
556
                /* if full, most recent snapshot must be $ORIGIN */
 
557
                if (ds->ds_phys->ds_prev_snap_txg >= TXG_INITIAL)
 
558
                        return (ENODEV);
 
559
        }
464
560
 
465
561
        /* temporary clone name must not exist */
466
562
        err = zap_lookup(ds->ds_dir->dd_pool->dp_meta_objset,
483
579
 
484
580
/* ARGSUSED */
485
581
static void
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)
487
583
{
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;
 
587
        dsl_dataset_t *cds;
492
588
        uint64_t flags = DS_FLAG_INCONSISTENT | rbsa->dsflags;
493
589
        uint64_t dsobj;
494
590
 
495
 
        /* create the temporary clone */
496
 
        VERIFY(0 == dsl_dataset_hold_obj(dp, ohds->ds_phys->ds_prev_snap_obj,
497
 
            FTAG, &ods));
498
 
        dsobj = dsl_dataset_create_sync(ohds->ds_dir,
499
 
            rbsa->clonelastname, ods, flags, cr, tx);
500
 
        dsl_dataset_rele(ods, FTAG);
501
 
 
502
 
        /* open the temporary clone */
503
 
        VERIFY(0 == dsl_dataset_own_obj(dp, dsobj,
504
 
            DS_MODE_INCONSISTENT, dmu_recv_tag, &cds));
505
 
 
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));
 
595
 
 
596
        /*
 
597
         * If we actually created a non-clone, we need to create the
 
598
         * objset in our new dataset.
 
599
         */
 
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);
 
603
        }
509
604
 
510
605
        rbsa->ds = cds;
511
606
 
513
608
            dp->dp_spa, tx, cr, "dataset = %lld", dsobj);
514
609
}
515
610
 
516
 
/* ARGSUSED */
517
 
static void
518
 
recv_offline_incremental_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx)
519
 
{
520
 
        dsl_dataset_t *ds = arg1;
521
 
 
522
 
        dmu_buf_will_dirty(ds->ds_dbuf, tx);
523
 
        ds->ds_phys->ds_flags |= DS_FLAG_INCONSISTENT;
524
 
 
525
 
        spa_history_internal_log(LOG_DS_REPLAY_INC_SYNC,
526
 
            ds->ds_dir->dd_pool->dp_spa, tx, cr, "dataset = %lld",
527
 
            ds->ds_object);
528
 
}
529
 
 
530
611
/*
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.
533
614
 */
534
615
int
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)
537
618
{
538
619
        int err = 0;
539
620
        boolean_t byteswap;
540
 
        struct recvbeginsyncarg rbsa;
541
 
        uint64_t version;
 
621
        struct recvbeginsyncarg rbsa = { 0 };
 
622
        uint64_t versioninfo;
542
623
        int flags;
543
624
        dsl_dataset_t *ds;
544
625
 
551
632
 
552
633
        rbsa.tofs = tofs;
553
634
        rbsa.tosnap = tosnap;
554
 
        rbsa.origin = origin ? origin->os->os_dsl_dataset : NULL;
 
635
        rbsa.origin = origin ? origin->os_dsl_dataset : NULL;
555
636
        rbsa.fromguid = drrb->drr_fromguid;
556
637
        rbsa.type = drrb->drr_type;
557
638
        rbsa.tag = FTAG;
558
639
        rbsa.dsflags = 0;
559
 
        version = drrb->drr_version;
 
640
        versioninfo = drrb->drr_versioninfo;
560
641
        flags = drrb->drr_flags;
561
642
 
562
643
        if (byteswap) {
563
644
                rbsa.type = BSWAP_32(rbsa.type);
564
645
                rbsa.fromguid = BSWAP_64(rbsa.fromguid);
565
 
                version = BSWAP_64(version);
 
646
                versioninfo = BSWAP_64(versioninfo);
566
647
                flags = BSWAP_32(flags);
567
648
        }
568
649
 
569
 
        if (version != DMU_BACKUP_STREAM_VERSION ||
 
650
        if (DMU_GET_STREAM_HDRTYPE(versioninfo) == DMU_COMPOUNDSTREAM ||
570
651
            rbsa.type >= DMU_OST_NUMTYPES ||
571
652
            ((flags & DRR_FLAG_CLONE) && origin == NULL))
572
653
                return (EINVAL);
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;
581
663
 
582
664
        /*
583
665
         * Process the begin in syncing context.
584
666
         */
585
 
        if (rbsa.fromguid && !(flags & DRR_FLAG_CLONE) && !online) {
586
 
                /* offline incremental receive */
587
 
                err = dsl_dataset_own(tofs, 0, dmu_recv_tag, &ds);
588
 
                if (err)
589
 
                        return (err);
590
 
 
591
 
                /*
592
 
                 * Only do the rollback if the most recent snapshot
593
 
                 * matches the incremental source
594
 
                 */
595
 
                if (force) {
596
 
                        if (ds->ds_prev == NULL ||
597
 
                            ds->ds_prev->ds_phys->ds_guid !=
598
 
                            rbsa.fromguid) {
599
 
                                dsl_dataset_disown(ds, dmu_recv_tag);
600
 
                                return (ENODEV);
601
 
                        }
602
 
                        (void) dsl_dataset_rollback(ds, DMU_OST_NONE);
603
 
                }
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);
608
 
                if (err) {
609
 
                        dsl_dataset_disown(ds, dmu_recv_tag);
610
 
                        return (err);
611
 
                }
612
 
                drc->drc_logical_ds = drc->drc_real_ds = ds;
613
 
        } else if (rbsa.fromguid && !(flags & DRR_FLAG_CLONE)) {
614
 
                /* online incremental receive */
 
667
 
 
668
        /* open the dataset we are logically receiving into */
 
669
        err = dsl_dataset_hold(tofs, dmu_recv_tag, &ds);
 
670
        if (err == 0) {
 
671
                /* target fs already exists; recv into temp clone */
 
672
 
 
673
                /* Can't recv a clone into an existing fs */
 
674
                if (flags & DRR_FLAG_CLONE) {
 
675
                        dsl_dataset_rele(ds, dmu_recv_tag);
 
676
                        return (EINVAL);
 
677
                }
 
678
 
 
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);
 
682
                        return (EBUSY);
 
683
                }
615
684
 
616
685
                /* tmp clone name is: tofs/%tosnap" */
617
686
                (void) snprintf(rbsa.clonelastname, sizeof (rbsa.clonelastname),
618
687
                    "%%%s", tosnap);
619
 
 
620
 
                /* open the dataset we are logically receiving into */
621
 
                err = dsl_dataset_hold(tofs, dmu_recv_tag, &ds);
622
 
                if (err)
623
 
                        return (err);
624
 
 
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);
629
691
                if (err) {
 
692
                        mutex_exit(&ds->ds_recvlock);
630
693
                        dsl_dataset_rele(ds, dmu_recv_tag);
631
694
                        return (err);
632
695
                }
633
696
                drc->drc_logical_ds = ds;
634
697
                drc->drc_real_ds = rbsa.ds;
635
 
        } else {
636
 
                /* create new fs -- full backup or clone */
637
 
                dsl_dir_t *dd = NULL;
638
 
                const char *tail;
639
 
 
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 */
 
700
                char *cp;
 
701
 
 
702
                /*
 
703
                 * If it's a non-clone incremental, we are missing the
 
704
                 * target fs, so fail the recv.
 
705
                 */
 
706
                if (rbsa.fromguid && !(flags & DRR_FLAG_CLONE))
 
707
                        return (ENOENT);
 
708
 
 
709
                /* Open the parent of tofs */
 
710
                cp = strrchr(tofs, '/');
 
711
                *cp = '\0';
 
712
                err = dsl_dataset_hold(tofs, FTAG, &ds);
 
713
                *cp = '/';
641
714
                if (err)
642
715
                        return (err);
643
 
                if (tail == NULL) {
644
 
                        if (!force) {
645
 
                                dsl_dir_close(dd, FTAG);
646
 
                                return (EEXIST);
647
 
                        }
648
 
 
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);
654
 
                        if (err) {
655
 
                                dsl_dir_close(dd, FTAG);
656
 
                                return (err);
657
 
                        }
658
 
 
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);
664
 
                } else {
665
 
                        err = dsl_sync_task_do(dd->dd_pool, recv_full_check,
666
 
                            recv_full_sync, dd, &rbsa, 5);
667
 
                }
668
 
                dsl_dir_close(dd, FTAG);
 
716
 
 
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);
669
720
                if (err)
670
721
                        return (err);
671
722
                drc->drc_logical_ds = drc->drc_real_ds = rbsa.ds;
672
723
                drc->drc_newfs = B_TRUE;
673
724
        }
674
725
 
675
 
        return (0);
 
726
        return (err);
676
727
}
677
728
 
678
729
struct restorearg {
683
734
        uint64_t voff;
684
735
        int bufsize; /* amount of memory allocated for buf */
685
736
        zio_cksum_t cksum;
 
737
        avl_tree_t guid_to_ds_map;
686
738
};
687
739
 
 
740
typedef struct guid_map_entry {
 
741
        uint64_t        guid;
 
742
        dsl_dataset_t   *gme_ds;
 
743
        avl_node_t      avlnode;
 
744
} guid_map_entry_t;
 
745
 
 
746
static int
 
747
guid_compare(const void *arg1, const void *arg2)
 
748
{
 
749
        const guid_map_entry_t *gmep1 = arg1;
 
750
        const guid_map_entry_t *gmep2 = arg2;
 
751
 
 
752
        if (gmep1->guid < gmep2->guid)
 
753
                return (-1);
 
754
        else if (gmep1->guid > gmep2->guid)
 
755
                return (1);
 
756
        return (0);
 
757
}
 
758
 
 
759
/*
 
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.
 
768
 */
 
769
int
 
770
find_ds_by_guid(const char *name, void *arg)
 
771
{
 
772
        avl_tree_t *guid_map = arg;
 
773
        dsl_dataset_t *ds, *snapds;
 
774
        guid_map_entry_t *gmep;
 
775
        dsl_pool_t *dp;
 
776
        int err;
 
777
        uint64_t lastobj, firstobj;
 
778
 
 
779
        if (dsl_dataset_hold(name, FTAG, &ds) != 0)
 
780
                return (0);
 
781
 
 
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;
 
786
 
 
787
        while (lastobj != firstobj) {
 
788
                err = dsl_dataset_hold_obj(dp, lastobj, guid_map, &snapds);
 
789
                if (err) {
 
790
                        /*
 
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
 
794
                         * processed.
 
795
                         */
 
796
                        rw_exit(&dp->dp_config_rwlock);
 
797
                        dsl_dataset_rele(ds, FTAG);
 
798
                        return (0);
 
799
                }
 
800
 
 
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;
 
806
        }
 
807
 
 
808
        rw_exit(&dp->dp_config_rwlock);
 
809
        dsl_dataset_rele(ds, FTAG);
 
810
 
 
811
        return (0);
 
812
}
 
813
 
688
814
static void *
689
815
restore_read(struct restorearg *ra, int len)
690
816
{
729
855
        switch (drr->drr_type) {
730
856
        case DRR_BEGIN:
731
857
                DO64(drr_begin.drr_magic);
732
 
                DO64(drr_begin.drr_version);
 
858
                DO64(drr_begin.drr_versioninfo);
733
859
                DO64(drr_begin.drr_creation_time);
734
860
                DO32(drr_begin.drr_type);
735
861
                DO32(drr_begin.drr_flags);
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);
746
873
                break;
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);
750
878
                break;
751
879
        case DRR_WRITE:
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);
 
890
                break;
 
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);
756
904
                break;
757
905
        case DRR_FREE:
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);
761
910
                break;
762
911
        case DRR_END:
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);
767
917
                break;
768
918
        }
769
919
#undef DO64
780
930
        if (drro->drr_type == DMU_OT_NONE ||
781
931
            drro->drr_type >= DMU_OT_NUMTYPES ||
782
932
            drro->drr_bonustype >= DMU_OT_NUMTYPES ||
783
 
            drro->drr_checksum >= ZIO_CHECKSUM_FUNCTIONS ||
 
933
            drro->drr_checksumtype >= ZIO_CHECKSUM_FUNCTIONS ||
784
934
            drro->drr_compress >= ZIO_COMPRESS_FUNCTIONS ||
785
935
            P2PHASE(drro->drr_blksz, SPA_MINBLOCKSIZE) ||
786
936
            drro->drr_blksz < SPA_MINBLOCKSIZE ||
830
980
                return (err);
831
981
        }
832
982
 
833
 
        dmu_object_set_checksum(os, drro->drr_object, drro->drr_checksum, tx);
 
983
        dmu_object_set_checksum(os, drro->drr_object, drro->drr_checksumtype,
 
984
            tx);
834
985
        dmu_object_set_compress(os, drro->drr_object, drro->drr_compress, tx);
835
986
 
836
987
        if (data != NULL) {
912
1063
        return (0);
913
1064
}
914
1065
 
 
1066
/*
 
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.
 
1072
 */
 
1073
static int
 
1074
restore_write_byref(struct restorearg *ra, objset_t *os,
 
1075
    struct drr_write_byref *drrwbr)
 
1076
{
 
1077
        dmu_tx_t *tx;
 
1078
        int err;
 
1079
        guid_map_entry_t gmesrch;
 
1080
        guid_map_entry_t *gmep;
 
1081
        avl_index_t     where;
 
1082
        objset_t *ref_os = NULL;
 
1083
        dmu_buf_t *dbp;
 
1084
 
 
1085
        if (drrwbr->drr_offset + drrwbr->drr_length < drrwbr->drr_offset)
 
1086
                return (EINVAL);
 
1087
 
 
1088
        /*
 
1089
         * If the GUID of the referenced dataset is different from the
 
1090
         * GUID of the target dataset, find the referenced dataset.
 
1091
         */
 
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,
 
1095
                    &where)) == NULL) {
 
1096
                        return (EINVAL);
 
1097
                }
 
1098
                if (dmu_objset_from_ds(gmep->gme_ds, &ref_os))
 
1099
                        return (EINVAL);
 
1100
        } else {
 
1101
                ref_os = os;
 
1102
        }
 
1103
 
 
1104
        if (err = dmu_buf_hold(ref_os, drrwbr->drr_refobject,
 
1105
            drrwbr->drr_refoffset, FTAG, &dbp))
 
1106
                return (err);
 
1107
 
 
1108
        tx = dmu_tx_create(os);
 
1109
 
 
1110
        dmu_tx_hold_write(tx, drrwbr->drr_object,
 
1111
            drrwbr->drr_offset, drrwbr->drr_length);
 
1112
        err = dmu_tx_assign(tx, TXG_WAIT);
 
1113
        if (err) {
 
1114
                dmu_tx_abort(tx);
 
1115
                return (err);
 
1116
        }
 
1117
        dmu_write(os, drrwbr->drr_object,
 
1118
            drrwbr->drr_offset, drrwbr->drr_length, dbp->db_data, tx);
 
1119
        dmu_buf_rele(dbp, FTAG);
 
1120
        dmu_tx_commit(tx);
 
1121
        return (0);
 
1122
}
 
1123
 
915
1124
/* ARGSUSED */
916
1125
static int
917
1126
restore_free(struct restorearg *ra, objset_t *os,
931
1140
        return (err);
932
1141
}
933
1142
 
934
 
void
935
 
dmu_recv_abort_cleanup(dmu_recv_cookie_t *drc)
936
 
{
937
 
        if (drc->drc_newfs || drc->drc_real_ds != drc->drc_logical_ds) {
938
 
                /*
939
 
                 * online incremental or new fs: destroy the fs (which
940
 
                 * may be a clone) that we created
941
 
                 */
942
 
                (void) dsl_dataset_destroy(drc->drc_real_ds, dmu_recv_tag);
943
 
                if (drc->drc_real_ds != drc->drc_logical_ds)
944
 
                        dsl_dataset_rele(drc->drc_logical_ds, dmu_recv_tag);
945
 
        } else {
946
 
                /*
947
 
                 * offline incremental: rollback to most recent snapshot.
948
 
                 */
949
 
                (void) dsl_dataset_rollback(drc->drc_real_ds, DMU_OST_NONE);
950
 
                dsl_dataset_disown(drc->drc_real_ds, dmu_recv_tag);
951
 
        }
952
 
}
953
 
 
954
1143
/*
955
1144
 * NB: callers *must* call dmu_recv_end() if this succeeds.
956
1145
 */
961
1150
        dmu_replay_record_t *drr;
962
1151
        objset_t *os;
963
1152
        zio_cksum_t pcksum;
 
1153
        guid_map_entry_t *gmep;
 
1154
        int featureflags;
964
1155
 
965
1156
        if (drc->drc_drrb->drr_magic == BSWAP_64(DMU_BACKUP_MAGIC))
966
1157
                ra.byteswap = TRUE;
985
1176
        if (ra.byteswap) {
986
1177
                struct drr_begin *drrb = drc->drc_drrb;
987
1178
                drrb->drr_magic = BSWAP_64(drrb->drr_magic);
988
 
                drrb->drr_version = BSWAP_64(drrb->drr_version);
 
1179
                drrb->drr_versioninfo = BSWAP_64(drrb->drr_versioninfo);
989
1180
                drrb->drr_creation_time = BSWAP_64(drrb->drr_creation_time);
990
1181
                drrb->drr_type = BSWAP_32(drrb->drr_type);
991
1182
                drrb->drr_toguid = BSWAP_64(drrb->drr_toguid);
998
1189
        ra.buf = kmem_alloc(ra.bufsize, KM_SLEEP);
999
1190
 
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) ==
 
1193
            DMU_SUBSTREAM);
1002
1194
        ASSERT(drc->drc_drrb->drr_type < DMU_OST_NUMTYPES);
1003
1195
 
1004
1196
        /*
1005
1197
         * Open the objset we are modifying.
1006
1198
         */
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);
1008
1200
 
1009
1201
        ASSERT(drc->drc_real_ds->ds_phys->ds_flags & DS_FLAG_INCONSISTENT);
1010
1202
 
 
1203
        featureflags = DMU_GET_FEATUREFLAGS(drc->drc_drrb->drr_versioninfo);
 
1204
 
 
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,
 
1212
                    DS_FIND_CHILDREN);
 
1213
        }
 
1214
 
1011
1215
        /*
1012
1216
         * Read records and process them.
1013
1217
         */
1047
1251
                        ra.err = restore_write(&ra, os, &drrw);
1048
1252
                        break;
1049
1253
                }
 
1254
                case DRR_WRITE_BYREF:
 
1255
                {
 
1256
                        struct drr_write_byref drrwbr =
 
1257
                            drr->drr_u.drr_write_byref;
 
1258
                        ra.err = restore_write_byref(&ra, os, &drrwbr);
 
1259
                        break;
 
1260
                }
1050
1261
                case DRR_FREE:
1051
1262
                {
1052
1263
                        struct drr_free drrf = drr->drr_u.drr_free;
1074
1285
        ASSERT(ra.err != 0);
1075
1286
 
1076
1287
out:
1077
 
        dmu_objset_close(os);
1078
 
 
1079
1288
        if (ra.err != 0) {
1080
1289
                /*
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.
1083
1292
                 */
1084
1293
                txg_wait_synced(drc->drc_real_ds->ds_dir->dd_pool, 0);
1085
 
                dmu_recv_abort_cleanup(drc);
 
1294
 
 
1295
                (void) dsl_dataset_destroy(drc->drc_real_ds, dmu_recv_tag,
 
1296
                    B_FALSE);
 
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);
 
1300
                }
 
1301
        }
 
1302
 
 
1303
        if (featureflags & DMU_BACKUP_FEATURE_DEDUP) {
 
1304
                void *cookie = NULL;
 
1305
 
 
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));
 
1309
                }
 
1310
                avl_destroy(&ra.guid_to_ds_map);
1086
1311
        }
1087
1312
 
1088
1313
        kmem_free(ra.buf, ra.bufsize);
1123
1348
        ds->ds_phys->ds_flags &= ~DS_FLAG_INCONSISTENT;
1124
1349
}
1125
1350
 
 
1351
static int
 
1352
dmu_recv_existing_end(dmu_recv_cookie_t *drc)
 
1353
{
 
1354
        struct recvendsyncarg resa;
 
1355
        dsl_dataset_t *ds = drc->drc_logical_ds;
 
1356
        int err;
 
1357
 
 
1358
        /*
 
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()
 
1361
         * can close it.
 
1362
         */
 
1363
        txg_wait_synced(ds->ds_dir->dd_pool, 0);
 
1364
 
 
1365
        if (dsl_dataset_tryown(ds, FALSE, dmu_recv_tag)) {
 
1366
                err = dsl_dataset_clone_swap(drc->drc_real_ds, ds,
 
1367
                    drc->drc_force);
 
1368
                if (err)
 
1369
                        goto out;
 
1370
        } else {
 
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,
 
1374
                    B_FALSE);
 
1375
                return (EBUSY);
 
1376
        }
 
1377
 
 
1378
        resa.creation_time = drc->drc_drrb->drr_creation_time;
 
1379
        resa.toguid = drc->drc_drrb->drr_toguid;
 
1380
        resa.tosnap = drc->drc_tosnap;
 
1381
 
 
1382
        err = dsl_sync_task_do(ds->ds_dir->dd_pool,
 
1383
            recv_end_check, recv_end_sync, ds, &resa, 3);
 
1384
        if (err) {
 
1385
                /* swap back */
 
1386
                (void) dsl_dataset_clone_swap(drc->drc_real_ds, ds, B_TRUE);
 
1387
        }
 
1388
 
 
1389
out:
 
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);
 
1393
        return (err);
 
1394
}
 
1395
 
 
1396
static int
 
1397
dmu_recv_new_end(dmu_recv_cookie_t *drc)
 
1398
{
 
1399
        struct recvendsyncarg resa;
 
1400
        dsl_dataset_t *ds = drc->drc_logical_ds;
 
1401
        int err;
 
1402
 
 
1403
        /*
 
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()
 
1406
         * can close it.
 
1407
         */
 
1408
        txg_wait_synced(ds->ds_dir->dd_pool, 0);
 
1409
 
 
1410
        resa.creation_time = drc->drc_drrb->drr_creation_time;
 
1411
        resa.toguid = drc->drc_drrb->drr_toguid;
 
1412
        resa.tosnap = drc->drc_tosnap;
 
1413
 
 
1414
        err = dsl_sync_task_do(ds->ds_dir->dd_pool,
 
1415
            recv_end_check, recv_end_sync, ds, &resa, 3);
 
1416
        if (err) {
 
1417
                /* clean up the fs we just recv'd into */
 
1418
                (void) dsl_dataset_destroy(ds, dmu_recv_tag, B_FALSE);
 
1419
        } else {
 
1420
                /* release the hold from dmu_recv_begin */
 
1421
                dsl_dataset_disown(ds, dmu_recv_tag);
 
1422
        }
 
1423
        return (err);
 
1424
}
 
1425
 
1126
1426
int
1127
1427
dmu_recv_end(dmu_recv_cookie_t *drc)
1128
1428
{
1129
 
        struct recvendsyncarg resa;
1130
 
        dsl_dataset_t *ds = drc->drc_logical_ds;
1131
 
        int err;
1132
 
 
1133
 
        /*
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.
1137
 
         */
1138
 
        txg_wait_synced(ds->ds_dir->dd_pool, 0);
1139
 
 
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,
1144
 
                            drc->drc_force);
1145
 
                        if (err)
1146
 
                                dsl_dataset_disown(ds, dmu_recv_tag);
1147
 
                } else {
1148
 
                        err = EBUSY;
1149
 
                        dsl_dataset_rele(ds, dmu_recv_tag);
1150
 
                }
1151
 
                /* dsl_dataset_destroy() will disown the ds */
1152
 
                (void) dsl_dataset_destroy(drc->drc_real_ds, dmu_recv_tag);
1153
 
                if (err)
1154
 
                        return (err);
1155
 
        }
1156
 
 
1157
 
        resa.creation_time = drc->drc_drrb->drr_creation_time;
1158
 
        resa.toguid = drc->drc_drrb->drr_toguid;
1159
 
        resa.tosnap = drc->drc_tosnap;
1160
 
 
1161
 
        err = dsl_sync_task_do(ds->ds_dir->dd_pool,
1162
 
            recv_end_check, recv_end_sync, ds, &resa, 3);
1163
 
        if (err) {
1164
 
                if (drc->drc_newfs) {
1165
 
                        ASSERT(ds == drc->drc_real_ds);
1166
 
                        (void) dsl_dataset_destroy(ds, dmu_recv_tag);
1167
 
                        return (err);
1168
 
                } else {
1169
 
                        (void) dsl_dataset_rollback(ds, DMU_OST_NONE);
1170
 
                }
1171
 
        }
1172
 
 
1173
 
        /* release the hold from dmu_recv_begin */
1174
 
        dsl_dataset_disown(ds, dmu_recv_tag);
1175
 
        return (err);
 
1429
        if (drc->drc_logical_ds != drc->drc_real_ds)
 
1430
                return (dmu_recv_existing_end(drc));
 
1431
        else
 
1432
                return (dmu_recv_new_end(drc));
1176
1433
}