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;