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