Print this page
*** NO COMMENTS ***
@@ -18,11 +18,11 @@
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
*/
#include <sys/dmu.h>
@@ -57,15 +57,18 @@
{
dsl_dataset_t *ds = dsp->dsa_os->os_dsl_dataset;
ssize_t resid; /* have to get resid to get detailed errno */
ASSERT3U(len % 8, ==, 0);
+ dsp->dsa_err = 0;
+ if (!dsp->sendsize) {
fletcher_4_incremental_native(buf, len, &dsp->dsa_zc);
dsp->dsa_err = vn_rdwr(UIO_WRITE, dsp->dsa_vp,
(caddr_t)buf, len,
- 0, UIO_SYSSPACE, FAPPEND, RLIM64_INFINITY, CRED(), &resid);
-
+ 0, UIO_SYSSPACE, FAPPEND, RLIM64_INFINITY,
+ CRED(), &resid);
+ }
mutex_enter(&ds->ds_sendstream_lock);
*dsp->dsa_off += len;
mutex_exit(&ds->ds_sendstream_lock);
return (dsp->dsa_err);
@@ -356,34 +359,41 @@
err = dump_spill(dsp, zb->zb_object, blksz, abuf->b_data);
(void) arc_buf_remove_ref(abuf, &abuf);
} else { /* it's a level-0 block of a regular object */
uint32_t aflags = ARC_WAIT;
- arc_buf_t *abuf;
+ arc_buf_t *abuf = NULL;
+ void *buf = NULL;
int blksz = BP_GET_LSIZE(bp);
+ if (!dsp->sendsize) {
if (dsl_read(NULL, spa, bp, pbuf,
arc_getbuf_func, &abuf, ZIO_PRIORITY_ASYNC_READ,
ZIO_FLAG_CANFAIL, &aflags, zb) != 0) {
if (zfs_send_corrupt_data) {
/* Send a block filled with 0x"zfs badd bloc" */
abuf = arc_buf_alloc(spa, blksz, &abuf,
ARC_BUFC_DATA);
uint64_t *ptr;
for (ptr = abuf->b_data;
- (char *)ptr < (char *)abuf->b_data + blksz;
+ (char *)ptr <
+ (char *)abuf->b_data + blksz;
ptr++)
*ptr = 0x2f5baddb10c;
} else {
return (EIO);
}
}
+ buf = abuf->b_data;
+ }
err = dump_data(dsp, type, zb->zb_object, zb->zb_blkid * blksz,
- blksz, bp, abuf->b_data);
+ blksz, bp, buf);
+ if (!dsp->sendsize) {
(void) arc_buf_remove_ref(abuf, &abuf);
}
+ }
ASSERT(err == 0 || err == EINTR);
return (err);
}
@@ -424,13 +434,14 @@
ret = is_before(origin, earlier);
dsl_dataset_rele(origin, FTAG);
return (ret);
}
+
int
dmu_send(objset_t *tosnap, objset_t *fromsnap, int outfd, vnode_t *vp,
- offset_t *off)
+ offset_t *off, boolean_t sendsize)
{
dsl_dataset_t *ds = tosnap->os_dsl_dataset;
dsl_dataset_t *fromds = fromsnap ? fromsnap->os_dsl_dataset : NULL;
dmu_replay_record_t *drr;
dmu_sendarg_t *dsp;
@@ -494,10 +505,11 @@
dsp->dsa_os = tosnap;
dsp->dsa_off = off;
dsp->dsa_toguid = ds->ds_phys->ds_guid;
ZIO_SET_CHECKSUM(&dsp->dsa_zc, 0, 0, 0, 0);
dsp->dsa_pending_op = PENDING_NONE;
+ dsp->sendsize = sendsize;
mutex_enter(&ds->ds_sendstream_lock);
list_insert_head(&ds->ds_sendstreams, dsp);
mutex_exit(&ds->ds_sendstream_lock);
@@ -504,12 +516,19 @@
if (dump_bytes(dsp, drr, sizeof (dmu_replay_record_t)) != 0) {
err = dsp->dsa_err;
goto out;
}
- err = traverse_dataset(ds, fromtxg, TRAVERSE_PRE | TRAVERSE_PREFETCH,
+ if (dsp->sendsize) {
+ err = traverse_dataset(ds, fromtxg,
+ TRAVERSE_PRE | TRAVERSE_PREFETCH_METADATA,
backup_cb, dsp);
+ } else {
+ err = traverse_dataset(ds,
+ fromtxg, TRAVERSE_PRE | TRAVERSE_PREFETCH,
+ backup_cb, dsp);
+ }
if (dsp->dsa_pending_op != PENDING_NONE)
if (dump_bytes(dsp, drr, sizeof (dmu_replay_record_t)) != 0)
err = EINTR;