Print this page
*** NO COMMENTS ***

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/zfs/dmu_send.c
          +++ new/usr/src/uts/common/fs/zfs/dmu_send.c
↓ open down ↓ 12 lines elided ↑ open up ↑
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23      - * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
       23 + * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
  24   24   * Copyright (c) 2012 by Delphix. All rights reserved.
  25   25   * Copyright (c) 2012, Joyent, Inc. All rights reserved.
  26   26   */
  27   27  
  28   28  #include <sys/dmu.h>
  29   29  #include <sys/dmu_impl.h>
  30   30  #include <sys/dmu_tx.h>
  31   31  #include <sys/dbuf.h>
  32   32  #include <sys/dnode.h>
  33   33  #include <sys/zfs_context.h>
↓ open down ↓ 18 lines elided ↑ open up ↑
  52   52  
  53   53  static char *dmu_recv_tag = "dmu_recv_tag";
  54   54  
  55   55  static int
  56   56  dump_bytes(dmu_sendarg_t *dsp, void *buf, int len)
  57   57  {
  58   58          dsl_dataset_t *ds = dsp->dsa_os->os_dsl_dataset;
  59   59          ssize_t resid; /* have to get resid to get detailed errno */
  60   60          ASSERT3U(len % 8, ==, 0);
  61   61  
  62      -        fletcher_4_incremental_native(buf, len, &dsp->dsa_zc);
  63      -        dsp->dsa_err = vn_rdwr(UIO_WRITE, dsp->dsa_vp,
  64      -            (caddr_t)buf, len,
  65      -            0, UIO_SYSSPACE, FAPPEND, RLIM64_INFINITY, CRED(), &resid);
  66      -
       62 +        dsp->dsa_err = 0;
       63 +        if (!dsp->sendsize) {
       64 +                fletcher_4_incremental_native(buf, len, &dsp->dsa_zc);
       65 +                dsp->dsa_err = vn_rdwr(UIO_WRITE, dsp->dsa_vp,
       66 +                    (caddr_t)buf, len,
       67 +                    0, UIO_SYSSPACE, FAPPEND, RLIM64_INFINITY,
       68 +                    CRED(), &resid);
       69 +        }
  67   70          mutex_enter(&ds->ds_sendstream_lock);
  68   71          *dsp->dsa_off += len;
  69   72          mutex_exit(&ds->ds_sendstream_lock);
  70   73  
  71   74          return (dsp->dsa_err);
  72   75  }
  73   76  
  74   77  static int
  75   78  dump_free(dmu_sendarg_t *dsp, uint64_t object, uint64_t offset,
  76   79      uint64_t length)
