annotate usr/src/uts/common/fs/zfs/dmu_objset.c @ 982:9bc5c1db9740

6345547 assertion failed: tempreserve < arc.c/4 from zfs_rename 6354299 Disable metadata compression, at least temporarily
author maybee
date Wed, 23 Nov 2005 07:16:54 -0800
parents d925b21dba78
children 938876158511
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
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 }