Print this page
*** NO COMMENTS ***
        
*** 18,28 ****
   *
   * CDDL HEADER END
   */
  /*
   * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
!  * Copyright 2011 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>
--- 18,28 ----
   *
   * CDDL HEADER END
   */
  /*
   * Copyright (c) 2005, 2010, Oracle and/or its affiliates. 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,71 ****
  {
          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);
  
          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);
! 
          mutex_enter(&ds->ds_sendstream_lock);
          *dsp->dsa_off += len;
          mutex_exit(&ds->ds_sendstream_lock);
  
          return (dsp->dsa_err);
--- 57,74 ----
  {
          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);
!         }
          mutex_enter(&ds->ds_sendstream_lock);
          *dsp->dsa_off += len;
          mutex_exit(&ds->ds_sendstream_lock);
  
          return (dsp->dsa_err);
*** 356,389 ****
  
                  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;
                  int blksz = BP_GET_LSIZE(bp);
  
                  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;
                                      ptr++)
                                          *ptr = 0x2f5baddb10c;
                          } else {
                                  return (EIO);
                          }
                  }
  
                  err = dump_data(dsp, type, zb->zb_object, zb->zb_blkid * blksz,
!                     blksz, bp, abuf->b_data);
                  (void) arc_buf_remove_ref(abuf, &abuf);
          }
  
          ASSERT(err == 0 || err == EINTR);
          return (err);
  }
  
--- 359,399 ----
  
                  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 = 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;
                                              ptr++)
                                                  *ptr = 0x2f5baddb10c;
                                  } else {
                                          return (EIO);
                                  }
                          }
+                         buf = abuf->b_data;
+                 }
  
                  err = dump_data(dsp, type, zb->zb_object, zb->zb_blkid * blksz,
!                     blksz, bp, buf);
!                 if (!dsp->sendsize) {
                          (void) arc_buf_remove_ref(abuf, &abuf);
                  }
+         }
  
          ASSERT(err == 0 || err == EINTR);
          return (err);
  }
  
*** 424,436 ****
          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)
  {
          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;
--- 434,447 ----
          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, 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,503 ****
--- 505,515 ----
          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,515 ****
          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,
              backup_cb, dsp);
  
          if (dsp->dsa_pending_op != PENDING_NONE)
                  if (dump_bytes(dsp, drr, sizeof (dmu_replay_record_t)) != 0)
                          err = EINTR;
  
--- 516,534 ----
          if (dump_bytes(dsp, drr, sizeof (dmu_replay_record_t)) != 0) {
                  err = dsp->dsa_err;
                  goto out;
          }
  
!         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;