usr/src/uts/common/fs/zfs/dmu_send.c
author ahrens
Mon, 07 Jul 2008 13:39:21 -0700
changeset 7046 361307ae060d
parent 6992 20c04e18c58c
child 7837 001de5627df3
permissions -rw-r--r--
6343667 scrub/resilver has to start over when a snapshot is taken 6343693 'zpool status' gives delayed start for 'zpool scrub' 6670746 scrub on degraded pool return the status of 'resilver completed'? 6675685 DTL entries are lost resulting in checksum errors 6706404 get_history_one() can dereference off end of hist_event_table[] 6715414 assertion failed: ds->ds_owner != tag in dsl_dataset_rele() 6716437 ztest gets SEGV in arc_released() 6722838 bfu does not update grub
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
     1
/*
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
     2
 * CDDL HEADER START
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
     3
 *
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
     5
 * Common Development and Distribution License (the "License").
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
     6
 * You may not use this file except in compliance with the License.
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
     7
 *
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    11
 * and limitations under the License.
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    12
 *
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    18
 *
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    19
 * CDDL HEADER END
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    20
 */
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    21
/*
6083
23e77aa611b1 6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents: 5378
diff changeset
    22
 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    23
 * Use is subject to license terms.
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    24
 */
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    25
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    26
#pragma ident	"%Z%%M%	%I%	%E% SMI"
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    27
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    28
#include <sys/dmu.h>
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    29
#include <sys/dmu_impl.h>
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    30
#include <sys/dmu_tx.h>
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    31
#include <sys/dbuf.h>
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    32
#include <sys/dnode.h>
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    33
#include <sys/zfs_context.h>
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    34
#include <sys/dmu_objset.h>
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    35
#include <sys/dmu_traverse.h>
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    36
#include <sys/dsl_dataset.h>
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    37
#include <sys/dsl_dir.h>
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    38
#include <sys/dsl_pool.h>
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    39
#include <sys/dsl_synctask.h>
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    40
#include <sys/zfs_ioctl.h>
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    41
#include <sys/zap.h>
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    42
#include <sys/zio_checksum.h>
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    43
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
    44
static char *dmu_recv_tag = "dmu_recv_tag";
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
    45
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    46
struct backuparg {
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    47
	dmu_replay_record_t *drr;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    48
	vnode_t *vp;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
    49
	offset_t *off;
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    50
	objset_t *os;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    51
	zio_cksum_t zc;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    52
	int err;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    53
};
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    54
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    55
static int
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    56
dump_bytes(struct backuparg *ba, void *buf, int len)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    57
{
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    58
	ssize_t resid; /* have to get resid to get detailed errno */
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    59
	ASSERT3U(len % 8, ==, 0);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    60
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    61
	fletcher_4_incremental_native(buf, len, &ba->zc);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    62
	ba->err = vn_rdwr(UIO_WRITE, ba->vp,
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    63
	    (caddr_t)buf, len,
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    64
	    0, UIO_SYSSPACE, FAPPEND, RLIM64_INFINITY, CRED(), &resid);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
    65
	*ba->off += len;
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    66
	return (ba->err);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    67
}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    68
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    69
static int
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    70
dump_free(struct backuparg *ba, uint64_t object, uint64_t offset,
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    71
    uint64_t length)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    72
{
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    73
	/* write a FREE record */
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    74
	bzero(ba->drr, sizeof (dmu_replay_record_t));
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    75
	ba->drr->drr_type = DRR_FREE;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    76
	ba->drr->drr_u.drr_free.drr_object = object;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    77
	ba->drr->drr_u.drr_free.drr_offset = offset;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    78
	ba->drr->drr_u.drr_free.drr_length = length;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    79
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    80
	if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)))
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    81
		return (EINTR);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    82
	return (0);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    83
}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    84
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    85
static int
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    86
dump_data(struct backuparg *ba, dmu_object_type_t type,
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    87
    uint64_t object, uint64_t offset, int blksz, void *data)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    88
{
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    89
	/* write a DATA record */
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    90
	bzero(ba->drr, sizeof (dmu_replay_record_t));
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    91
	ba->drr->drr_type = DRR_WRITE;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    92
	ba->drr->drr_u.drr_write.drr_object = object;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    93
	ba->drr->drr_u.drr_write.drr_type = type;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    94
	ba->drr->drr_u.drr_write.drr_offset = offset;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    95
	ba->drr->drr_u.drr_write.drr_length = blksz;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    96
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    97
	if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)))
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    98
		return (EINTR);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
    99
	if (dump_bytes(ba, data, blksz))
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   100
		return (EINTR);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   101
	return (0);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   102
}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   103
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   104
static int
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   105
dump_freeobjects(struct backuparg *ba, uint64_t firstobj, uint64_t numobjs)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   106
{
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   107
	/* write a FREEOBJECTS record */
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   108
	bzero(ba->drr, sizeof (dmu_replay_record_t));
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   109
	ba->drr->drr_type = DRR_FREEOBJECTS;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   110
	ba->drr->drr_u.drr_freeobjects.drr_firstobj = firstobj;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   111
	ba->drr->drr_u.drr_freeobjects.drr_numobjs = numobjs;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   112
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   113
	if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)))
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   114
		return (EINTR);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   115
	return (0);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   116
}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   117
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   118
static int
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   119
dump_dnode(struct backuparg *ba, uint64_t object, dnode_phys_t *dnp)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   120
{
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   121
	if (dnp == NULL || dnp->dn_type == DMU_OT_NONE)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   122
		return (dump_freeobjects(ba, object, 1));
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   123
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   124
	/* write an OBJECT record */
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   125
	bzero(ba->drr, sizeof (dmu_replay_record_t));
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   126
	ba->drr->drr_type = DRR_OBJECT;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   127
	ba->drr->drr_u.drr_object.drr_object = object;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   128
	ba->drr->drr_u.drr_object.drr_type = dnp->dn_type;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   129
	ba->drr->drr_u.drr_object.drr_bonustype = dnp->dn_bonustype;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   130
	ba->drr->drr_u.drr_object.drr_blksz =
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   131
	    dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   132
	ba->drr->drr_u.drr_object.drr_bonuslen = dnp->dn_bonuslen;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   133
	ba->drr->drr_u.drr_object.drr_checksum = dnp->dn_checksum;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   134
	ba->drr->drr_u.drr_object.drr_compress = dnp->dn_compress;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   135
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   136
	if (dump_bytes(ba, ba->drr, sizeof (dmu_replay_record_t)))
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   137
		return (EINTR);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   138
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   139
	if (dump_bytes(ba, DN_BONUS(dnp), P2ROUNDUP(dnp->dn_bonuslen, 8)))
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   140
		return (EINTR);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   141
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   142
	/* free anything past the end of the file */
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   143
	if (dump_free(ba, object, (dnp->dn_maxblkid + 1) *
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   144
	    (dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT), -1ULL))
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   145
		return (EINTR);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   146
	if (ba->err)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   147
		return (EINTR);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   148
	return (0);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   149
}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   150
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   151
#define	BP_SPAN(dnp, level) \
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   152
	(((uint64_t)dnp->dn_datablkszsec) << (SPA_MINBLOCKSHIFT + \
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   153
	(level) * (dnp->dn_indblkshift - SPA_BLKPTRSHIFT)))
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   154
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   155
static int
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   156
backup_cb(traverse_blk_cache_t *bc, spa_t *spa, void *arg)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   157
{
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   158
	struct backuparg *ba = arg;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   159
	uint64_t object = bc->bc_bookmark.zb_object;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   160
	int level = bc->bc_bookmark.zb_level;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   161
	uint64_t blkid = bc->bc_bookmark.zb_blkid;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   162
	blkptr_t *bp = bc->bc_blkptr.blk_birth ? &bc->bc_blkptr : NULL;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   163
	dmu_object_type_t type = bp ? BP_GET_TYPE(bp) : DMU_OT_NONE;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   164
	void *data = bc->bc_data;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   165
	int err = 0;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   166
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   167
	if (issig(JUSTLOOKING) && issig(FORREAL))
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   168
		return (EINTR);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   169
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   170
	ASSERT(data || bp == NULL);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   171
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   172
	if (bp == NULL && object == 0) {
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   173
		uint64_t span = BP_SPAN(bc->bc_dnode, level);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   174
		uint64_t dnobj = (blkid * span) >> DNODE_SHIFT;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   175
		err = dump_freeobjects(ba, dnobj, span >> DNODE_SHIFT);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   176
	} else if (bp == NULL) {
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   177
		uint64_t span = BP_SPAN(bc->bc_dnode, level);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   178
		err = dump_free(ba, object, blkid * span, span);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   179
	} else if (data && level == 0 && type == DMU_OT_DNODE) {
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   180
		dnode_phys_t *blk = data;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   181
		int i;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   182
		int blksz = BP_GET_LSIZE(bp);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   183
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   184
		for (i = 0; i < blksz >> DNODE_SHIFT; i++) {
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   185
			uint64_t dnobj =
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   186
			    (blkid << (DNODE_BLOCK_SHIFT - DNODE_SHIFT)) + i;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   187
			err = dump_dnode(ba, dnobj, blk+i);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   188
			if (err)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   189
				break;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   190
		}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   191
	} else if (level == 0 &&
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   192
	    type != DMU_OT_DNODE && type != DMU_OT_OBJSET) {
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   193
		int blksz = BP_GET_LSIZE(bp);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   194
		if (data == NULL) {
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   195
			uint32_t aflags = ARC_WAIT;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   196
			arc_buf_t *abuf;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   197
			zbookmark_t zb;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   198
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   199
			zb.zb_objset = ba->os->os->os_dsl_dataset->ds_object;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   200
			zb.zb_object = object;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   201
			zb.zb_level = level;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   202
			zb.zb_blkid = blkid;
7046
361307ae060d 6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents: 6992
diff changeset
   203
			(void) arc_read_nolock(NULL, spa, bp,
361307ae060d 6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents: 6992
diff changeset
   204
			    arc_getbuf_func, &abuf, ZIO_PRIORITY_ASYNC_READ,
361307ae060d 6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents: 6992
diff changeset
   205
			    ZIO_FLAG_MUSTSUCCEED, &aflags, &zb);
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   206
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   207
			if (abuf) {
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   208
				err = dump_data(ba, type, object, blkid * blksz,
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   209
				    blksz, abuf->b_data);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   210
				(void) arc_buf_remove_ref(abuf, &abuf);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   211
			}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   212
		} else {
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   213
			err = dump_data(ba, type, object, blkid * blksz,
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   214
			    blksz, data);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   215
		}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   216
	}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   217
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   218
	ASSERT(err == 0 || err == EINTR);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   219
	return (err);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   220
}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   221
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   222
int
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   223
dmu_sendbackup(objset_t *tosnap, objset_t *fromsnap, boolean_t fromorigin,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   224
    vnode_t *vp, offset_t *off)
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   225
{
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   226
	dsl_dataset_t *ds = tosnap->os->os_dsl_dataset;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   227
	dsl_dataset_t *fromds = fromsnap ? fromsnap->os->os_dsl_dataset : NULL;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   228
	dmu_replay_record_t *drr;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   229
	struct backuparg ba;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   230
	int err;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   231
	uint64_t fromtxg = 0;
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   232
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   233
	/* tosnap must be a snapshot */
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   234
	if (ds->ds_phys->ds_next_snap_obj == 0)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   235
		return (EINVAL);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   236
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   237
	/* fromsnap must be an earlier snapshot from the same fs as tosnap */
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   238
	if (fromds && (ds->ds_dir != fromds->ds_dir ||
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   239
	    fromds->ds_phys->ds_creation_txg >= ds->ds_phys->ds_creation_txg))
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   240
		return (EXDEV);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   241
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   242
	if (fromorigin) {
7046
361307ae060d 6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents: 6992
diff changeset
   243
		dsl_pool_t *dp = ds->ds_dir->dd_pool;
361307ae060d 6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents: 6992
diff changeset
   244
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   245
		if (fromsnap)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   246
			return (EINVAL);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   247
7046
361307ae060d 6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents: 6992
diff changeset
   248
		if (dsl_dir_is_clone(ds->ds_dir)) {
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   249
			rw_enter(&dp->dp_config_rwlock, RW_READER);
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   250
			err = dsl_dataset_hold_obj(dp,
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   251
			    ds->ds_dir->dd_phys->dd_origin_obj, FTAG, &fromds);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   252
			rw_exit(&dp->dp_config_rwlock);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   253
			if (err)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   254
				return (err);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   255
		} else {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   256
			fromorigin = B_FALSE;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   257
		}
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   258
	}
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   259
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   260
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   261
	drr = kmem_zalloc(sizeof (dmu_replay_record_t), KM_SLEEP);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   262
	drr->drr_type = DRR_BEGIN;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   263
	drr->drr_u.drr_begin.drr_magic = DMU_BACKUP_MAGIC;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   264
	drr->drr_u.drr_begin.drr_version = DMU_BACKUP_STREAM_VERSION;
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   265
	drr->drr_u.drr_begin.drr_creation_time =
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   266
	    ds->ds_phys->ds_creation_time;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   267
	drr->drr_u.drr_begin.drr_type = tosnap->os->os_phys->os_type;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   268
	if (fromorigin)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   269
		drr->drr_u.drr_begin.drr_flags |= DRR_FLAG_CLONE;
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   270
	drr->drr_u.drr_begin.drr_toguid = ds->ds_phys->ds_guid;
6492
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6479
diff changeset
   271
	if (ds->ds_phys->ds_flags & DS_FLAG_CI_DATASET)
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6479
diff changeset
   272
		drr->drr_u.drr_begin.drr_flags |= DRR_FLAG_CI_DATA;
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6479
diff changeset
   273
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   274
	if (fromds)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   275
		drr->drr_u.drr_begin.drr_fromguid = fromds->ds_phys->ds_guid;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   276
	dsl_dataset_name(ds, drr->drr_u.drr_begin.drr_toname);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   277
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   278
	if (fromds)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   279
		fromtxg = fromds->ds_phys->ds_creation_txg;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   280
	if (fromorigin)
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   281
		dsl_dataset_rele(fromds, FTAG);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   282
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   283
	ba.drr = drr;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   284
	ba.vp = vp;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   285
	ba.os = tosnap;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   286
	ba.off = off;
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   287
	ZIO_SET_CHECKSUM(&ba.zc, 0, 0, 0, 0);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   288
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   289
	if (dump_bytes(&ba, drr, sizeof (dmu_replay_record_t))) {
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   290
		kmem_free(drr, sizeof (dmu_replay_record_t));
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   291
		return (ba.err);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   292
	}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   293
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   294
	err = traverse_dsl_dataset(ds, fromtxg,
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   295
	    ADVANCE_PRE | ADVANCE_HOLES | ADVANCE_DATA | ADVANCE_NOLOCK,
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   296
	    backup_cb, &ba);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   297
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   298
	if (err) {
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   299
		if (err == EINTR && ba.err)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   300
			err = ba.err;
3655
bf932d11a0cb 6511976 memory leak in dmu_sendbackup()
gw25295
parents: 3547
diff changeset
   301
		kmem_free(drr, sizeof (dmu_replay_record_t));
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   302
		return (err);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   303
	}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   304
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   305
	bzero(drr, sizeof (dmu_replay_record_t));
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   306
	drr->drr_type = DRR_END;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   307
	drr->drr_u.drr_end.drr_checksum = ba.zc;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   308
3655
bf932d11a0cb 6511976 memory leak in dmu_sendbackup()
gw25295
parents: 3547
diff changeset
   309
	if (dump_bytes(&ba, drr, sizeof (dmu_replay_record_t))) {
bf932d11a0cb 6511976 memory leak in dmu_sendbackup()
gw25295
parents: 3547
diff changeset
   310
		kmem_free(drr, sizeof (dmu_replay_record_t));
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   311
		return (ba.err);
3655
bf932d11a0cb 6511976 memory leak in dmu_sendbackup()
gw25295
parents: 3547
diff changeset
   312
	}
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   313
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   314
	kmem_free(drr, sizeof (dmu_replay_record_t));
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   315
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   316
	return (0);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   317
}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   318
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   319
struct recvbeginsyncarg {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   320
	const char *tofs;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   321
	const char *tosnap;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   322
	dsl_dataset_t *origin;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   323
	uint64_t fromguid;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   324
	dmu_objset_type_t type;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   325
	void *tag;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   326
	boolean_t force;
6492
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6479
diff changeset
   327
	uint64_t dsflags;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   328
	char clonelastname[MAXNAMELEN];
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   329
	dsl_dataset_t *ds; /* the ds to recv into; returned from the syncfunc */
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   330
};
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   331
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   332
static dsl_dataset_t *
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   333
recv_full_sync_impl(dsl_pool_t *dp, uint64_t dsobj, dmu_objset_type_t type,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   334
    cred_t *cr, dmu_tx_t *tx)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   335
{
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   336
	dsl_dataset_t *ds;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   337
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   338
	/* This should always work, since we just created it */
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   339
	/* XXX - create should return an owned ds */
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   340
	VERIFY(0 == dsl_dataset_own_obj(dp, dsobj,
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   341
	    DS_MODE_INCONSISTENT, dmu_recv_tag, &ds));
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   342
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   343
	if (type != DMU_OST_NONE) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   344
		(void) dmu_objset_create_impl(dp->dp_spa,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   345
		    ds, &ds->ds_phys->ds_bp, type, tx);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   346
	}
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   347
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   348
	spa_history_internal_log(LOG_DS_REPLAY_FULL_SYNC,
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   349
	    dp->dp_spa, tx, cr, "dataset = %lld", dsobj);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   350
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   351
	return (ds);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   352
}
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   353
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   354
/* ARGSUSED */
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   355
static int
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   356
recv_full_check(void *arg1, void *arg2, dmu_tx_t *tx)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   357
{
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   358
	dsl_dir_t *dd = arg1;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   359
	struct recvbeginsyncarg *rbsa = arg2;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   360
	objset_t *mos = dd->dd_pool->dp_meta_objset;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   361
	uint64_t val;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   362
	int err;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   363
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   364
	err = zap_lookup(mos, dd->dd_phys->dd_child_dir_zapobj,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   365
	    strrchr(rbsa->tofs, '/') + 1, sizeof (uint64_t), 1, &val);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   366
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   367
	if (err != ENOENT)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   368
		return (err ? err : EEXIST);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   369
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   370
	if (rbsa->origin) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   371
		/* make sure it's a snap in the same pool */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   372
		if (rbsa->origin->ds_dir->dd_pool != dd->dd_pool)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   373
			return (EXDEV);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   374
		if (rbsa->origin->ds_phys->ds_num_children == 0)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   375
			return (EINVAL);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   376
		if (rbsa->origin->ds_phys->ds_guid != rbsa->fromguid)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   377
			return (ENODEV);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   378
	}
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   379
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   380
	return (0);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   381
}
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   382
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   383
static void
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   384
recv_full_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   385
{
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   386
	dsl_dir_t *dd = arg1;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   387
	struct recvbeginsyncarg *rbsa = arg2;
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   388
	uint64_t flags = DS_FLAG_INCONSISTENT | rbsa->dsflags;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   389
	uint64_t dsobj;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   390
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   391
	dsobj = dsl_dataset_create_sync(dd, strrchr(rbsa->tofs, '/') + 1,
6492
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6479
diff changeset
   392
	    rbsa->origin, flags, cr, tx);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   393
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   394
	rbsa->ds = recv_full_sync_impl(dd->dd_pool, dsobj,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   395
	    rbsa->origin ? DMU_OST_NONE : rbsa->type, cr, tx);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   396
}
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   397
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   398
static int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   399
recv_full_existing_check(void *arg1, void *arg2, dmu_tx_t *tx)
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   400
{
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   401
	dsl_dataset_t *ds = arg1;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   402
	struct recvbeginsyncarg *rbsa = arg2;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   403
	int err;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   404
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   405
	/* must be a head ds */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   406
	if (ds->ds_phys->ds_next_snap_obj != 0)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   407
		return (EINVAL);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   408
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   409
	/* must not be a clone ds */
7046
361307ae060d 6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents: 6992
diff changeset
   410
	if (dsl_dir_is_clone(ds->ds_dir))
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   411
		return (EINVAL);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   412
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   413
	err = dsl_dataset_destroy_check(ds, rbsa->tag, tx);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   414
	if (err)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   415
		return (err);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   416
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   417
	if (rbsa->origin) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   418
		/* make sure it's a snap in the same pool */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   419
		if (rbsa->origin->ds_dir->dd_pool != ds->ds_dir->dd_pool)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   420
			return (EXDEV);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   421
		if (rbsa->origin->ds_phys->ds_num_children == 0)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   422
			return (EINVAL);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   423
		if (rbsa->origin->ds_phys->ds_guid != rbsa->fromguid)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   424
			return (ENODEV);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   425
	}
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   426
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   427
	return (0);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   428
}
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   429
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   430
static void
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   431
recv_full_existing_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   432
{
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   433
	dsl_dataset_t *ds = arg1;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   434
	struct recvbeginsyncarg *rbsa = arg2;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   435
	dsl_dir_t *dd = ds->ds_dir;
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   436
	uint64_t flags = DS_FLAG_INCONSISTENT | rbsa->dsflags;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   437
	uint64_t dsobj;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   438
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   439
	/*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   440
	 * NB: caller must provide an extra hold on the dsl_dir_t, so it
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   441
	 * won't go away when dsl_dataset_destroy_sync() closes the
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   442
	 * dataset.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   443
	 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   444
	dsl_dataset_destroy_sync(ds, rbsa->tag, cr, tx);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   445
7046
361307ae060d 6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents: 6992
diff changeset
   446
	dsobj = dsl_dataset_create_sync_dd(dd, rbsa->origin, flags, tx);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   447
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   448
	rbsa->ds = recv_full_sync_impl(dd->dd_pool, dsobj,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   449
	    rbsa->origin ? DMU_OST_NONE : rbsa->type, cr, tx);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   450
}
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   451
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   452
/* ARGSUSED */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   453
static int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   454
recv_incremental_check(void *arg1, void *arg2, dmu_tx_t *tx)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   455
{
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   456
	dsl_dataset_t *ds = arg1;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   457
	struct recvbeginsyncarg *rbsa = arg2;
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   458
	int err;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   459
	uint64_t val;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   460
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   461
	/* must not have any changes since most recent snapshot */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   462
	if (!rbsa->force && dsl_dataset_modified_since_lastsnap(ds))
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   463
		return (ETXTBSY);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   464
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   465
	/* must already be a snapshot of this fs */
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   466
	if (ds->ds_phys->ds_prev_snap_obj == 0)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   467
		return (ENODEV);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   468
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   469
	/* most recent snapshot must match fromguid */
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   470
	if (ds->ds_prev->ds_phys->ds_guid != rbsa->fromguid)
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   471
		return (ENODEV);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   472
6083
23e77aa611b1 6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents: 5378
diff changeset
   473
	/* temporary clone name must not exist */
23e77aa611b1 6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents: 5378
diff changeset
   474
	err = zap_lookup(ds->ds_dir->dd_pool->dp_meta_objset,
23e77aa611b1 6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents: 5378
diff changeset
   475
	    ds->ds_dir->dd_phys->dd_child_dir_zapobj,
23e77aa611b1 6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents: 5378
diff changeset
   476
	    rbsa->clonelastname, 8, 1, &val);
23e77aa611b1 6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents: 5378
diff changeset
   477
	if (err == 0)
23e77aa611b1 6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents: 5378
diff changeset
   478
		return (EEXIST);
23e77aa611b1 6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents: 5378
diff changeset
   479
	if (err != ENOENT)
23e77aa611b1 6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents: 5378
diff changeset
   480
		return (err);
23e77aa611b1 6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents: 5378
diff changeset
   481
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   482
	/* new snapshot name must not exist */
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   483
	err = zap_lookup(ds->ds_dir->dd_pool->dp_meta_objset,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   484
	    ds->ds_phys->ds_snapnames_zapobj, rbsa->tosnap, 8, 1, &val);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   485
	if (err == 0)
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   486
		return (EEXIST);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   487
	if (err != ENOENT)
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   488
		return (err);
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   489
	return (0);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   490
}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   491
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   492
/* ARGSUSED */
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   493
static void
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   494
recv_online_incremental_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx)
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4944
diff changeset
   495
{
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   496
	dsl_dataset_t *ohds = arg1;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   497
	struct recvbeginsyncarg *rbsa = arg2;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   498
	dsl_pool_t *dp = ohds->ds_dir->dd_pool;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   499
	dsl_dataset_t *ods, *cds;
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   500
	uint64_t flags = DS_FLAG_INCONSISTENT | rbsa->dsflags;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   501
	uint64_t dsobj;
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4944
diff changeset
   502
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   503
	/* create the temporary clone */
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   504
	VERIFY(0 == dsl_dataset_hold_obj(dp, ohds->ds_phys->ds_prev_snap_obj,
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   505
	    FTAG, &ods));
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   506
	dsobj = dsl_dataset_create_sync(ohds->ds_dir,
6492
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6479
diff changeset
   507
	    rbsa->clonelastname, ods, flags, cr, tx);
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   508
	dsl_dataset_rele(ods, FTAG);
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4944
diff changeset
   509
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   510
	/* open the temporary clone */
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   511
	VERIFY(0 == dsl_dataset_own_obj(dp, dsobj,
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   512
	    DS_MODE_INCONSISTENT, dmu_recv_tag, &cds));
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   513
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5367
diff changeset
   514
	/* copy the refquota from the target fs to the clone */
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5367
diff changeset
   515
	if (ohds->ds_quota > 0)
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5367
diff changeset
   516
		dsl_dataset_set_quota_sync(cds, &ohds->ds_quota, cr, tx);
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5367
diff changeset
   517
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   518
	rbsa->ds = cds;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   519
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   520
	spa_history_internal_log(LOG_DS_REPLAY_INC_SYNC,
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   521
	    dp->dp_spa, tx, cr, "dataset = %lld", dsobj);
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4944
diff changeset
   522
}
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4944
diff changeset
   523
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4944
diff changeset
   524