↓ open down ↓ 274 lines elided ↑ open up ↑
 351  354  
 352  355                  if (arc_read_nolock(NULL, spa, bp,
 353  356                      arc_getbuf_func, &abuf, ZIO_PRIORITY_ASYNC_READ,
 354  357                      ZIO_FLAG_CANFAIL, &aflags, zb) != 0)
 355  358                          return (EIO);
 356  359  
 357  360                  err = dump_spill(dsp, zb->zb_object, blksz, abuf->b_data);
 358  361                  (void) arc_buf_remove_ref(abuf, &abuf);
 359  362          } else { /* it's a level-0 block of a regular object */
 360  363                  uint32_t aflags = ARC_WAIT;
 361      -                arc_buf_t *abuf;
      364 +                arc_buf_t *abuf = NULL;
      365 +                void *buf = NULL;
 362  366                  int blksz = BP_GET_LSIZE(bp);
 363  367  
 364      -                if (dsl_read(NULL, spa, bp, pbuf,
 365      -                    arc_getbuf_func, &abuf, ZIO_PRIORITY_ASYNC_READ,
 366      -                    ZIO_FLAG_CANFAIL, &aflags, zb) != 0) {
 367      -                        if (zfs_send_corrupt_data) {
      368 +                if (!dsp->sendsize) {
      369 +                        if (dsl_read(NULL, spa, bp, pbuf,
      370 +                            arc_getbuf_func, &abuf, ZIO_PRIORITY_ASYNC_READ,
      371 +                            ZIO_FLAG_CANFAIL, &aflags, zb) != 0) {
      372 +                                if (zfs_send_corrupt_data) {
 368  373                                  /* Send a block filled with 0x"zfs badd bloc" */
 369      -                                abuf = arc_buf_alloc(spa, blksz, &abuf,
 370      -                                    ARC_BUFC_DATA);
 371      -                                uint64_t *ptr;
 372      -                                for (ptr = abuf->b_data;
 373      -                                    (char *)ptr < (char *)abuf->b_data + blksz;
 374      -                                    ptr++)
 375      -                                        *ptr = 0x2f5baddb10c;
 376      -                        } else {
 377      -                                return (EIO);
      374 +                                        abuf = arc_buf_alloc(spa, blksz, &abuf,
      375 +                                            ARC_BUFC_DATA);
      376 +                                        uint64_t *ptr;
      377 +                                        for (ptr = abuf->b_data;
      378 +                                            (char *)ptr <
      379 +                                            (char *)abuf->b_data + blksz;
      380 +                                            ptr++)
      381 +                                                *ptr = 0x2f5baddb10c;
      382 +                                } else {
      383 +                                        return (EIO);
      384 +                                }
 378  385                          }
      386 +                        buf = abuf->b_data;
 379  387                  }
 380  388  
 381  389                  err = dump_data(dsp, type, zb->zb_object, zb->zb_blkid * blksz,
 382      -                    blksz, bp, abuf->b_data);
 383      -                (void) arc_buf_remove_ref(abuf, &abuf);
      390 +                    blksz, bp, buf);
      391 +                if (!dsp->sendsize) {
      392 +                        (void) arc_buf_remove_ref(abuf, &abuf);
      393 +                }
 384  394          }
 385  395  
 386  396          ASSERT(err == 0 || err == EINTR);
 387  397          return (err);
 388  398  }
 389  399  
 390  400  /*
 391  401   * Return TRUE if 'earlier' is an earlier snapshot in 'later's timeline.
 392  402   * For example, they could both be snapshots of the same filesystem, and
 393  403   * 'earlier' is before 'later'.  Or 'earlier' could be the origin of
↓ open down ↓ 25 lines elided ↑ open up ↑
 419  429          error = dsl_dataset_hold_obj(dp,
 420  430              later->ds_dir->dd_phys->dd_origin_obj, FTAG, &origin);
 421  431          rw_exit(&dp->dp_config_rwlock);
 422  432          if (error != 0)
 423  433                  return (B_FALSE);
 424  434          ret = is_before(origin, earlier);
 425  435          dsl_dataset_rele(origin, FTAG);
 426  436          return (ret);
 427  437  }
 428  438  
      439 +
 429  440  int
 430  441  dmu_send(objset_t *tosnap, objset_t *fromsnap, int outfd, vnode_t *vp,
 431      -    offset_t *off)
      442 +    offset_t *off, boolean_t sendsize)
 432  443  {
 433  444          dsl_dataset_t *ds = tosnap->os_dsl_dataset;
 434  445          dsl_dataset_t *fromds = fromsnap ? fromsnap->os_dsl_dataset : NULL;
 435  446          dmu_replay_record_t *drr;
 436  447          dmu_sendarg_t *dsp;
 437  448          int err;
 438  449          uint64_t fromtxg = 0;
 439  450  
 440  451          /* tosnap must be a snapshot */
 441  452          if (ds->ds_phys->ds_next_snap_obj == 0)
↓ open down ↓ 47 lines elided ↑ open up ↑
 489  500  
 490  501          dsp->dsa_drr = drr;
 491  502          dsp->dsa_vp = vp;
 492  503          dsp->dsa_outfd = outfd;
 493  504          dsp->dsa_proc = curproc;
 494  505          dsp->dsa_os = tosnap;
 495  506          dsp->dsa_off = off;
 496  507          dsp->dsa_toguid = ds->ds_phys->ds_guid;
 497  508          ZIO_SET_CHECKSUM(&dsp->dsa_zc, 0, 0, 0, 0);
 498  509          dsp->dsa_pending_op = PENDING_NONE;
      510 +        dsp->sendsize = sendsize;
 499  511  
 500  512          mutex_enter(&ds->ds_sendstream_lock);
 501  513          list_insert_head(&ds->ds_sendstreams, dsp);
 502  514          mutex_exit(&ds->ds_sendstream_lock);
 503  515  
 504  516          if (dump_bytes(dsp, drr, sizeof (dmu_replay_record_t)) != 0) {
 505  517                  err = dsp->dsa_err;
 506  518                  goto out;
 507  519          }
 508  520  
 509      -        err = traverse_dataset(ds, fromtxg, TRAVERSE_PRE | TRAVERSE_PREFETCH,
 510      -            backup_cb, dsp);
      521 +        if (dsp->sendsize) {
      522 +                err = traverse_dataset(ds, fromtxg,
      523 +                    TRAVERSE_PRE | TRAVERSE_PREFETCH_METADATA,
      524 +                    backup_cb, dsp);
      525 +        } else {
      526 +                err = traverse_dataset(ds,
      527 +                    fromtxg, TRAVERSE_PRE | TRAVERSE_PREFETCH,
      528 +                    backup_cb, dsp);
      529 +        }
 511  530  
 512  531          if (dsp->dsa_pending_op != PENDING_NONE)
 513  532                  if (dump_bytes(dsp, drr, sizeof (dmu_replay_record_t)) != 0)
 514  533                          err = EINTR;
 515  534  
 516  535          if (err) {
 517  536                  if (err == EINTR && dsp->dsa_err)
 518  537                          err = dsp->dsa_err;
 519  538                  goto out;
 520  539          }
↓ open down ↓ 1171 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX