usr/src/uts/common/fs/zfs/dmu_objset.c
author eschrock
Mon, 30 Jan 2006 21:34:28 -0800
changeset 1354 81359ee1ee63
parent 982 9bc5c1db9740
child 1544 938876158511
permissions -rw-r--r--
6362672 import gets confused about overlapping slices 6364582 need to fixup paths if they've changed
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     1
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     2
 * CDDL HEADER START
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     3
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     5
 * Common Development and Distribution License, Version 1.0 only
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     6
 * (the "License").  You may not use this file except in compliance
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     7
 * with the License.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     8
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
     9
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    10
 * or http://www.opensolaris.org/os/licensing.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    11
 * See the License for the specific language governing permissions
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    12
 * and limitations under the License.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    13
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    14
 * When distributing Covered Code, include this CDDL HEADER in each
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    15
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    16
 * If applicable, add the following below this CDDL HEADER, with the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    17
 * fields enclosed by brackets "[]" replaced with your own identifying
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    18
 * information: Portions Copyright [yyyy] [name of copyright owner]
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    19
 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    20
 * CDDL HEADER END
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    21
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    22
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    23
 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    24
 * Use is subject to license terms.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    25
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    26
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    27
#pragma ident	"%Z%%M%	%I%	%E% SMI"
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    28
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    29
#include <sys/zfs_context.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    30
#include <sys/dmu_objset.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    31
#include <sys/dsl_dir.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    32
#include <sys/dsl_dataset.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    33
#include <sys/dsl_prop.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    34
#include <sys/dsl_pool.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    35
#include <sys/dnode.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    36
#include <sys/dbuf.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    37
#include <sys/dmu_tx.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    38
#include <sys/zio_checksum.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    39
#include <sys/zap.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    40
#include <sys/zil.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    41
#include <sys/dmu_impl.h>
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    42
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    43
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    44
spa_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    45
dmu_objset_spa(objset_t *os)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    46
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    47
	return (os->os->os_spa);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    48
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    49
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    50
zilog_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    51
dmu_objset_zil(objset_t *os)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    52
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    53
	return (os->os->os_zil);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    54
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    55
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    56
dsl_pool_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    57
dmu_objset_pool(objset_t *os)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    58
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    59
	dsl_dataset_t *ds;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    60
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    61
	if ((ds = os->os->os_dsl_dataset) != NULL && ds->ds_dir)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    62
		return (ds->ds_dir->dd_pool);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    63
	else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    64
		return (spa_get_dsl(os->os->os_spa));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    65
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    66
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    67
dsl_dataset_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    68
dmu_objset_ds(objset_t *os)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    69
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    70
	return (os->os->os_dsl_dataset);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    71
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    72
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    73
dmu_objset_type_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    74
dmu_objset_type(objset_t *os)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    75
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    76
	return (os->os->os_phys->os_type);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    77
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    78
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    79
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    80
dmu_objset_name(objset_t *os, char *buf)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    81
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    82
	dsl_dataset_name(os->os->os_dsl_dataset, buf);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    83
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    84
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    85
uint64_t
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    86
dmu_objset_id(objset_t *os)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    87
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    88
	dsl_dataset_t *ds = os->os->os_dsl_dataset;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    89
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    90
	return (ds ? ds->ds_object : 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    91
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    92
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    93
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    94
checksum_changed_cb(void *arg, uint64_t newval)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    95
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    96
	objset_impl_t *osi = arg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    97
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    98
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
    99
	 * Inheritance should have been done by now.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   100
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   101
	ASSERT(newval != ZIO_CHECKSUM_INHERIT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   102
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   103
	osi->os_checksum = zio_checksum_select(newval, ZIO_CHECKSUM_ON_VALUE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   104
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   105
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   106
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   107
compression_changed_cb(void *arg, uint64_t newval)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   108
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   109
	objset_impl_t *osi = arg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   110
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   111
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   112
	 * Inheritance and range checking should have been done by now.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   113
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   114
	ASSERT(newval != ZIO_COMPRESS_INHERIT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   115
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   116
	osi->os_compress = zio_compress_select(newval, ZIO_COMPRESS_ON_VALUE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   117
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   118
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   119
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   120
dmu_objset_byteswap(void *buf, size_t size)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   121
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   122
	objset_phys_t *osp = buf;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   123
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   124
	ASSERT(size == sizeof (objset_phys_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   125
	dnode_byteswap(&osp->os_meta_dnode);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   126
	byteswap_uint64_array(&osp->os_zil_header, sizeof (zil_header_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   127
	osp->os_type = BSWAP_64(osp->os_type);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   128
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   129
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   130
objset_impl_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   131
dmu_objset_open_impl(spa_t *spa, dsl_dataset_t *ds, blkptr_t *bp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   132
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   133
	objset_impl_t *winner, *osi;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   134
	int i, err, checksum;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   135
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   136
	osi = kmem_zalloc(sizeof (objset_impl_t), KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   137
	osi->os.os = osi;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   138
	osi->os_dsl_dataset = ds;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   139
	osi->os_spa = spa;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   140
	if (bp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   141
		osi->os_rootbp = *bp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   142
	osi->os_phys = zio_buf_alloc(sizeof (objset_phys_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   143
	if (!BP_IS_HOLE(&osi->os_rootbp)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   144
		dprintf_bp(&osi->os_rootbp, "reading %s", "");
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   145
		(void) arc_read(NULL, spa, &osi->os_rootbp,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   146
		    dmu_ot[DMU_OT_OBJSET].ot_byteswap,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   147
		    arc_bcopy_func, osi->os_phys,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   148
		    ZIO_PRIORITY_SYNC_READ, ZIO_FLAG_MUSTSUCCEED, ARC_WAIT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   149
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   150
		bzero(osi->os_phys, sizeof (objset_phys_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   151
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   152
	osi->os_zil = zil_alloc(&osi->os, &osi->os_phys->os_zil_header);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   153
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   154
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   155
	 * Note: the changed_cb will be called once before the register
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   156
	 * func returns, thus changing the checksum/compression from the
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   157
	 * default (fletcher2/off).
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   158
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   159
	if (ds) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   160
		err = dsl_prop_register(ds, "checksum",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   161
		    checksum_changed_cb, osi);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   162
		ASSERT(err == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   163
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   164
		err = dsl_prop_register(ds, "compression",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   165
		    compression_changed_cb, osi);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   166
		ASSERT(err == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   167
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   168
		/* It's the meta-objset. */
982
9bc5c1db9740 6345547 assertion failed: tempreserve < arc.c/4 from zfs_rename
maybee
parents: 885
diff changeset
   169
		/* XXX - turn off metadata compression temporarily */
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   170
		osi->os_checksum = ZIO_CHECKSUM_FLETCHER_4;
982
9bc5c1db9740 6345547 assertion failed: tempreserve < arc.c/4 from zfs_rename
maybee
parents: 885
diff changeset
   171
		osi->os_compress = ZIO_COMPRESS_OFF;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   172
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   173
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   174
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   175
	 * Metadata always gets compressed and checksummed.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   176
	 * If the data checksum is multi-bit correctable, and it's not
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   177
	 * a ZBT-style checksum, then it's suitable for metadata as well.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   178
	 * Otherwise, the metadata checksum defaults to fletcher4.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   179
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   180
	checksum = osi->os_checksum;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   181
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   182
	if (zio_checksum_table[checksum].ci_correctable &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   183
	    !zio_checksum_table[checksum].ci_zbt)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   184
		osi->os_md_checksum = checksum;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   185
	else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   186
		osi->os_md_checksum = ZIO_CHECKSUM_FLETCHER_4;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   187
982
9bc5c1db9740 6345547 assertion failed: tempreserve < arc.c/4 from zfs_rename
maybee
parents: 885
diff changeset
   188
	/* XXX - turn off metadata compression temporarily */
9bc5c1db9740 6345547 assertion failed: tempreserve < arc.c/4 from zfs_rename
maybee
parents: 885
diff changeset
   189
	osi->os_md_compress = ZIO_COMPRESS_OFF;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   190
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   191
	for (i = 0; i < TXG_SIZE; i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   192
		list_create(&osi->os_dirty_dnodes[i], sizeof (dnode_t),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   193
		    offsetof(dnode_t, dn_dirty_link[i]));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   194
		list_create(&osi->os_free_dnodes[i], sizeof (dnode_t),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   195
		    offsetof(dnode_t, dn_dirty_link[i]));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   196
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   197
	list_create(&osi->os_dnodes, sizeof (dnode_t),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   198
	    offsetof(dnode_t, dn_link));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   199
	list_create(&osi->os_downgraded_dbufs, sizeof (dmu_buf_impl_t),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   200
	    offsetof(dmu_buf_impl_t, db_link));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   201
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   202
	osi->os_meta_dnode = dnode_special_open(osi,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   203
	    &osi->os_phys->os_meta_dnode, DMU_META_DNODE_OBJECT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   204
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   205
	if (ds != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   206
		winner = dsl_dataset_set_user_ptr(ds, osi, dmu_objset_evict);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   207
		if (winner) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   208
			dmu_objset_evict(ds, osi);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   209
			osi = winner;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   210
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   211
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   212
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   213
	return (osi);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   214
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   215
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   216
/* called from zpl */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   217
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   218
dmu_objset_open(const char *name, dmu_objset_type_t type, int mode,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   219
    objset_t **osp)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   220
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   221
	dsl_dataset_t *ds;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   222
	int err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   223
	objset_t *os;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   224
	objset_impl_t *osi;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   225
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   226
	os = kmem_alloc(sizeof (objset_t), KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   227
	err = dsl_dataset_open(name, mode, os, &ds);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   228
	if (err) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   229
		kmem_free(os, sizeof (objset_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   230
		return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   231
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   232
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   233
	osi = dsl_dataset_get_user_ptr(ds);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   234
	if (osi == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   235
		blkptr_t bp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   236
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   237
		dsl_dataset_get_blkptr(ds, &bp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   238
		osi = dmu_objset_open_impl(dsl_dataset_get_spa(ds), ds, &bp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   239
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   240
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   241
	os->os = osi;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   242
	os->os_mode = mode;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   243
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   244
	if (type != DMU_OST_ANY && type != os->os->os_phys->os_type) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   245
		dmu_objset_close(os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   246
		return (EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   247
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   248
	*osp = os;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   249
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   250
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   251
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   252
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   253
dmu_objset_close(objset_t *os)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   254
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   255
	dsl_dataset_close(os->os->os_dsl_dataset, os->os_mode, os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   256
	kmem_free(os, sizeof (objset_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   257
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   258
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   259
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   260
dmu_objset_evict(dsl_dataset_t *ds, void *arg)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   261
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   262
	objset_impl_t *osi = arg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   263
	int err, i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   264
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   265
	for (i = 0; i < TXG_SIZE; i++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   266
		ASSERT(list_head(&osi->os_dirty_dnodes[i]) == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   267
		ASSERT(list_head(&osi->os_free_dnodes[i]) == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   268
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   269
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   270
	if (ds) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   271
		err = dsl_prop_unregister(ds, "checksum",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   272
		    checksum_changed_cb, osi);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   273
		ASSERT(err == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   274
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   275
		err = dsl_prop_unregister(ds, "compression",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   276
		    compression_changed_cb, osi);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   277
		ASSERT(err == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   278
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   279
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   280
	ASSERT3P(list_head(&osi->os_dnodes), ==, osi->os_meta_dnode);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   281
	ASSERT3P(list_tail(&osi->os_dnodes), ==, osi->os_meta_dnode);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   282
	ASSERT3P(list_head(&osi->os_meta_dnode->dn_dbufs), ==, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   283
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   284
	dnode_special_close(osi->os_meta_dnode);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   285
	zil_free(osi->os_zil);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   286
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   287
	zio_buf_free(osi->os_phys, sizeof (objset_phys_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   288
	kmem_free(osi, sizeof (objset_impl_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   289
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   290
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   291
/* called from dsl for meta-objset */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   292
objset_impl_t *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   293
dmu_objset_create_impl(spa_t *spa, dsl_dataset_t *ds, dmu_objset_type_t type,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   294
    dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   295
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   296
	objset_impl_t *osi;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   297
	dnode_t *mdn;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   298
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   299
	ASSERT(dmu_tx_is_syncing(tx));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   300
	osi = dmu_objset_open_impl(spa, ds, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   301
	mdn = osi->os_meta_dnode;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   302
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   303
	dnode_allocate(mdn, DMU_OT_DNODE, 1 << DNODE_BLOCK_SHIFT,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   304
	    DN_MAX_INDBLKSHIFT, DMU_OT_NONE, 0, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   305
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   306
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   307
	 * We don't want to have to increase the meta-dnode's nlevels
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   308
	 * later, because then we could do it in quescing context while
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   309
	 * we are also accessing it in open context.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   310
	 *
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   311
	 * This precaution is not necessary for the MOS (ds == NULL),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   312
	 * because the MOS is only updated in syncing context.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   313
	 * This is most fortunate: the MOS is the only objset that
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   314
	 * needs to be synced multiple times as spa_sync() iterates
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   315
	 * to convergence, so minimizing its dn_nlevels matters.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   316
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   317
	if (ds != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   318
		mdn->dn_next_nlevels[tx->tx_txg & TXG_MASK] =
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   319
		    mdn->dn_nlevels = DN_META_DNODE_LEVELS;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   320
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   321
	ASSERT(type != DMU_OST_NONE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   322
	ASSERT(type != DMU_OST_ANY);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   323
	ASSERT(type < DMU_OST_NUMTYPES);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   324
	osi->os_phys->os_type = type;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   325
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   326
	dsl_dataset_dirty(ds, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   327
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   328
	return (osi);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   329
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   330
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   331
struct oscarg {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   332
	void (*userfunc)(objset_t *os, void *arg, dmu_tx_t *tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   333
	void *userarg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   334
	dsl_dataset_t *clone_parent;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   335
	const char *fullname;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   336
	const char *lastname;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   337
	dmu_objset_type_t type;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   338
};
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   339
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   340
static int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   341
dmu_objset_create_sync(dsl_dir_t *dd, void *arg, dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   342
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   343
	struct oscarg *oa = arg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   344
	dsl_dataset_t *ds;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   345
	int err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   346
	blkptr_t bp;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   347
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   348
	ASSERT(dmu_tx_is_syncing(tx));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   349
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   350
	err = dsl_dataset_create_sync(dd, oa->fullname, oa->lastname,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   351
	    oa->clone_parent, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   352
	dprintf_dd(dd, "fn=%s ln=%s err=%d\n",
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   353
	    oa->fullname, oa->lastname, err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   354
	if (err)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   355
		return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   356
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   357
	err = dsl_dataset_open_spa(dd->dd_pool->dp_spa, oa->fullname,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   358
	    DS_MODE_STANDARD | DS_MODE_READONLY, FTAG, &ds);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   359
	ASSERT3U(err, ==, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   360
	dsl_dataset_get_blkptr(ds, &bp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   361
	if (BP_IS_HOLE(&bp)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   362
		objset_impl_t *osi;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   363
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   364
		/* This is an empty dmu_objset; not a clone. */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   365
		osi = dmu_objset_create_impl(dsl_dataset_get_spa(ds),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   366
		    ds, oa->type, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   367
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   368
		if (oa->userfunc)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   369
			oa->userfunc(&osi->os, oa->userarg, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   370
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   371
	dsl_dataset_close(ds, DS_MODE_STANDARD | DS_MODE_READONLY, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   372
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   373
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   374
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   375
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   376
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   377
dmu_objset_create(const char *name, dmu_objset_type_t type,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   378
    objset_t *clone_parent,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   379
    void (*func)(objset_t *os, void *arg, dmu_tx_t *tx), void *arg)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   380
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   381
	dsl_dir_t *pds;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   382
	const char *tail;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   383
	int err = 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   384
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   385
	pds = dsl_dir_open(name, FTAG, &tail);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   386
	if (pds == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   387
		return (ENOENT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   388
	if (tail == NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   389
		dsl_dir_close(pds, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   390
		return (EEXIST);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   391
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   392
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   393
	dprintf("name=%s\n", name);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   394
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   395
	if (tail[0] == '@') {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   396
		/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   397
		 * If we're creating a snapshot, make sure everything
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   398
		 * they might want is on disk.  XXX Sketchy to know
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   399
		 * about snapshots here, better to put in DSL.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   400
		 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   401
		objset_t *os;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   402
		size_t plen = strchr(name, '@') - name + 1;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   403
		char *pbuf = kmem_alloc(plen, KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   404
		bcopy(name, pbuf, plen - 1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   405
		pbuf[plen - 1] = '\0';
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   406
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   407
		err = dmu_objset_open(pbuf, DMU_OST_ANY, DS_MODE_STANDARD, &os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   408
		if (err == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   409
			err = zil_suspend(dmu_objset_zil(os));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   410
			if (err == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   411
				err = dsl_dir_sync_task(pds,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   412
				    dsl_dataset_snapshot_sync,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   413
				    (void*)(tail+1), 16*1024);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   414
				zil_resume(dmu_objset_zil(os));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   415
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   416
			dmu_objset_close(os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   417
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   418
		kmem_free(pbuf, plen);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   419
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   420
		struct oscarg oa = { 0 };
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   421
		oa.userfunc = func;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   422
		oa.userarg = arg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   423
		oa.fullname = name;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   424
		oa.lastname = tail;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   425
		oa.type = type;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   426
		if (clone_parent != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   427
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   428
			 * You can't clone to a different type.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   429
			 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   430
			if (clone_parent->os->os_phys->os_type != type) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   431
				dsl_dir_close(pds, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   432
				return (EINVAL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   433
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   434
			oa.clone_parent = clone_parent->os->os_dsl_dataset;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   435
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   436
		err = dsl_dir_sync_task(pds, dmu_objset_create_sync, &oa,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   437
		    256*1024);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   438
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   439
	dsl_dir_close(pds, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   440
	return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   441
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   442
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   443
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   444
dmu_objset_destroy(const char *name)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   445
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   446
	objset_t *os;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   447
	int error;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   448
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   449
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   450
	 * If it looks like we'll be able to destroy it, and there's
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   451
	 * an unplayed replay log sitting around, destroy the log.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   452
	 * It would be nicer to do this in dsl_dataset_destroy_sync(),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   453
	 * but the replay log objset is modified in open context.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   454
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   455
	error = dmu_objset_open(name, DMU_OST_ANY, DS_MODE_EXCLUSIVE, &os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   456
	if (error == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   457
		zil_destroy(dmu_objset_zil(os));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   458
		dmu_objset_close(os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   459
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   460
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   461
	/* XXX uncache everything? */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   462
	return (dsl_dataset_destroy(name));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   463
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   464
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   465
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   466
dmu_objset_rollback(const char *name)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   467
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   468
	int err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   469
	objset_t *os;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   470
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   471
	err = dmu_objset_open(name, DMU_OST_ANY, DS_MODE_EXCLUSIVE, &os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   472
	if (err == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   473
		err = zil_suspend(dmu_objset_zil(os));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   474
		if (err == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   475
			zil_resume(dmu_objset_zil(os));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   476
		dmu_objset_close(os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   477
		if (err == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   478
			/* XXX uncache everything? */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   479
			err = dsl_dataset_rollback(name);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   480
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   481
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   482
	return (err);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   483
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   484
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   485
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   486
dmu_objset_sync_dnodes(objset_impl_t *os, list_t *list, dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   487
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   488
	dnode_t *dn = list_head(list);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   489
	int level, err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   490
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   491
	for (level = 0; dn = list_head(list); level++) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   492
		zio_t *zio;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   493
		zio = zio_root(os->os_spa, NULL, NULL, ZIO_FLAG_MUSTSUCCEED);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   494
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   495
		ASSERT3U(level, <=, DN_MAX_LEVELS);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   496
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   497
		while (dn) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   498
			dnode_t *next = list_next(list, dn);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   499
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   500
			list_remove(list, dn);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   501
			if (dnode_sync(dn, level, zio, tx) == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   502
				/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   503
				 * This dnode requires syncing at higher
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   504
				 * levels; put it back onto the list.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   505
				 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   506
				if (next)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   507
					list_insert_before(list, next, dn);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   508
				else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   509
					list_insert_tail(list, dn);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   510
			}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   511
			dn = next;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   512
		}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   513
		err = zio_wait(zio);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   514
		ASSERT(err == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   515
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   516
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   517
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   518
/* ARGSUSED */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   519
static void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   520
killer(zio_t *zio, arc_buf_t *abuf, void *arg)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   521
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   522
	objset_impl_t *os = arg;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   523
	objset_phys_t *osphys = zio->io_data;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   524
	dnode_phys_t *dnp = &osphys->os_meta_dnode;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   525
	int i;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   526
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   527
	ASSERT3U(zio->io_error, ==, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   528
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   529
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   530
	 * Update rootbp fill count.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   531
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   532
	os->os_rootbp.blk_fill = 1;	/* count the meta-dnode */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   533
	for (i = 0; i < dnp->dn_nblkptr; i++)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   534
		os->os_rootbp.blk_fill += dnp->dn_blkptr[i].blk_fill;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   535
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   536
	BP_SET_TYPE(zio->io_bp, DMU_OT_OBJSET);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   537
	BP_SET_LEVEL(zio->io_bp, 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   538
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   539
	if (!DVA_EQUAL(BP_IDENTITY(zio->io_bp),
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   540
	    BP_IDENTITY(&zio->io_bp_orig))) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   541
		dsl_dataset_block_kill(os->os_dsl_dataset, &zio->io_bp_orig,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   542
		    os->os_synctx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   543
		dsl_dataset_block_born(os->os_dsl_dataset, zio->io_bp,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   544
		    os->os_synctx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   545
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   546
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   547
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   548
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   549
/* called from dsl */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   550
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   551
dmu_objset_sync(objset_impl_t *os, dmu_tx_t *tx)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   552
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   553
	extern taskq_t *dbuf_tq;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   554
	int txgoff;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   555
	list_t *dirty_list;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   556
	int err;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   557
	arc_buf_t *abuf =
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   558
	    arc_buf_alloc(os->os_spa, sizeof (objset_phys_t), FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   559
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   560
	ASSERT(dmu_tx_is_syncing(tx));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   561
	ASSERT(os->os_synctx == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   562
	/* XXX the write_done callback should really give us the tx... */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   563
	os->os_synctx = tx;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   564
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   565
	dprintf_ds(os->os_dsl_dataset, "txg=%llu\n", tx->tx_txg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   566
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   567
	txgoff = tx->tx_txg & TXG_MASK;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   568
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   569
	dmu_objset_sync_dnodes(os, &os->os_free_dnodes[txgoff], tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   570
	dmu_objset_sync_dnodes(os, &os->os_dirty_dnodes[txgoff], tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   571
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   572
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   573
	 * Free intent log blocks up to this tx.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   574
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   575
	zil_sync(os->os_zil, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   576
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   577
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   578
	 * Sync meta-dnode
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   579
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   580
	dirty_list = &os->os_dirty_dnodes[txgoff];
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   581
	ASSERT(list_head(dirty_list) == NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   582
	list_insert_tail(dirty_list, os->os_meta_dnode);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   583
	dmu_objset_sync_dnodes(os, dirty_list, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   584
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   585
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   586
	 * Sync the root block.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   587
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   588
	bcopy(os->os_phys, abuf->b_data, sizeof (objset_phys_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   589
	err = arc_write(NULL, os->os_spa, os->os_md_checksum,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   590
	    os->os_md_compress, tx->tx_txg, &os->os_rootbp, abuf, killer, os,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   591
	    ZIO_PRIORITY_ASYNC_WRITE, ZIO_FLAG_MUSTSUCCEED, ARC_WAIT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   592
	ASSERT(err == 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   593
	arc_buf_free(abuf, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   594
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   595
	dsl_dataset_set_blkptr(os->os_dsl_dataset, &os->os_rootbp, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   596
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   597
	ASSERT3P(os->os_synctx, ==, tx);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   598
	taskq_wait(dbuf_tq);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   599
	os->os_synctx = NULL;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   600
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   601
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   602
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   603
dmu_objset_stats(objset_t *os, dmu_objset_stats_t *dds)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   604
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   605
	if (os->os->os_dsl_dataset != NULL) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   606
		dsl_dataset_stats(os->os->os_dsl_dataset, dds);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   607
	} else {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   608
		ASSERT(os->os->os_phys->os_type == DMU_OST_META);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   609
		bzero(dds, sizeof (*dds));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   610
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   611
	dds->dds_type = os->os->os_phys->os_type;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   612
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   613
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   614
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   615
dmu_objset_is_snapshot(objset_t *os)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   616
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   617
	if (os->os->os_dsl_dataset != NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   618
		return (dsl_dataset_is_snapshot(os->os->os_dsl_dataset));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   619
	else
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   620
		return (B_FALSE);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   621
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   622
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   623
int
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   624
dmu_snapshot_list_next(objset_t *os, int namelen, char *name,
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   625
    uint64_t *idp, uint64_t *offp)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   626
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   627
	dsl_dataset_t *ds = os->os->os_dsl_dataset;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   628
	zap_cursor_t cursor;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   629
	zap_attribute_t attr;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   630
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   631
	if (ds->ds_phys->ds_snapnames_zapobj == 0)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   632
		return (ENOENT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   633
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   634
	zap_cursor_init_serialized(&cursor,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   635
	    ds->ds_dir->dd_pool->dp_meta_objset,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   636
	    ds->ds_phys->ds_snapnames_zapobj, *offp);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   637
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   638
	if (zap_cursor_retrieve(&cursor, &attr) != 0) {
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   639
		zap_cursor_fini(&cursor);
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   640
		return (ENOENT);
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   641
	}
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   642
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   643
	if (strlen(attr.za_name) + 1 > namelen) {
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   644
		zap_cursor_fini(&cursor);
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   645
		return (ENAMETOOLONG);
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   646
	}
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   647
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   648
	(void) strcpy(name, attr.za_name);
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   649
	if (idp)
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   650
		*idp = attr.za_first_integer;
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   651
	zap_cursor_advance(&cursor);
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   652
	*offp = zap_cursor_serialize(&cursor);
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   653
	zap_cursor_fini(&cursor);
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   654
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   655
	return (0);
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   656
}
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   657
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   658
int
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   659
dmu_dir_list_next(objset_t *os, int namelen, char *name,
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   660
    uint64_t *idp, uint64_t *offp)
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   661
{
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   662
	dsl_dir_t *dd = os->os->os_dsl_dataset->ds_dir;
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   663
	zap_cursor_t cursor;
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   664
	zap_attribute_t attr;
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   665
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   666
	if (dd->dd_phys->dd_child_dir_zapobj == 0)
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   667
		return (ENOENT);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   668
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   669
	/* there is no next dir on a snapshot! */
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   670
	if (os->os->os_dsl_dataset->ds_object !=
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   671
	    dd->dd_phys->dd_head_dataset_obj)
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   672
		return (ENOENT);
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   673
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   674
	zap_cursor_init_serialized(&cursor,
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   675
	    dd->dd_pool->dp_meta_objset,
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   676
	    dd->dd_phys->dd_child_dir_zapobj, *offp);
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   677
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   678
	if (zap_cursor_retrieve(&cursor, &attr) != 0) {
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   679
		zap_cursor_fini(&cursor);
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   680
		return (ENOENT);
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   681
	}
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   682
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   683
	if (strlen(attr.za_name) + 1 > namelen) {
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   684
		zap_cursor_fini(&cursor);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   685
		return (ENAMETOOLONG);
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   686
	}
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   687
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   688
	(void) strcpy(name, attr.za_name);
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   689
	if (idp)
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   690
		*idp = attr.za_first_integer;
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   691
	zap_cursor_advance(&cursor);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   692
	*offp = zap_cursor_serialize(&cursor);
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   693
	zap_cursor_fini(&cursor);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   694
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   695
	return (0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   696
}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   697
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   698
/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   699
 * Find all objsets under name, and for each, call 'func(child_name, arg)'.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   700
 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   701
void
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   702
dmu_objset_find(char *name, void func(char *, void *), void *arg, int flags)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   703
{
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   704
	dsl_dir_t *dd;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   705
	objset_t *os;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   706
	uint64_t snapobj;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   707
	zap_cursor_t zc;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   708
	zap_attribute_t attr;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   709
	char *child;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   710
	int do_self;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   711
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   712
	dd = dsl_dir_open(name, FTAG, NULL);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   713
	if (dd == NULL)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   714
		return;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   715
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   716
	do_self = (dd->dd_phys->dd_head_dataset_obj != 0);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   717
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   718
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   719
	 * Iterate over all children.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   720
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   721
	if (dd->dd_phys->dd_child_dir_zapobj != 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   722
		for (zap_cursor_init(&zc, dd->dd_pool->dp_meta_objset,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   723
		    dd->dd_phys->dd_child_dir_zapobj);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   724
		    zap_cursor_retrieve(&zc, &attr) == 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   725
		    (void) zap_cursor_advance(&zc)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   726
			ASSERT(attr.za_integer_length == sizeof (uint64_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   727
			ASSERT(attr.za_num_integers == 1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   728
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   729
			/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   730
			 * No separating '/' because parent's name ends in /.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   731
			 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   732
			child = kmem_alloc(MAXPATHLEN, KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   733
			/* XXX could probably just use name here */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   734
			dsl_dir_name(dd, child);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   735
			(void) strcat(child, "/");
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   736
			(void) strcat(child, attr.za_name);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   737
			dmu_objset_find(child, func, arg, flags);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   738
			kmem_free(child, MAXPATHLEN);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   739
		}
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   740
		zap_cursor_fini(&zc);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   741
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   742
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   743
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   744
	 * Iterate over all snapshots.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   745
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   746
	if ((flags & DS_FIND_SNAPSHOTS) &&
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   747
	    dmu_objset_open(name, DMU_OST_ANY,
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   748
	    DS_MODE_STANDARD | DS_MODE_READONLY, &os) == 0) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   749
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   750
		snapobj = os->os->os_dsl_dataset->ds_phys->ds_snapnames_zapobj;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   751
		dmu_objset_close(os);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   752
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   753
		for (zap_cursor_init(&zc, dd->dd_pool->dp_meta_objset, snapobj);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   754
		    zap_cursor_retrieve(&zc, &attr) == 0;
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   755
		    (void) zap_cursor_advance(&zc)) {
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   756
			ASSERT(attr.za_integer_length == sizeof (uint64_t));
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   757
			ASSERT(attr.za_num_integers == 1);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   758
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   759
			child = kmem_alloc(MAXPATHLEN, KM_SLEEP);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   760
			/* XXX could probably just use name here */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   761
			dsl_dir_name(dd, child);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   762
			(void) strcat(child, "@");
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   763
			(void) strcat(child, attr.za_name);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   764
			func(child, arg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   765
			kmem_free(child, MAXPATHLEN);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   766
		}
885
d925b21dba78 6347493 tar of 25K empty directory entries in ZFS takes 30+ seconds ...
ahrens
parents: 789
diff changeset
   767
		zap_cursor_fini(&zc);
789
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   768
	}
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   769
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   770
	dsl_dir_close(dd, FTAG);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   771
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   772
	/*
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   773
	 * Apply to self if appropriate.
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   774
	 */
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   775
	if (do_self)
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   776
		func(name, arg);
b348f31ed315 PSARC 2002/240 ZFS
ahrens
parents:
diff changeset
   777
}