/* ARGSUSED */
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   525
static void
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   526
recv_offline_incremental_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx)
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   527
{
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   528
	dsl_dataset_t *ds = arg1;
5378
111aa1baa84a PSARC 2007/555 zfs fs-only quotas and reservations
ck153898
parents: 5367
diff changeset
   529
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   530
	dmu_buf_will_dirty(ds->ds_dbuf, tx);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   531
	ds->ds_phys->ds_flags |= DS_FLAG_INCONSISTENT;
4543
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 3655
diff changeset
   532
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 3655
diff changeset
   533
	spa_history_internal_log(LOG_DS_REPLAY_INC_SYNC,
12bb2876a62e PSARC/2006/465 ZFS Delegated Administration
marks
parents: 3655
diff changeset
   534
	    ds->ds_dir->dd_pool->dp_spa, tx, cr, "dataset = %lld",
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   535
	    ds->ds_object);
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   536
}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   537
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   538
/*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   539
 * NB: callers *MUST* call dmu_recv_stream() if dmu_recv_begin()
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   540
 * succeeds; otherwise we will leak the holds on the datasets.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   541
 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   542
int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   543
dmu_recv_begin(char *tofs, char *tosnap, struct drr_begin *drrb,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   544
    boolean_t force, objset_t *origin, boolean_t online, dmu_recv_cookie_t *drc)
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   545
{
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   546
	int err = 0;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   547
	boolean_t byteswap;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   548
	struct recvbeginsyncarg rbsa;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   549
	uint64_t version;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   550
	int flags;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   551
	dsl_dataset_t *ds;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   552
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   553
	if (drrb->drr_magic == DMU_BACKUP_MAGIC)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   554
		byteswap = FALSE;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   555
	else if (drrb->drr_magic == BSWAP_64(DMU_BACKUP_MAGIC))
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   556
		byteswap = TRUE;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   557
	else
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   558
		return (EINVAL);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   559
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   560
	rbsa.tofs = tofs;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   561
	rbsa.tosnap = tosnap;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   562
	rbsa.origin = origin ? origin->os->os_dsl_dataset : NULL;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   563
	rbsa.fromguid = drrb->drr_fromguid;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   564
	rbsa.type = drrb->drr_type;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   565
	rbsa.tag = FTAG;
6492
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6479
diff changeset
   566
	rbsa.dsflags = 0;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   567
	version = drrb->drr_version;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   568
	flags = drrb->drr_flags;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   569
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   570
	if (byteswap) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   571
		rbsa.type = BSWAP_32(rbsa.type);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   572
		rbsa.fromguid = BSWAP_64(rbsa.fromguid);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   573
		version = BSWAP_64(version);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   574
		flags = BSWAP_32(flags);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   575
	}
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   576
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   577
	if (version != DMU_BACKUP_STREAM_VERSION ||
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   578
	    rbsa.type >= DMU_OST_NUMTYPES ||
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   579
	    ((flags & DRR_FLAG_CLONE) && origin == NULL))
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   580
		return (EINVAL);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   581
6492
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6479
diff changeset
   582
	if (flags & DRR_FLAG_CI_DATA)
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6479
diff changeset
   583
		rbsa.dsflags = DS_FLAG_CI_DATASET;
903545192033 6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents: 6479
diff changeset
   584
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   585
	bzero(drc, sizeof (dmu_recv_cookie_t));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   586
	drc->drc_drrb = drrb;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   587
	drc->drc_tosnap = tosnap;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   588
	drc->drc_force = force;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   589
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   590
	/*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   591
	 * Process the begin in syncing context.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   592
	 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   593
	if (rbsa.fromguid && !(flags & DRR_FLAG_CLONE) && !online) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   594
		/* offline incremental receive */
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   595
		err = dsl_dataset_own(tofs, 0, dmu_recv_tag, &ds);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   596
		if (err)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   597
			return (err);
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   598
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   599
		/*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   600
		 * Only do the rollback if the most recent snapshot
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   601
		 * matches the incremental source
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   602
		 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   603
		if (force) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   604
			if (ds->ds_prev == NULL ||
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   605
			    ds->ds_prev->ds_phys->ds_guid !=
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   606
			    rbsa.fromguid) {
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   607
				dsl_dataset_disown(ds, dmu_recv_tag);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   608
				return (ENODEV);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   609
			}
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   610
			(void) dsl_dataset_rollback(ds, DMU_OST_NONE);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   611
		}
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   612
		rbsa.force = B_FALSE;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   613
		err = dsl_sync_task_do(ds->ds_dir->dd_pool,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   614
		    recv_incremental_check,
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   615
		    recv_offline_incremental_sync, ds, &rbsa, 1);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   616
		if (err) {
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   617
			dsl_dataset_disown(ds, dmu_recv_tag);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   618
			return (err);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   619
		}
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   620
		drc->drc_logical_ds = drc->drc_real_ds = ds;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   621
	} else if (rbsa.fromguid && !(flags & DRR_FLAG_CLONE)) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   622
		/* online incremental receive */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   623
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   624
		/* tmp clone name is: tofs/%tosnap" */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   625
		(void) snprintf(rbsa.clonelastname, sizeof (rbsa.clonelastname),
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   626
		    "%%%s", tosnap);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   627
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   628
		/* open the dataset we are logically receiving into */
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   629
		err = dsl_dataset_hold(tofs, dmu_recv_tag, &ds);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   630
		if (err)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   631
			return (err);
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   632
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   633
		rbsa.force = force;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   634
		err = dsl_sync_task_do(ds->ds_dir->dd_pool,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   635
		    recv_incremental_check,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   636
		    recv_online_incremental_sync, ds, &rbsa, 5);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   637
		if (err) {
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   638
			dsl_dataset_rele(ds, dmu_recv_tag);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   639
			return (err);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   640
		}
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   641
		drc->drc_logical_ds = ds;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   642
		drc->drc_real_ds = rbsa.ds;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   643
	} else {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   644
		/* create new fs -- full backup or clone */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   645
		dsl_dir_t *dd = NULL;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   646
		const char *tail;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   647
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   648
		err = dsl_dir_open(tofs, FTAG, &dd, &tail);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   649
		if (err)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   650
			return (err);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   651
		if (tail == NULL) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   652
			if (!force) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   653
				dsl_dir_close(dd, FTAG);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   654
				return (EEXIST);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   655
			}
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   656
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   657
			rw_enter(&dd->dd_pool->dp_config_rwlock, RW_READER);
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   658
			err = dsl_dataset_own_obj(dd->dd_pool,
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   659
			    dd->dd_phys->dd_head_dataset_obj,
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   660
			    DS_MODE_INCONSISTENT, FTAG, &ds);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   661
			rw_exit(&dd->dd_pool->dp_config_rwlock);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   662
			if (err) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   663
				dsl_dir_close(dd, FTAG);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   664
				return (err);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   665
			}
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   666
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   667
			dsl_dataset_make_exclusive(ds, FTAG);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   668
			err = dsl_sync_task_do(dd->dd_pool,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   669
			    recv_full_existing_check,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   670
			    recv_full_existing_sync, ds, &rbsa, 5);
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   671
			dsl_dataset_disown(ds, FTAG);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   672
		} else {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   673
			err = dsl_sync_task_do(dd->dd_pool, recv_full_check,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   674
			    recv_full_sync, dd, &rbsa, 5);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   675
		}
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   676
		dsl_dir_close(dd, FTAG);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   677
		if (err)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   678
			return (err);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   679
		drc->drc_logical_ds = drc->drc_real_ds = rbsa.ds;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   680
		drc->drc_newfs = B_TRUE;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   681
	}
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   682
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   683
	return (0);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   684
}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   685
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   686
struct restorearg {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   687
	int err;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   688
	int byteswap;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   689
	vnode_t *vp;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   690
	char *buf;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   691
	uint64_t voff;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   692
	int bufsize; /* amount of memory allocated for buf */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   693
	zio_cksum_t cksum;
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4944
diff changeset
   694
};
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4944
diff changeset
   695
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   696
static void *
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   697
restore_read(struct restorearg *ra, int len)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   698
{
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   699
	void *rv;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   700
	int done = 0;
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   701
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   702
	/* some things will require 8-byte alignment, so everything must */
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   703
	ASSERT3U(len % 8, ==, 0);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   704
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   705
	while (done < len) {
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   706
		ssize_t resid;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   707
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   708
		ra->err = vn_rdwr(UIO_READ, ra->vp,
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   709
		    (caddr_t)ra->buf + done, len - done,
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   710
		    ra->voff, UIO_SYSSPACE, FAPPEND,
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   711
		    RLIM64_INFINITY, CRED(), &resid);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   712
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   713
		if (resid == len - done)
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   714
			ra->err = EINVAL;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   715
		ra->voff += len - done - resid;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   716
		done = len - resid;
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   717
		if (ra->err)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   718
			return (NULL);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   719
	}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   720
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   721
	ASSERT3U(done, ==, len);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   722
	rv = ra->buf;
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   723
	if (ra->byteswap)
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   724
		fletcher_4_incremental_byteswap(rv, len, &ra->cksum);
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   725
	else
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   726
		fletcher_4_incremental_native(rv, len, &ra->cksum);
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   727
	return (rv);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   728
}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   729
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   730
static void
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   731
backup_byteswap(dmu_replay_record_t *drr)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   732
{
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   733
#define	DO64(X) (drr->drr_u.X = BSWAP_64(drr->drr_u.X))
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   734
#define	DO32(X) (drr->drr_u.X = BSWAP_32(drr->drr_u.X))
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   735
	drr->drr_type = BSWAP_32(drr->drr_type);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   736
	drr->drr_payloadlen = BSWAP_32(drr->drr_payloadlen);
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   737
	switch (drr->drr_type) {
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   738
	case DRR_BEGIN:
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   739
		DO64(drr_begin.drr_magic);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   740
		DO64(drr_begin.drr_version);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   741
		DO64(drr_begin.drr_creation_time);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   742
		DO32(drr_begin.drr_type);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   743
		DO32(drr_begin.drr_flags);
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   744
		DO64(drr_begin.drr_toguid);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   745
		DO64(drr_begin.drr_fromguid);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   746
		break;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   747
	case DRR_OBJECT:
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   748
		DO64(drr_object.drr_object);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   749
		/* DO64(drr_object.drr_allocation_txg); */
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   750
		DO32(drr_object.drr_type);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   751
		DO32(drr_object.drr_bonustype);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   752
		DO32(drr_object.drr_blksz);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   753
		DO32(drr_object.drr_bonuslen);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   754
		break;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   755
	case DRR_FREEOBJECTS:
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   756
		DO64(drr_freeobjects.drr_firstobj);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   757
		DO64(drr_freeobjects.drr_numobjs);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   758
		break;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   759
	case DRR_WRITE:
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   760
		DO64(drr_write.drr_object);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   761
		DO32(drr_write.drr_type);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   762
		DO64(drr_write.drr_offset);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   763
		DO64(drr_write.drr_length);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   764
		break;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   765
	case DRR_FREE:
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   766
		DO64(drr_free.drr_object);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   767
		DO64(drr_free.drr_offset);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   768
		DO64(drr_free.drr_length);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   769
		break;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   770
	case DRR_END:
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   771
		DO64(drr_end.drr_checksum.zc_word[0]);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   772
		DO64(drr_end.drr_checksum.zc_word[1]);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   773
		DO64(drr_end.drr_checksum.zc_word[2]);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   774
		DO64(drr_end.drr_checksum.zc_word[3]);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   775
		break;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   776
	}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   777
#undef DO64
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   778
#undef DO32
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   779
}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   780
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   781
static int
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   782
restore_object(struct restorearg *ra, objset_t *os, struct drr_object *drro)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   783
{
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   784
	int err;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   785
	dmu_tx_t *tx;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   786
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   787
	err = dmu_object_info(os, drro->drr_object, NULL);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   788
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   789
	if (err != 0 && err != ENOENT)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   790
		return (EINVAL);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   791
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   792
	if (drro->drr_type == DMU_OT_NONE ||
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   793
	    drro->drr_type >= DMU_OT_NUMTYPES ||
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   794
	    drro->drr_bonustype >= DMU_OT_NUMTYPES ||
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   795
	    drro->drr_checksum >= ZIO_CHECKSUM_FUNCTIONS ||
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   796
	    drro->drr_compress >= ZIO_COMPRESS_FUNCTIONS ||
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   797
	    P2PHASE(drro->drr_blksz, SPA_MINBLOCKSIZE) ||
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   798
	    drro->drr_blksz < SPA_MINBLOCKSIZE ||
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   799
	    drro->drr_blksz > SPA_MAXBLOCKSIZE ||
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   800
	    drro->drr_bonuslen > DN_MAX_BONUSLEN) {
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   801
		return (EINVAL);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   802
	}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   803
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   804
	tx = dmu_tx_create(os);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   805
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   806
	if (err == ENOENT) {
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   807
		/* currently free, want to be allocated */
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   808
		dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   809
		dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, 1);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   810
		err = dmu_tx_assign(tx, TXG_WAIT);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   811
		if (err) {
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   812
			dmu_tx_abort(tx);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   813
			return (err);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   814
		}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   815
		err = dmu_object_claim(os, drro->drr_object,
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   816
		    drro->drr_type, drro->drr_blksz,
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   817
		    drro->drr_bonustype, drro->drr_bonuslen, tx);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   818
	} else {
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   819
		/* currently allocated, want to be allocated */
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   820
		dmu_tx_hold_bonus(tx, drro->drr_object);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   821
		/*
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   822
		 * We may change blocksize, so need to
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   823
		 * hold_write
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   824
		 */
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   825
		dmu_tx_hold_write(tx, drro->drr_object, 0, 1);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   826
		err = dmu_tx_assign(tx, TXG_WAIT);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   827
		if (err) {
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   828
			dmu_tx_abort(tx);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   829
			return (err);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   830
		}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   831
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   832
		err = dmu_object_reclaim(os, drro->drr_object,
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   833
		    drro->drr_type, drro->drr_blksz,
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   834
		    drro->drr_bonustype, drro->drr_bonuslen, tx);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   835
	}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   836
	if (err) {
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   837
		dmu_tx_commit(tx);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   838
		return (EINVAL);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   839
	}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   840
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   841
	dmu_object_set_checksum(os, drro->drr_object, drro->drr_checksum, tx);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   842
	dmu_object_set_compress(os, drro->drr_object, drro->drr_compress, tx);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   843
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   844
	if (drro->drr_bonuslen) {
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   845
		dmu_buf_t *db;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   846
		void *data;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   847
		VERIFY(0 == dmu_bonus_hold(os, drro->drr_object, FTAG, &db));
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   848
		dmu_buf_will_dirty(db, tx);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   849
4944
96d96f8de974 6569719 panic dangling dbufs (dn=ffffffff28814d30, dbuf=ffffffff20756008)
maybee
parents: 4543
diff changeset
   850
		ASSERT3U(db->db_size, >=, drro->drr_bonuslen);
96d96f8de974 6569719 panic dangling dbufs (dn=ffffffff28814d30, dbuf=ffffffff20756008)
maybee
parents: 4543
diff changeset
   851
		data = restore_read(ra, P2ROUNDUP(drro->drr_bonuslen, 8));
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   852
		if (data == NULL) {
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   853
			dmu_tx_commit(tx);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   854
			return (ra->err);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   855
		}
4944
96d96f8de974 6569719 panic dangling dbufs (dn=ffffffff28814d30, dbuf=ffffffff20756008)
maybee
parents: 4543
diff changeset
   856
		bcopy(data, db->db_data, drro->drr_bonuslen);
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   857
		if (ra->byteswap) {
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   858
			dmu_ot[drro->drr_bonustype].ot_byteswap(db->db_data,
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   859
			    drro->drr_bonuslen);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   860
		}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   861
		dmu_buf_rele(db, FTAG);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   862
	}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   863
	dmu_tx_commit(tx);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   864
	return (0);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   865
}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   866
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   867
/* ARGSUSED */
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   868
static int
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   869
restore_freeobjects(struct restorearg *ra, objset_t *os,
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   870
    struct drr_freeobjects *drrfo)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   871
{
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   872
	uint64_t obj;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   873
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   874
	if (drrfo->drr_firstobj + drrfo->drr_numobjs < drrfo->drr_firstobj)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   875
		return (EINVAL);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   876
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   877
	for (obj = drrfo->drr_firstobj;
3087
62df4acfd5cb 6468748 assertion failure in dnode_sync
ahrens
parents: 2885
diff changeset
   878
	    obj < drrfo->drr_firstobj + drrfo->drr_numobjs;
62df4acfd5cb 6468748 assertion failure in dnode_sync
ahrens
parents: 2885
diff changeset
   879
	    (void) dmu_object_next(os, &obj, FALSE, 0)) {
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   880
		int err;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   881
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   882
		if (dmu_object_info(os, obj, NULL) != 0)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   883
			continue;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   884
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6689
diff changeset
   885
		err = dmu_free_object(os, obj);
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6689
diff changeset
   886
		if (err)
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   887
			return (err);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   888
	}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   889
	return (0);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   890
}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   891
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   892
static int
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   893
restore_write(struct restorearg *ra, objset_t *os,
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   894
    struct drr_write *drrw)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   895
{
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   896
	dmu_tx_t *tx;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   897
	void *data;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   898
	int err;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   899
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   900
	if (drrw->drr_offset + drrw->drr_length < drrw->drr_offset ||
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   901
	    drrw->drr_type >= DMU_OT_NUMTYPES)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   902
		return (EINVAL);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   903
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   904
	data = restore_read(ra, drrw->drr_length);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   905
	if (data == NULL)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   906
		return (ra->err);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   907
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   908
	if (dmu_object_info(os, drrw->drr_object, NULL) != 0)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   909
		return (EINVAL);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   910
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   911
	tx = dmu_tx_create(os);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   912
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   913
	dmu_tx_hold_write(tx, drrw->drr_object,
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   914
	    drrw->drr_offset, drrw->drr_length);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   915
	err = dmu_tx_assign(tx, TXG_WAIT);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   916
	if (err) {
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   917
		dmu_tx_abort(tx);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   918
		return (err);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   919
	}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   920
	if (ra->byteswap)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   921
		dmu_ot[drrw->drr_type].ot_byteswap(data, drrw->drr_length);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   922
	dmu_write(os, drrw->drr_object,
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   923
	    drrw->drr_offset, drrw->drr_length, data, tx);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   924
	dmu_tx_commit(tx);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   925
	return (0);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   926
}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   927
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   928
/* ARGSUSED */
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   929
static int
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   930
restore_free(struct restorearg *ra, objset_t *os,
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   931
    struct drr_free *drrf)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   932
{
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   933
	int err;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   934
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   935
	if (drrf->drr_length != -1ULL &&
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   936
	    drrf->drr_offset + drrf->drr_length < drrf->drr_offset)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   937
		return (EINVAL);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   938
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   939
	if (dmu_object_info(os, drrf->drr_object, NULL) != 0)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   940
		return (EINVAL);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   941
6992
20c04e18c58c 6573681 deleting a very large file can be slow
maybee
parents: 6689
diff changeset
   942
	err = dmu_free_long_range(os, drrf->drr_object,
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   943
	    drrf->drr_offset, drrf->drr_length);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   944
	return (err);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   945
}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   946
6083
23e77aa611b1 6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents: 5378
diff changeset
   947
