Rebase master to b117
[zfs.git] / module / zfs / dmu_send.c
index 6043df0..9ca3999 100644 (file)
@@ -161,7 +161,9 @@ backup_cb(spa_t *spa, blkptr_t *bp, const zbookmark_t *zb,
        if (issig(JUSTLOOKING) && issig(FORREAL))
                return (EINTR);
 
-       if (bp == NULL && zb->zb_object == 0) {
+       if (zb->zb_object != 0 && DMU_OBJECT_IS_SPECIAL(zb->zb_object)) {
+               return (0);
+       } else if (bp == NULL && zb->zb_object == 0) {
                uint64_t span = BP_SPAN(dnp, zb->zb_level);
                uint64_t dnobj = (zb->zb_blkid * span) >> DNODE_SHIFT;
                err = dump_freeobjects(ba, dnobj, span >> DNODE_SHIFT);
@@ -775,11 +777,6 @@ restore_object(struct restorearg *ra, objset_t *os, struct drr_object *drro)
        dmu_tx_t *tx;
        void *data = NULL;
 
-       err = dmu_object_info(os, drro->drr_object, NULL);
-
-       if (err != 0 && err != ENOENT)
-               return (EINVAL);
-
        if (drro->drr_type == DMU_OT_NONE ||
            drro->drr_type >= DMU_OT_NUMTYPES ||
            drro->drr_bonustype >= DMU_OT_NUMTYPES ||
@@ -792,18 +789,21 @@ restore_object(struct restorearg *ra, objset_t *os, struct drr_object *drro)
                return (EINVAL);
        }
 
+       err = dmu_object_info(os, drro->drr_object, NULL);
+
+       if (err != 0 && err != ENOENT)
+               return (EINVAL);
+
        if (drro->drr_bonuslen) {
                data = restore_read(ra, P2ROUNDUP(drro->drr_bonuslen, 8));
                if (ra->err)
                        return (ra->err);
        }
 
-       tx = dmu_tx_create(os);
-
        if (err == ENOENT) {
                /* currently free, want to be allocated */
+               tx = dmu_tx_create(os);
                dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT);
-               dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, 1);
                err = dmu_tx_assign(tx, TXG_WAIT);
                if (err) {
                        dmu_tx_abort(tx);
@@ -812,28 +812,22 @@ restore_object(struct restorearg *ra, objset_t *os, struct drr_object *drro)
                err = dmu_object_claim(os, drro->drr_object,
                    drro->drr_type, drro->drr_blksz,
                    drro->drr_bonustype, drro->drr_bonuslen, tx);
+               dmu_tx_commit(tx);
        } else {
                /* currently allocated, want to be allocated */
-               dmu_tx_hold_bonus(tx, drro->drr_object);
-               /*
-                * We may change blocksize and delete old content,
-                * so need to hold_write and hold_free.
-                */
-               dmu_tx_hold_write(tx, drro->drr_object, 0, 1);
-               dmu_tx_hold_free(tx, drro->drr_object, 0, DMU_OBJECT_END);
-               err = dmu_tx_assign(tx, TXG_WAIT);
-               if (err) {
-                       dmu_tx_abort(tx);
-                       return (err);
-               }
-
                err = dmu_object_reclaim(os, drro->drr_object,
                    drro->drr_type, drro->drr_blksz,
-                   drro->drr_bonustype, drro->drr_bonuslen, tx);
+                   drro->drr_bonustype, drro->drr_bonuslen);
        }
-       if (err) {
-               dmu_tx_commit(tx);
+       if (err)
                return (EINVAL);
+
+       tx = dmu_tx_create(os);
+       dmu_tx_hold_bonus(tx, drro->drr_object);
+       err = dmu_tx_assign(tx, TXG_WAIT);
+       if (err) {
+               dmu_tx_abort(tx);
+               return (err);
        }
 
        dmu_object_set_checksum(os, drro->drr_object, drro->drr_checksum, tx);