]> granicus.if.org Git - zfs/commitdiff
Merge commit 'refs/top-bases/fix-stack' into fix-stack
authorBrian Behlendorf <behlendorf1@llnl.gov>
Fri, 28 May 2010 20:54:08 +0000 (13:54 -0700)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Fri, 28 May 2010 20:54:08 +0000 (13:54 -0700)
Conflicts:
module/zfs/dmu_objset.c
module/zfs/spa_history.c

1  2 
lib/libzpool/include/sys/zfs_context.h
module/zfs/dbuf.c
module/zfs/dmu_objset.c
module/zfs/dmu_send.c

index 9c66c6cc1b19fdde1de50b735e39ace3df12dab8,9a6d712e53fe9fb11a267a11665c588eec948975..8c16ec1ef7b511b8107606b7f6fdb2deb888ecd1
@@@ -75,13 -75,8 +75,14 @@@ extern "C" 
  #include <sys/u8_textprep.h>
  #include <sys/sysevent/eventdefs.h>
  #include <sys/sysevent/dev.h>
+ #include <sys/sunddi.h>
  
 +/*
 + * Stack
 + */
 +
 +#define  noinline     __attribute__((noinline))
 +
  /*
   * Debugging
   */
Simple merge
index cff74b11b4e05fa232decb15bde99f2e90130e64,690e6ecdee6ab84e5611ee49ca8ca295fb25c97a..32bb614c813605c0d83f940f956344f3d9273c99
@@@ -820,39 -882,35 +882,38 @@@ dmu_objset_snapshot(char *fsname, char 
        spa_t *spa;
        int err;
  
 -      (void) strcpy(sn.failed, fsname);
 +      sn = kmem_alloc(sizeof (struct snaparg), KM_SLEEP);
 +      (void) strcpy(sn->failed, fsname);
  
        err = spa_open(fsname, &spa, FTAG);
 -      if (err)
 +      if (err) {
 +              kmem_free(sn, sizeof (struct snaparg));
                return (err);
 +      }
  
 -      sn.dstg = dsl_sync_task_group_create(spa_get_dsl(spa));
 -      sn.snapname = snapname;
 -      sn.props = props;
 -      sn.recursive = recursive;
 +      sn->dstg = dsl_sync_task_group_create(spa_get_dsl(spa));
 +      sn->snapname = snapname;
 +      sn->props = props;
++      sn->recursive = recursive;
  
        if (recursive) {
-               sn->checkperms = B_TRUE;
                err = dmu_objset_find(fsname,
 -                  dmu_objset_snapshot_one, &sn, DS_FIND_CHILDREN);
 +                  dmu_objset_snapshot_one, sn, DS_FIND_CHILDREN);
        } else {
-               sn->checkperms = B_FALSE;
 -              err = dmu_objset_snapshot_one(fsname, &sn);
 +              err = dmu_objset_snapshot_one(fsname, sn);
        }
  
        if (err == 0)
 -              err = dsl_sync_task_group_wait(sn.dstg);
 +              err = dsl_sync_task_group_wait(sn->dstg);
  
 -      for (dst = list_head(&sn.dstg->dstg_tasks); dst;
 -          dst = list_next(&sn.dstg->dstg_tasks, dst)) {
 +      for (dst = list_head(&sn->dstg->dstg_tasks); dst;
 +          dst = list_next(&sn->dstg->dstg_tasks, dst)) {
                objset_t *os = dst->dst_arg1;
-               dsl_dataset_t *ds = os->os->os_dsl_dataset;
+               dsl_dataset_t *ds = os->os_dsl_dataset;
                if (dst->dst_err)
 -                      dsl_dataset_name(ds, sn.failed);
 +                      dsl_dataset_name(ds, sn->failed);
                zil_resume(dmu_objset_zil(os));
-               dmu_objset_close(os);
+               dmu_objset_rele(os, &sn);
        }
  
        if (err)
index 266f35ad983e6b826b75f7c8c54af259778e6bf4,6b00b73b43be124143e7582da4ba1edcefb04f1b..2f837a1e973ca158be86d1862d8b6bcfce1dcdf0
@@@ -882,8 -1145,116 +1145,116 @@@ restore_write(struct restorearg *ra, ob
        return (0);
  }
  
+ /*
+  * Handle a DRR_WRITE_BYREF record.  This record is used in dedup'ed
+  * streams to refer to a copy of the data that is already on the
+  * system because it came in earlier in the stream.  This function
+  * finds the earlier copy of the data, and uses that copy instead of
+  * data from the stream to fulfill this write.
+  */
+ static int
+ restore_write_byref(struct restorearg *ra, objset_t *os,
+     struct drr_write_byref *drrwbr)
+ {
+       dmu_tx_t *tx;
+       int err;
+       guid_map_entry_t gmesrch;
+       guid_map_entry_t *gmep;
+       avl_index_t     where;
+       objset_t *ref_os = NULL;
+       dmu_buf_t *dbp;
+       if (drrwbr->drr_offset + drrwbr->drr_length < drrwbr->drr_offset)
+               return (EINVAL);
+       /*
+        * If the GUID of the referenced dataset is different from the
+        * GUID of the target dataset, find the referenced dataset.
+        */
+       if (drrwbr->drr_toguid != drrwbr->drr_refguid) {
+               gmesrch.guid = drrwbr->drr_refguid;
+               if ((gmep = avl_find(&ra->guid_to_ds_map, &gmesrch,
+                   &where)) == NULL) {
+                       return (EINVAL);
+               }
+               if (dmu_objset_from_ds(gmep->gme_ds, &ref_os))
+                       return (EINVAL);
+       } else {
+               ref_os = os;
+       }
+       if (err = dmu_buf_hold(ref_os, drrwbr->drr_refobject,
+           drrwbr->drr_refoffset, FTAG, &dbp, DMU_READ_PREFETCH))
+               return (err);
+       tx = dmu_tx_create(os);
+       dmu_tx_hold_write(tx, drrwbr->drr_object,
+           drrwbr->drr_offset, drrwbr->drr_length);
+       err = dmu_tx_assign(tx, TXG_WAIT);
+       if (err) {
+               dmu_tx_abort(tx);
+               return (err);
+       }
+       dmu_write(os, drrwbr->drr_object,
+           drrwbr->drr_offset, drrwbr->drr_length, dbp->db_data, tx);
+       dmu_buf_rele(dbp, FTAG);
+       dmu_tx_commit(tx);
+       return (0);
+ }
+ static int
+ restore_spill(struct restorearg *ra, objset_t *os, struct drr_spill *drrs)
+ {
+       dmu_tx_t *tx;
+       void *data;
+       dmu_buf_t *db, *db_spill;
+       int err;
+       if (drrs->drr_length < SPA_MINBLOCKSIZE ||
+           drrs->drr_length > SPA_MAXBLOCKSIZE)
+               return (EINVAL);
+       data = restore_read(ra, drrs->drr_length);
+       if (data == NULL)
+               return (ra->err);
+       if (dmu_object_info(os, drrs->drr_object, NULL) != 0)
+               return (EINVAL);
+       VERIFY(0 == dmu_bonus_hold(os, drrs->drr_object, FTAG, &db));
+       if ((err = dmu_spill_hold_by_bonus(db, FTAG, &db_spill)) != 0) {
+               dmu_buf_rele(db, FTAG);
+               return (err);
+       }
+       tx = dmu_tx_create(os);
+       dmu_tx_hold_spill(tx, db->db_object);
+       err = dmu_tx_assign(tx, TXG_WAIT);
+       if (err) {
+               dmu_buf_rele(db, FTAG);
+               dmu_buf_rele(db_spill, FTAG);
+               dmu_tx_abort(tx);
+               return (err);
+       }
+       dmu_buf_will_dirty(db_spill, tx);
+       if (db_spill->db_size < drrs->drr_length)
+               VERIFY(0 == dbuf_spill_set_blksz(db_spill,
+                   drrs->drr_length, tx));
+       bcopy(data, db_spill->db_data, drrs->drr_length);
+       dmu_buf_rele(db, FTAG);
+       dmu_buf_rele(db_spill, FTAG);
+       dmu_tx_commit(tx);
+       return (0);
+ }
  /* ARGSUSED */
 -static int
 +noinline static int
  restore_free(struct restorearg *ra, objset_t *os,
      struct drr_free *drrf)
  {