void
23e77aa611b1 6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents: 5378
diff changeset
   948
dmu_recv_abort_cleanup(dmu_recv_cookie_t *drc)
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   949
{
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   950
	if (drc->drc_newfs || drc->drc_real_ds != drc->drc_logical_ds) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   951
		/*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   952
		 * online incremental or new fs: destroy the fs (which
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   953
		 * may be a clone) that we created
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   954
		 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   955
		(void) dsl_dataset_destroy(drc->drc_real_ds, dmu_recv_tag);
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   956
		if (drc->drc_real_ds != drc->drc_logical_ds)
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   957
			dsl_dataset_rele(drc->drc_logical_ds, dmu_recv_tag);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   958
	} else {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   959
		/*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   960
		 * offline incremental: rollback to most recent snapshot.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   961
		 */
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   962
		(void) dsl_dataset_rollback(drc->drc_real_ds, DMU_OST_NONE);
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
   963
		dsl_dataset_disown(drc->drc_real_ds, dmu_recv_tag);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   964
	}
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   965
}
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   966
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   967
/*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   968
 * NB: callers *must* call dmu_recv_end() if this succeeds.
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   969
 */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   970
int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   971
dmu_recv_stream(dmu_recv_cookie_t *drc, vnode_t *vp, offset_t *voffp)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   972
{
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   973
	struct restorearg ra = { 0 };
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   974
	dmu_replay_record_t *drr;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   975
	objset_t *os;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   976
	zio_cksum_t pcksum;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   977
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   978
	if (drc->drc_drrb->drr_magic == BSWAP_64(DMU_BACKUP_MAGIC))
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   979
		ra.byteswap = TRUE;
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   980
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   981
	{
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   982
		/* compute checksum of drr_begin record */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   983
		dmu_replay_record_t *drr;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   984
		drr = kmem_zalloc(sizeof (dmu_replay_record_t), KM_SLEEP);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   985
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   986
		drr->drr_type = DRR_BEGIN;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   987
		drr->drr_u.drr_begin = *drc->drc_drrb;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   988
		if (ra.byteswap) {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   989
			fletcher_4_incremental_byteswap(drr,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   990
			    sizeof (dmu_replay_record_t), &ra.cksum);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   991
		} else {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   992
			fletcher_4_incremental_native(drr,
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   993
			    sizeof (dmu_replay_record_t), &ra.cksum);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   994
		}
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   995
		kmem_free(drr, sizeof (dmu_replay_record_t));
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   996
	}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   997
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
   998
	if (ra.byteswap) {
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
   999
		struct drr_begin *drrb = drc->drc_drrb;
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1000
		drrb->drr_magic = BSWAP_64(drrb->drr_magic);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1001
		drrb->drr_version = BSWAP_64(drrb->drr_version);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1002
		drrb->drr_creation_time = BSWAP_64(drrb->drr_creation_time);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1003
		drrb->drr_type = BSWAP_32(drrb->drr_type);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1004
		drrb->drr_toguid = BSWAP_64(drrb->drr_toguid);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1005
		drrb->drr_fromguid = BSWAP_64(drrb->drr_fromguid);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1006
	}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1007
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1008
	ra.vp = vp;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1009
	ra.voff = *voffp;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1010
	ra.bufsize = 1<<20;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1011
	ra.buf = kmem_alloc(ra.bufsize, KM_SLEEP);
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4944
diff changeset
  1012
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1013
	/* these were verified in dmu_recv_begin */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1014
	ASSERT(drc->drc_drrb->drr_version == DMU_BACKUP_STREAM_VERSION);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1015
	ASSERT(drc->drc_drrb->drr_type < DMU_OST_NUMTYPES);
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1016
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1017
	/*
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1018
	 * Open the objset we are modifying.
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1019
	 */
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1020
	VERIFY(dmu_objset_open_ds(drc->drc_real_ds, DMU_OST_ANY, &os) == 0);
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1021
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1022
	ASSERT(drc->drc_real_ds->ds_phys->ds_flags & DS_FLAG_INCONSISTENT);
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1023
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1024
	/*
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1025
	 * Read records and process them.
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1026
	 */
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1027
	pcksum = ra.cksum;
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1028
	while (ra.err == 0 &&
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1029
	    NULL != (drr = restore_read(&ra, sizeof (*drr)))) {
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1030
		if (issig(JUSTLOOKING) && issig(FORREAL)) {
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1031
			ra.err = EINTR;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1032
			goto out;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1033
		}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1034
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1035
		if (ra.byteswap)
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1036
			backup_byteswap(drr);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1037
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1038
		switch (drr->drr_type) {
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1039
		case DRR_OBJECT:
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1040
		{
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1041
			/*
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1042
			 * We need to make a copy of the record header,
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1043
			 * because restore_{object,write} may need to
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1044
			 * restore_read(), which will invalidate drr.
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1045
			 */
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1046
			struct drr_object drro = drr->drr_u.drr_object;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1047
			ra.err = restore_object(&ra, os, &drro);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1048
			break;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1049
		}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1050
		case DRR_FREEOBJECTS:
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1051
		{
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1052
			struct drr_freeobjects drrfo =
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1053
			    drr->drr_u.drr_freeobjects;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1054
			ra.err = restore_freeobjects(&ra, os, &drrfo);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1055
			break;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1056
		}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1057
		case DRR_WRITE:
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1058
		{
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1059
			struct drr_write drrw = drr->drr_u.drr_write;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1060
			ra.err = restore_write(&ra, os, &drrw);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1061
			break;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1062
		}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1063
		case DRR_FREE:
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1064
		{
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1065
			struct drr_free drrf = drr->drr_u.drr_free;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1066
			ra.err = restore_free(&ra, os, &drrf);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1067
			break;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1068
		}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1069
		case DRR_END:
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1070
		{
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1071
			struct drr_end drre = drr->drr_u.drr_end;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1072
			/*
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1073
			 * We compare against the *previous* checksum
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1074
			 * value, because the stored checksum is of
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1075
			 * everything before the DRR_END record.
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1076
			 */
6479
2fc187a28649 6655375 panic loop: assertion failed: crc != 0
ahrens
parents: 6083
diff changeset
  1077
			if (!ZIO_CHECKSUM_EQUAL(drre.drr_checksum, pcksum))
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1078
				ra.err = ECKSUM;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1079
			goto out;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1080
		}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1081
		default:
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1082
			ra.err = EINVAL;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1083
			goto out;
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1084
		}
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1085
		pcksum = ra.cksum;
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1086
	}
6479
2fc187a28649 6655375 panic loop: assertion failed: crc != 0
ahrens
parents: 6083
diff changeset
  1087
	ASSERT(ra.err != 0);
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1088
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1089
out:
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1090
	dmu_objset_close(os);
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1091
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1092
	if (ra.err != 0) {
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1093
		/*
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1094
		 * rollback or destroy what we created, so we don't
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1095
		 * leave it in the restoring state.
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1096
		 */
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1097
		txg_wait_synced(drc->drc_real_ds->ds_dir->dd_pool, 0);
6083
23e77aa611b1 6655963 Panic: 0 == zap_add(mos, pds->dd_phys->dd_child_dir_zapobj, name, sizeof (uint64_t), 1, &ddobj, tx)
ek110237
parents: 5378
diff changeset
  1098
		dmu_recv_abort_cleanup(drc);
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1099
	}
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1100
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1101
	kmem_free(ra.buf, ra.bufsize);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1102
	*voffp = ra.voff;
2743
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1103
	return (ra.err);
632c24f376ff 6461438 zfs send/recv code should live in its own file
ahrens
parents:
diff changeset
  1104
}
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4944
diff changeset
  1105
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1106
struct recvendsyncarg {
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1107
	char *tosnap;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1108
	uint64_t creation_time;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1109
	uint64_t toguid;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1110
};
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1111
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1112
static int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1113
recv_end_check(void *arg1, void *arg2, dmu_tx_t *tx)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1114
{
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1115
	dsl_dataset_t *ds = arg1;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1116
	struct recvendsyncarg *resa = arg2;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1117
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1118
	return (dsl_dataset_snapshot_check(ds, resa->tosnap, tx));
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1119
}
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1120
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1121
static void
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1122
recv_end_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx)
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4944
diff changeset
  1123
{
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1124
	dsl_dataset_t *ds = arg1;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1125
	struct recvendsyncarg *resa = arg2;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1126
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1127
	dsl_dataset_snapshot_sync(ds, resa->tosnap, cr, tx);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1128
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1129
	/* set snapshot's creation time and guid */
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1130
	dmu_buf_will_dirty(ds->ds_prev->ds_dbuf, tx);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1131
	ds->ds_prev->ds_phys->ds_creation_time = resa->creation_time;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1132
	ds->ds_prev->ds_phys->ds_guid = resa->toguid;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1133
	ds->ds_prev->ds_phys->ds_flags &= ~DS_FLAG_INCONSISTENT;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1134
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1135
	dmu_buf_will_dirty(ds->ds_dbuf, tx);
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1136
	ds->ds_phys->ds_flags &= ~DS_FLAG_INCONSISTENT;
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1137
}
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1138
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1139
int
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1140
dmu_recv_end(dmu_recv_cookie_t *drc)
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1141
{
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1142
	struct recvendsyncarg resa;
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1143
	dsl_dataset_t *ds = drc->drc_logical_ds;
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1144
	int err;
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1145
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1146
	/*
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1147
	 * XXX hack; seems the ds is still dirty and
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1148
	 * dsl_pool_zil_clean() expects it to have a ds_user_ptr
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1149
	 * (and zil), but clone_swap() can close it.
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1150
	 */
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1151
	txg_wait_synced(ds->ds_dir->dd_pool, 0);
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4944
diff changeset
  1152
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1153
	if (ds != drc->drc_real_ds) {
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1154
		/* we are doing an online recv */
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1155
		if (dsl_dataset_tryown(ds, FALSE, dmu_recv_tag)) {
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1156
			err = dsl_dataset_clone_swap(drc->drc_real_ds, ds,
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1157
			    drc->drc_force);
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1158
			if (err)
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1159
				dsl_dataset_disown(ds, dmu_recv_tag);
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1160
		} else {
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1161
			err = EBUSY;
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1162
			dsl_dataset_rele(ds, dmu_recv_tag);
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1163
		}
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1164
		/* dsl_dataset_destroy() will disown the ds */
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1165
		(void) dsl_dataset_destroy(drc->drc_real_ds, dmu_recv_tag);
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1166
		if (err)
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1167
			return (err);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1168
	}
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1169
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1170
	resa.creation_time = drc->drc_drrb->drr_creation_time;
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1171
	resa.toguid = drc->drc_drrb->drr_toguid;
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1172
	resa.tosnap = drc->drc_tosnap;
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1173
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1174
	err = dsl_sync_task_do(ds->ds_dir->dd_pool,
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1175
	    recv_end_check, recv_end_sync, ds, &resa, 3);
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1176
	if (err) {
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1177
		if (drc->drc_newfs) {
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1178
			ASSERT(ds == drc->drc_real_ds);
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1179
			(void) dsl_dataset_destroy(ds, dmu_recv_tag);
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1180
			return (err);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1181
		} else {
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1182
			(void) dsl_dataset_rollback(ds, DMU_OST_NONE);
5367
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1183
		}
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1184
	}
c40abbe796be PSARC/2007/574 zfs send -R
ahrens
parents: 5326
diff changeset
  1185
6689
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1186
	/* release the hold from dmu_recv_begin */
47572a2f5e73 6610506 Eliminate or improve retry logic from callers of dmu_objset_open()
maybee
parents: 6492
diff changeset
  1187
	dsl_dataset_disown(ds, dmu_recv_tag);
5326
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4944
diff changeset
  1188
	return (err);
6752aa2bd5bc 6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents: 4944
diff changeset
  1189
}