author | maybee |
Fri, 05 May 2006 10:59:51 -0700 | |
changeset 1936 | b6ded90e4d4b |
parent 1878 | c22df0f5603f |
child 2113 | 0510bb40c993 |
permissions | -rw-r--r-- |
789 | 1 |
/* |
2 |
* CDDL HEADER START |
|
3 |
* |
|
4 |
* The contents of this file are subject to the terms of the |
|
1544 | 5 |
* Common Development and Distribution License (the "License"). |
6 |
* You may not use this file except in compliance with the License. |
|
789 | 7 |
* |
8 |
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
|
9 |
* or http://www.opensolaris.org/os/licensing. |
|
10 |
* See the License for the specific language governing permissions |
|
11 |
* and limitations under the License. |
|
12 |
* |
|
13 |
* When distributing Covered Code, include this CDDL HEADER in each |
|
14 |
* file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
|
15 |
* If applicable, add the following below this CDDL HEADER, with the |
|
16 |
* fields enclosed by brackets "[]" replaced with your own identifying |
|
17 |
* information: Portions Copyright [yyyy] [name of copyright owner] |
|
18 |
* |
|
19 |
* CDDL HEADER END |
|
20 |
*/ |
|
21 |
/* |
|
1394
e8d500b79ced
6381600 tc_open.021 in mstc testsuite is returning -1 when run on a zfs
marks
parents:
869
diff
changeset
|
22 |
* Copyright 2006 Sun Microsystems, Inc. All rights reserved. |
789 | 23 |
* Use is subject to license terms. |
24 |
*/ |
|
25 |
||
26 |
#pragma ident "%Z%%M% %I% %E% SMI" |
|
27 |
||
28 |
#include <sys/types.h> |
|
29 |
#include <sys/param.h> |
|
30 |
#include <sys/time.h> |
|
31 |
#include <sys/systm.h> |
|
32 |
#include <sys/sysmacros.h> |
|
33 |
#include <sys/resource.h> |
|
34 |
#include <sys/mntent.h> |
|
1816
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
35 |
#include <sys/mkdev.h> |
789 | 36 |
#include <sys/vfs.h> |
37 |
#include <sys/vnode.h> |
|
38 |
#include <sys/file.h> |
|
39 |
#include <sys/kmem.h> |
|
40 |
#include <sys/cmn_err.h> |
|
41 |
#include <sys/errno.h> |
|
42 |
#include <sys/unistd.h> |
|
43 |
#include <sys/stat.h> |
|
44 |
#include <sys/mode.h> |
|
45 |
#include <sys/atomic.h> |
|
46 |
#include <vm/pvn.h> |
|
47 |
#include "fs/fs_subr.h" |
|
48 |
#include <sys/zfs_dir.h> |
|
49 |
#include <sys/zfs_acl.h> |
|
50 |
#include <sys/zfs_ioctl.h> |
|
51 |
#include <sys/zfs_znode.h> |
|
1669 | 52 |
#include <sys/zfs_rlock.h> |
789 | 53 |
#include <sys/zap.h> |
54 |
#include <sys/dmu.h> |
|
55 |
#include <sys/fs/zfs.h> |
|
56 |
||
57 |
struct kmem_cache *znode_cache = NULL; |
|
58 |
||
59 |
/*ARGSUSED*/ |
|
60 |
static void |
|
61 |
znode_pageout_func(dmu_buf_t *dbuf, void *user_ptr) |
|
62 |
{ |
|
63 |
znode_t *zp = user_ptr; |
|
64 |
vnode_t *vp = ZTOV(zp); |
|
65 |
||
1544 | 66 |
mutex_enter(&zp->z_lock); |
789 | 67 |
if (vp->v_count == 0) { |
1544 | 68 |
mutex_exit(&zp->z_lock); |
789 | 69 |
vn_invalid(vp); |
70 |
zfs_znode_free(zp); |
|
1544 | 71 |
} else { |
72 |
/* signal force unmount that this znode can be freed */ |
|
73 |
zp->z_dbuf = NULL; |
|
74 |
mutex_exit(&zp->z_lock); |
|
789 | 75 |
} |
76 |
} |
|
77 |
||
78 |
/*ARGSUSED*/ |
|
79 |
static int |
|
80 |
zfs_znode_cache_constructor(void *buf, void *cdrarg, int kmflags) |
|
81 |
{ |
|
82 |
znode_t *zp = buf; |
|
83 |
||
84 |
zp->z_vnode = vn_alloc(KM_SLEEP); |
|
85 |
zp->z_vnode->v_data = (caddr_t)zp; |
|
86 |
mutex_init(&zp->z_lock, NULL, MUTEX_DEFAULT, NULL); |
|
87 |
rw_init(&zp->z_map_lock, NULL, RW_DEFAULT, NULL); |
|
1669 | 88 |
rw_init(&zp->z_parent_lock, NULL, RW_DEFAULT, NULL); |
789 | 89 |
mutex_init(&zp->z_acl_lock, NULL, MUTEX_DEFAULT, NULL); |
1669 | 90 |
|
91 |
mutex_init(&zp->z_range_lock, NULL, MUTEX_DEFAULT, NULL); |
|
92 |
avl_create(&zp->z_range_avl, zfs_range_compare, |
|
93 |
sizeof (rl_t), offsetof(rl_t, r_node)); |
|
94 |
||
789 | 95 |
zp->z_dbuf_held = 0; |
96 |
zp->z_dirlocks = 0; |
|
97 |
return (0); |
|
98 |
} |
|
99 |
||
100 |
/*ARGSUSED*/ |
|
101 |
static void |
|
102 |
zfs_znode_cache_destructor(void *buf, void *cdarg) |
|
103 |
{ |
|
104 |
znode_t *zp = buf; |
|
105 |
||
106 |
ASSERT(zp->z_dirlocks == 0); |
|
107 |
mutex_destroy(&zp->z_lock); |
|
108 |
rw_destroy(&zp->z_map_lock); |
|
1669 | 109 |
rw_destroy(&zp->z_parent_lock); |
789 | 110 |
mutex_destroy(&zp->z_acl_lock); |
1669 | 111 |
avl_destroy(&zp->z_range_avl); |
789 | 112 |
|
113 |
ASSERT(zp->z_dbuf_held == 0); |
|
114 |
ASSERT(ZTOV(zp)->v_count == 0); |
|
115 |
vn_free(ZTOV(zp)); |
|
116 |
} |
|
117 |
||
118 |
void |
|
119 |
zfs_znode_init(void) |
|
120 |
{ |
|
121 |
/* |
|
122 |
* Initialize zcache |
|
123 |
*/ |
|
124 |
ASSERT(znode_cache == NULL); |
|
125 |
znode_cache = kmem_cache_create("zfs_znode_cache", |
|
126 |
sizeof (znode_t), 0, zfs_znode_cache_constructor, |
|
127 |
zfs_znode_cache_destructor, NULL, NULL, NULL, 0); |
|
128 |
} |
|
129 |
||
130 |
void |
|
131 |
zfs_znode_fini(void) |
|
132 |
{ |
|
133 |
/* |
|
134 |
* Cleanup vfs & vnode ops |
|
135 |
*/ |
|
136 |
zfs_remove_op_tables(); |
|
137 |
||
138 |
/* |
|
139 |
* Cleanup zcache |
|
140 |
*/ |
|
141 |
if (znode_cache) |
|
142 |
kmem_cache_destroy(znode_cache); |
|
143 |
znode_cache = NULL; |
|
144 |
} |
|
145 |
||
146 |
struct vnodeops *zfs_dvnodeops; |
|
147 |
struct vnodeops *zfs_fvnodeops; |
|
148 |
struct vnodeops *zfs_symvnodeops; |
|
149 |
struct vnodeops *zfs_xdvnodeops; |
|
150 |
struct vnodeops *zfs_evnodeops; |
|
151 |
||
152 |
void |
|
153 |
zfs_remove_op_tables() |
|
154 |
{ |
|
155 |
/* |
|
156 |
* Remove vfs ops |
|
157 |
*/ |
|
158 |
ASSERT(zfsfstype); |
|
159 |
(void) vfs_freevfsops_by_type(zfsfstype); |
|
160 |
zfsfstype = 0; |
|
161 |
||
162 |
/* |
|
163 |
* Remove vnode ops |
|
164 |
*/ |
|
165 |
if (zfs_dvnodeops) |
|
166 |
vn_freevnodeops(zfs_dvnodeops); |
|
167 |
if (zfs_fvnodeops) |
|
168 |
vn_freevnodeops(zfs_fvnodeops); |
|
169 |
if (zfs_symvnodeops) |
|
170 |
vn_freevnodeops(zfs_symvnodeops); |
|
171 |
if (zfs_xdvnodeops) |
|
172 |
vn_freevnodeops(zfs_xdvnodeops); |
|
173 |
if (zfs_evnodeops) |
|
174 |
vn_freevnodeops(zfs_evnodeops); |
|
175 |
||
176 |
zfs_dvnodeops = NULL; |
|
177 |
zfs_fvnodeops = NULL; |
|
178 |
zfs_symvnodeops = NULL; |
|
179 |
zfs_xdvnodeops = NULL; |
|
180 |
zfs_evnodeops = NULL; |
|
181 |
} |
|
182 |
||
183 |
extern const fs_operation_def_t zfs_dvnodeops_template[]; |
|
184 |
extern const fs_operation_def_t zfs_fvnodeops_template[]; |
|
185 |
extern const fs_operation_def_t zfs_xdvnodeops_template[]; |
|
186 |
extern const fs_operation_def_t zfs_symvnodeops_template[]; |
|
187 |
extern const fs_operation_def_t zfs_evnodeops_template[]; |
|
188 |
||
189 |
int |
|
190 |
zfs_create_op_tables() |
|
191 |
{ |
|
192 |
int error; |
|
193 |
||
194 |
/* |
|
195 |
* zfs_dvnodeops can be set if mod_remove() calls mod_installfs() |
|
196 |
* due to a failure to remove the the 2nd modlinkage (zfs_modldrv). |
|
197 |
* In this case we just return as the ops vectors are already set up. |
|
198 |
*/ |
|
199 |
if (zfs_dvnodeops) |
|
200 |
return (0); |
|
201 |
||
202 |
error = vn_make_ops(MNTTYPE_ZFS, zfs_dvnodeops_template, |
|
203 |
&zfs_dvnodeops); |
|
204 |
if (error) |
|
205 |
return (error); |
|
206 |
||
207 |
error = vn_make_ops(MNTTYPE_ZFS, zfs_fvnodeops_template, |
|
208 |
&zfs_fvnodeops); |
|
209 |
if (error) |
|
210 |
return (error); |
|
211 |
||
212 |
error = vn_make_ops(MNTTYPE_ZFS, zfs_symvnodeops_template, |
|
213 |
&zfs_symvnodeops); |
|
214 |
if (error) |
|
215 |
return (error); |
|
216 |
||
217 |
error = vn_make_ops(MNTTYPE_ZFS, zfs_xdvnodeops_template, |
|
218 |
&zfs_xdvnodeops); |
|
219 |
if (error) |
|
220 |
return (error); |
|
221 |
||
222 |
error = vn_make_ops(MNTTYPE_ZFS, zfs_evnodeops_template, |
|
223 |
&zfs_evnodeops); |
|
224 |
||
225 |
return (error); |
|
226 |
} |
|
227 |
||
228 |
/* |
|
229 |
* zfs_init_fs - Initialize the zfsvfs struct and the file system |
|
230 |
* incore "master" object. Verify version compatibility. |
|
231 |
*/ |
|
232 |
int |
|
233 |
zfs_init_fs(zfsvfs_t *zfsvfs, znode_t **zpp, cred_t *cr) |
|
234 |
{ |
|
235 |
extern int zfsfstype; |
|
236 |
||
237 |
objset_t *os = zfsvfs->z_os; |
|
238 |
uint64_t zoid; |
|
1760 | 239 |
uint64_t version = ZPL_VERSION; |
789 | 240 |
int i, error; |
241 |
dmu_object_info_t doi; |
|
242 |
dmu_objset_stats_t *stats; |
|
243 |
||
244 |
*zpp = NULL; |
|
245 |
||
246 |
/* |
|
247 |
* XXX - hack to auto-create the pool root filesystem at |
|
248 |
* the first attempted mount. |
|
249 |
*/ |
|
250 |
if (dmu_object_info(os, MASTER_NODE_OBJ, &doi) == ENOENT) { |
|
251 |
dmu_tx_t *tx = dmu_tx_create(os); |
|
252 |
||
1544 | 253 |
dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, TRUE, NULL); /* master */ |
254 |
dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, TRUE, NULL); /* del queue */ |
|
789 | 255 |
dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT); /* root node */ |
256 |
error = dmu_tx_assign(tx, TXG_WAIT); |
|
257 |
ASSERT3U(error, ==, 0); |
|
258 |
zfs_create_fs(os, cr, tx); |
|
259 |
dmu_tx_commit(tx); |
|
260 |
} |
|
261 |
||
1760 | 262 |
error = zap_lookup(os, MASTER_NODE_OBJ, ZPL_VERSION_OBJ, 8, 1, |
1544 | 263 |
&version); |
264 |
if (error) { |
|
265 |
return (error); |
|
1760 | 266 |
} else if (version != ZPL_VERSION) { |
789 | 267 |
(void) printf("Mismatched versions: File system " |
268 |
"is version %lld on-disk format, which is " |
|
269 |
"incompatible with this software version %lld!", |
|
1760 | 270 |
(u_longlong_t)version, ZPL_VERSION); |
789 | 271 |
return (ENOTSUP); |
272 |
} |
|
273 |
||
274 |
/* |
|
275 |
* The fsid is 64 bits, composed of an 8-bit fs type, which |
|
276 |
* separates our fsid from any other filesystem types, and a |
|
277 |
* 56-bit objset unique ID. The objset unique ID is unique to |
|
278 |
* all objsets open on this system, provided by unique_create(). |
|
279 |
* The 8-bit fs type must be put in the low bits of fsid[1] |
|
280 |
* because that's where other Solaris filesystems put it. |
|
281 |
*/ |
|
282 |
stats = kmem_alloc(sizeof (dmu_objset_stats_t), KM_SLEEP); |
|
283 |
dmu_objset_stats(os, stats); |
|
284 |
ASSERT((stats->dds_fsid_guid & ~((1ULL<<56)-1)) == 0); |
|
285 |
zfsvfs->z_vfs->vfs_fsid.val[0] = stats->dds_fsid_guid; |
|
286 |
zfsvfs->z_vfs->vfs_fsid.val[1] = ((stats->dds_fsid_guid>>32) << 8) | |
|
287 |
zfsfstype & 0xFF; |
|
288 |
kmem_free(stats, sizeof (dmu_objset_stats_t)); |
|
289 |
stats = NULL; |
|
290 |
||
1544 | 291 |
error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_ROOT_OBJ, 8, 1, &zoid); |
292 |
if (error) |
|
293 |
return (error); |
|
789 | 294 |
ASSERT(zoid != 0); |
295 |
zfsvfs->z_root = zoid; |
|
296 |
||
297 |
/* |
|
298 |
* Create the per mount vop tables. |
|
299 |
*/ |
|
300 |
||
301 |
/* |
|
302 |
* Initialize zget mutex's |
|
303 |
*/ |
|
304 |
for (i = 0; i != ZFS_OBJ_MTX_SZ; i++) |
|
305 |
mutex_init(&zfsvfs->z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL); |
|
306 |
||
307 |
error = zfs_zget(zfsvfs, zoid, zpp); |
|
308 |
if (error) |
|
309 |
return (error); |
|
310 |
ASSERT3U((*zpp)->z_id, ==, zoid); |
|
311 |
||
1544 | 312 |
error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_DELETE_QUEUE, 8, 1, &zoid); |
313 |
if (error) |
|
314 |
return (error); |
|
789 | 315 |
|
316 |
zfsvfs->z_dqueue = zoid; |
|
317 |
||
318 |
/* |
|
319 |
* Initialize delete head structure |
|
320 |
* Thread(s) will be started/stopped via |
|
321 |
* readonly_changed_cb() depending |
|
322 |
* on whether this is rw/ro mount. |
|
323 |
*/ |
|
324 |
list_create(&zfsvfs->z_delete_head.z_znodes, |
|
325 |
sizeof (znode_t), offsetof(znode_t, z_list_node)); |
|
326 |
||
327 |
return (0); |
|
328 |
} |
|
329 |
||
330 |
/* |
|
1816
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
331 |
* define a couple of values we need available |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
332 |
* for both 64 and 32 bit environments. |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
333 |
*/ |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
334 |
#ifndef NBITSMINOR64 |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
335 |
#define NBITSMINOR64 32 |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
336 |
#endif |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
337 |
#ifndef MAXMAJ64 |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
338 |
#define MAXMAJ64 0xffffffffUL |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
339 |
#endif |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
340 |
#ifndef MAXMIN64 |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
341 |
#define MAXMIN64 0xffffffffUL |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
342 |
#endif |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
343 |
|
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
344 |
/* |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
345 |
* Create special expldev for ZFS private use. |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
346 |
* Can't use standard expldev since it doesn't do |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
347 |
* what we want. The standard expldev() takes a |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
348 |
* dev32_t in LP64 and expands it to a long dev_t. |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
349 |
* We need an interface that takes a dev32_t in ILP32 |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
350 |
* and expands it to a long dev_t. |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
351 |
*/ |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
352 |
static uint64_t |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
353 |
zfs_expldev(dev_t dev) |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
354 |
{ |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
355 |
#ifndef _LP64 |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
356 |
major_t major = (major_t)dev >> NBITSMINOR32 & MAXMAJ32; |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
357 |
return (((uint64_t)major << NBITSMINOR64) | |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
358 |
((minor_t)dev & MAXMIN32)); |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
359 |
#else |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
360 |
return (dev); |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
361 |
#endif |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
362 |
} |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
363 |
|
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
364 |
/* |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
365 |
* Special cmpldev for ZFS private use. |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
366 |
* Can't use standard cmpldev since it takes |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
367 |
* a long dev_t and compresses it to dev32_t in |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
368 |
* LP64. We need to do a compaction of a long dev_t |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
369 |
* to a dev32_t in ILP32. |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
370 |
*/ |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
371 |
dev_t |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
372 |
zfs_cmpldev(uint64_t dev) |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
373 |
{ |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
374 |
#ifndef _LP64 |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
375 |
minor_t minor = (minor_t)dev & MAXMIN64; |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
376 |
major_t major = (major_t)(dev >> NBITSMINOR64) & MAXMAJ64; |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
377 |
|
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
378 |
if (major > MAXMAJ32 || minor > MAXMIN32) |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
379 |
return (NODEV32); |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
380 |
|
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
381 |
return (((dev32_t)major << NBITSMINOR32) | minor); |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
382 |
#else |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
383 |
return (dev); |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
384 |
#endif |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
385 |
} |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
386 |
|
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
387 |
/* |
789 | 388 |
* Construct a new znode/vnode and intialize. |
389 |
* |
|
390 |
* This does not do a call to dmu_set_user() that is |
|
391 |
* up to the caller to do, in case you don't want to |
|
392 |
* return the znode |
|
393 |
*/ |
|
1544 | 394 |
static znode_t * |
789 | 395 |
zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, uint64_t obj_num, int blksz) |
396 |
{ |
|
397 |
znode_t *zp; |
|
398 |
vnode_t *vp; |
|
399 |
||
400 |
zp = kmem_cache_alloc(znode_cache, KM_SLEEP); |
|
401 |
||
402 |
ASSERT(zp->z_dirlocks == NULL); |
|
403 |
||
404 |
zp->z_phys = db->db_data; |
|
405 |
zp->z_zfsvfs = zfsvfs; |
|
406 |
zp->z_active = 1; |
|
407 |
zp->z_reap = 0; |
|
408 |
zp->z_atime_dirty = 0; |
|
409 |
zp->z_dbuf_held = 0; |
|
410 |
zp->z_mapcnt = 0; |
|
411 |
zp->z_last_itx = 0; |
|
412 |
zp->z_dbuf = db; |
|
413 |
zp->z_id = obj_num; |
|
414 |
zp->z_blksz = blksz; |
|
415 |
zp->z_seq = 0x7A4653; |
|
416 |
||
417 |
mutex_enter(&zfsvfs->z_znodes_lock); |
|
418 |
list_insert_tail(&zfsvfs->z_all_znodes, zp); |
|
419 |
mutex_exit(&zfsvfs->z_znodes_lock); |
|
420 |
||
421 |
vp = ZTOV(zp); |
|
422 |
vn_reinit(vp); |
|
423 |
||
424 |
vp->v_vfsp = zfsvfs->z_parent->z_vfs; |
|
425 |
vp->v_type = IFTOVT((mode_t)zp->z_phys->zp_mode); |
|
426 |
||
427 |
switch (vp->v_type) { |
|
428 |
case VDIR: |
|
429 |
if (zp->z_phys->zp_flags & ZFS_XATTR) { |
|
430 |
vn_setops(vp, zfs_xdvnodeops); |
|
431 |
vp->v_flag |= V_XATTRDIR; |
|
432 |
} else |
|
433 |
vn_setops(vp, zfs_dvnodeops); |
|
869
dc133b87dfb3
6297285 znode prefetching in zfs_readdir causes 5x performance degradation for 'ls'
perrin
parents:
789
diff
changeset
|
434 |
zp->z_zn_prefetch = B_TRUE; /* z_prefetch default is enabled */ |
789 | 435 |
break; |
436 |
case VBLK: |
|
437 |
case VCHR: |
|
1816
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
438 |
vp->v_rdev = zfs_cmpldev(zp->z_phys->zp_rdev); |
789 | 439 |
/*FALLTHROUGH*/ |
440 |
case VFIFO: |
|
441 |
case VSOCK: |
|
442 |
case VDOOR: |
|
443 |
vn_setops(vp, zfs_fvnodeops); |
|
444 |
break; |
|
445 |
case VREG: |
|
446 |
vp->v_flag |= VMODSORT; |
|
447 |
vn_setops(vp, zfs_fvnodeops); |
|
448 |
break; |
|
449 |
case VLNK: |
|
450 |
vn_setops(vp, zfs_symvnodeops); |
|
451 |
break; |
|
452 |
default: |
|
453 |
vn_setops(vp, zfs_evnodeops); |
|
454 |
break; |
|
455 |
} |
|
456 |
||
457 |
return (zp); |
|
458 |
} |
|
459 |
||
460 |
static void |
|
461 |
zfs_znode_dmu_init(znode_t *zp) |
|
462 |
{ |
|
463 |
znode_t *nzp; |
|
464 |
zfsvfs_t *zfsvfs = zp->z_zfsvfs; |
|
465 |
dmu_buf_t *db = zp->z_dbuf; |
|
466 |
||
467 |
mutex_enter(&zp->z_lock); |
|
468 |
||
469 |
nzp = dmu_buf_set_user(db, zp, &zp->z_phys, znode_pageout_func); |
|
470 |
||
471 |
/* |
|
472 |
* there should be no |
|
473 |
* concurrent zgets on this object. |
|
474 |
*/ |
|
475 |
ASSERT3P(nzp, ==, NULL); |
|
476 |
||
477 |
/* |
|
478 |
* Slap on VROOT if we are the root znode |
|
479 |
*/ |
|
480 |
if (zp->z_id == zfsvfs->z_root) { |
|
481 |
ZTOV(zp)->v_flag |= VROOT; |
|
482 |
} |
|
483 |
||
484 |
ASSERT(zp->z_dbuf_held == 0); |
|
485 |
zp->z_dbuf_held = 1; |
|
486 |
VFS_HOLD(zfsvfs->z_vfs); |
|
487 |
mutex_exit(&zp->z_lock); |
|
488 |
vn_exists(ZTOV(zp)); |
|
489 |
} |
|
490 |
||
491 |
/* |
|
492 |
* Create a new DMU object to hold a zfs znode. |
|
493 |
* |
|
494 |
* IN: dzp - parent directory for new znode |
|
495 |
* vap - file attributes for new znode |
|
496 |
* tx - dmu transaction id for zap operations |
|
497 |
* cr - credentials of caller |
|
498 |
* flag - flags: |
|
499 |
* IS_ROOT_NODE - new object will be root |
|
500 |
* IS_XATTR - new object is an attribute |
|
501 |
* IS_REPLAY - intent log replay |
|
502 |
* |
|
503 |
* OUT: oid - ID of created object |
|
504 |
* |
|
505 |
*/ |
|
506 |
void |
|
507 |
zfs_mknode(znode_t *dzp, vattr_t *vap, uint64_t *oid, dmu_tx_t *tx, cred_t *cr, |
|
508 |
uint_t flag, znode_t **zpp, int bonuslen) |
|
509 |
{ |
|
510 |
dmu_buf_t *dbp; |
|
511 |
znode_phys_t *pzp; |
|
512 |
znode_t *zp; |
|
513 |
zfsvfs_t *zfsvfs = dzp->z_zfsvfs; |
|
514 |
timestruc_t now; |
|
515 |
uint64_t gen; |
|
516 |
int err; |
|
517 |
||
518 |
ASSERT(vap && (vap->va_mask & (AT_TYPE|AT_MODE)) == (AT_TYPE|AT_MODE)); |
|
519 |
||
520 |
if (zfsvfs->z_assign >= TXG_INITIAL) { /* ZIL replay */ |
|
521 |
*oid = vap->va_nodeid; |
|
522 |
flag |= IS_REPLAY; |
|
523 |
now = vap->va_ctime; /* see zfs_replay_create() */ |
|
524 |
gen = vap->va_nblocks; /* ditto */ |
|
525 |
} else { |
|
526 |
*oid = 0; |
|
527 |
gethrestime(&now); |
|
528 |
gen = dmu_tx_get_txg(tx); |
|
529 |
} |
|
530 |
||
531 |
/* |
|
532 |
* Create a new DMU object. |
|
533 |
*/ |
|
1544 | 534 |
/* |
535 |
* There's currently no mechanism for pre-reading the blocks that will |
|
536 |
* be to needed allocate a new object, so we accept the small chance |
|
537 |
* that there will be an i/o error and we will fail one of the |
|
538 |
* assertions below. |
|
539 |
*/ |
|
789 | 540 |
if (vap->va_type == VDIR) { |
541 |
if (flag & IS_REPLAY) { |
|
542 |
err = zap_create_claim(zfsvfs->z_os, *oid, |
|
543 |
DMU_OT_DIRECTORY_CONTENTS, |
|
544 |
DMU_OT_ZNODE, sizeof (znode_phys_t) + bonuslen, tx); |
|
545 |
ASSERT3U(err, ==, 0); |
|
546 |
} else { |
|
547 |
*oid = zap_create(zfsvfs->z_os, |
|
548 |
DMU_OT_DIRECTORY_CONTENTS, |
|
549 |
DMU_OT_ZNODE, sizeof (znode_phys_t) + bonuslen, tx); |
|
550 |
} |
|
551 |
} else { |
|
552 |
if (flag & IS_REPLAY) { |
|
553 |
err = dmu_object_claim(zfsvfs->z_os, *oid, |
|
554 |
DMU_OT_PLAIN_FILE_CONTENTS, 0, |
|
555 |
DMU_OT_ZNODE, sizeof (znode_phys_t) + bonuslen, tx); |
|
556 |
ASSERT3U(err, ==, 0); |
|
557 |
} else { |
|
558 |
*oid = dmu_object_alloc(zfsvfs->z_os, |
|
559 |
DMU_OT_PLAIN_FILE_CONTENTS, 0, |
|
560 |
DMU_OT_ZNODE, sizeof (znode_phys_t) + bonuslen, tx); |
|
561 |
} |
|
562 |
} |
|
1544 | 563 |
VERIFY(0 == dmu_bonus_hold(zfsvfs->z_os, *oid, NULL, &dbp)); |
789 | 564 |
dmu_buf_will_dirty(dbp, tx); |
565 |
||
566 |
/* |
|
567 |
* Initialize the znode physical data to zero. |
|
568 |
*/ |
|
569 |
ASSERT(dbp->db_size >= sizeof (znode_phys_t)); |
|
570 |
bzero(dbp->db_data, dbp->db_size); |
|
571 |
pzp = dbp->db_data; |
|
572 |
||
573 |
/* |
|
574 |
* If this is the root, fix up the half-initialized parent pointer |
|
575 |
* to reference the just-allocated physical data area. |
|
576 |
*/ |
|
577 |
if (flag & IS_ROOT_NODE) { |
|
578 |
dzp->z_phys = pzp; |
|
579 |
dzp->z_id = *oid; |
|
580 |
} |
|
581 |
||
582 |
/* |
|
583 |
* If parent is an xattr, so am I. |
|
584 |
*/ |
|
585 |
if (dzp->z_phys->zp_flags & ZFS_XATTR) |
|
586 |
flag |= IS_XATTR; |
|
587 |
||
588 |
if (vap->va_type == VBLK || vap->va_type == VCHR) { |
|
1816
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
589 |
pzp->zp_rdev = zfs_expldev(vap->va_rdev); |
789 | 590 |
} |
591 |
||
592 |
if (vap->va_type == VDIR) { |
|
593 |
pzp->zp_size = 2; /* contents ("." and "..") */ |
|
594 |
pzp->zp_links = (flag & (IS_ROOT_NODE | IS_XATTR)) ? 2 : 1; |
|
595 |
} |
|
596 |
||
597 |
pzp->zp_parent = dzp->z_id; |
|
598 |
if (flag & IS_XATTR) |
|
599 |
pzp->zp_flags |= ZFS_XATTR; |
|
600 |
||
601 |
pzp->zp_gen = gen; |
|
602 |
||
603 |
ZFS_TIME_ENCODE(&now, pzp->zp_crtime); |
|
604 |
ZFS_TIME_ENCODE(&now, pzp->zp_ctime); |
|
605 |
||
606 |
if (vap->va_mask & AT_ATIME) { |
|
607 |
ZFS_TIME_ENCODE(&vap->va_atime, pzp->zp_atime); |
|
608 |
} else { |
|
609 |
ZFS_TIME_ENCODE(&now, pzp->zp_atime); |
|
610 |
} |
|
611 |
||
612 |
if (vap->va_mask & AT_MTIME) { |
|
613 |
ZFS_TIME_ENCODE(&vap->va_mtime, pzp->zp_mtime); |
|
614 |
} else { |
|
615 |
ZFS_TIME_ENCODE(&now, pzp->zp_mtime); |
|
616 |
} |
|
617 |
||
618 |
pzp->zp_mode = MAKEIMODE(vap->va_type, vap->va_mode); |
|
619 |
zp = zfs_znode_alloc(zfsvfs, dbp, *oid, 0); |
|
620 |
||
621 |
zfs_perm_init(zp, dzp, flag, vap, tx, cr); |
|
622 |
||
623 |
if (zpp) { |
|
624 |
kmutex_t *hash_mtx = ZFS_OBJ_MUTEX(zp); |
|
625 |
||
626 |
mutex_enter(hash_mtx); |
|
627 |
zfs_znode_dmu_init(zp); |
|
1544 | 628 |
mutex_exit(hash_mtx); |
629 |
||
789 | 630 |
*zpp = zp; |
631 |
} else { |
|
632 |
ZTOV(zp)->v_count = 0; |
|
1544 | 633 |
dmu_buf_rele(dbp, NULL); |
789 | 634 |
zfs_znode_free(zp); |
635 |
} |
|
636 |
} |
|
637 |
||
638 |
int |
|
639 |
zfs_zget(zfsvfs_t *zfsvfs, uint64_t obj_num, znode_t **zpp) |
|
640 |
{ |
|
641 |
dmu_object_info_t doi; |
|
642 |
dmu_buf_t *db; |
|
643 |
znode_t *zp; |
|
1544 | 644 |
int err; |
789 | 645 |
|
646 |
*zpp = NULL; |
|
647 |
||
648 |
ZFS_OBJ_HOLD_ENTER(zfsvfs, obj_num); |
|
649 |
||
1544 | 650 |
err = dmu_bonus_hold(zfsvfs->z_os, obj_num, NULL, &db); |
651 |
if (err) { |
|
789 | 652 |
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); |
1544 | 653 |
return (err); |
789 | 654 |
} |
655 |
||
656 |
dmu_object_info_from_db(db, &doi); |
|
657 |
if (doi.doi_bonus_type != DMU_OT_ZNODE || |
|
658 |
doi.doi_bonus_size < sizeof (znode_phys_t)) { |
|
1544 | 659 |
dmu_buf_rele(db, NULL); |
789 | 660 |
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); |
661 |
return (EINVAL); |
|
662 |
} |
|
663 |
||
664 |
ASSERT(db->db_object == obj_num); |
|
665 |
ASSERT(db->db_offset == -1); |
|
666 |
ASSERT(db->db_data != NULL); |
|
667 |
||
668 |
zp = dmu_buf_get_user(db); |
|
669 |
||
670 |
if (zp != NULL) { |
|
671 |
mutex_enter(&zp->z_lock); |
|
672 |
||
673 |
ASSERT3U(zp->z_id, ==, obj_num); |
|
674 |
if (zp->z_reap) { |
|
1544 | 675 |
dmu_buf_rele(db, NULL); |
789 | 676 |
mutex_exit(&zp->z_lock); |
677 |
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); |
|
678 |
return (ENOENT); |
|
679 |
} else if (zp->z_dbuf_held) { |
|
1544 | 680 |
dmu_buf_rele(db, NULL); |
789 | 681 |
} else { |
682 |
zp->z_dbuf_held = 1; |
|
683 |
VFS_HOLD(zfsvfs->z_vfs); |
|
684 |
} |
|
685 |
||
1544 | 686 |
if (zp->z_active == 0) |
789 | 687 |
zp->z_active = 1; |
1544 | 688 |
|
789 | 689 |
VN_HOLD(ZTOV(zp)); |
690 |
mutex_exit(&zp->z_lock); |
|
1544 | 691 |
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); |
789 | 692 |
*zpp = zp; |
693 |
return (0); |
|
694 |
} |
|
695 |
||
696 |
/* |
|
697 |
* Not found create new znode/vnode |
|
698 |
*/ |
|
699 |
zp = zfs_znode_alloc(zfsvfs, db, obj_num, doi.doi_data_block_size); |
|
700 |
ASSERT3U(zp->z_id, ==, obj_num); |
|
701 |
zfs_znode_dmu_init(zp); |
|
1544 | 702 |
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); |
789 | 703 |
*zpp = zp; |
704 |
return (0); |
|
705 |
} |
|
706 |
||
707 |
void |
|
708 |
zfs_znode_delete(znode_t *zp, dmu_tx_t *tx) |
|
709 |
{ |
|
710 |
zfsvfs_t *zfsvfs = zp->z_zfsvfs; |
|
711 |
int error; |
|
712 |
||
713 |
ZFS_OBJ_HOLD_ENTER(zfsvfs, zp->z_id); |
|
714 |
if (zp->z_phys->zp_acl.z_acl_extern_obj) { |
|
715 |
error = dmu_object_free(zfsvfs->z_os, |
|
716 |
zp->z_phys->zp_acl.z_acl_extern_obj, tx); |
|
717 |
ASSERT3U(error, ==, 0); |
|
718 |
} |
|
719 |
error = dmu_object_free(zfsvfs->z_os, zp->z_id, tx); |
|
720 |
ASSERT3U(error, ==, 0); |
|
721 |
zp->z_dbuf_held = 0; |
|
722 |
ZFS_OBJ_HOLD_EXIT(zfsvfs, zp->z_id); |
|
1544 | 723 |
dmu_buf_rele(zp->z_dbuf, NULL); |
789 | 724 |
} |
725 |
||
726 |
void |
|
727 |
zfs_zinactive(znode_t *zp) |
|
728 |
{ |
|
729 |
vnode_t *vp = ZTOV(zp); |
|
730 |
zfsvfs_t *zfsvfs = zp->z_zfsvfs; |
|
731 |
uint64_t z_id = zp->z_id; |
|
732 |
||
733 |
ASSERT(zp->z_dbuf_held && zp->z_phys); |
|
734 |
||
735 |
/* |
|
736 |
* Don't allow a zfs_zget() while were trying to release this znode |
|
737 |
*/ |
|
738 |
ZFS_OBJ_HOLD_ENTER(zfsvfs, z_id); |
|
739 |
||
740 |
mutex_enter(&zp->z_lock); |
|
741 |
mutex_enter(&vp->v_lock); |
|
742 |
vp->v_count--; |
|
743 |
if (vp->v_count > 0 || vn_has_cached_data(vp)) { |
|
744 |
/* |
|
745 |
* If the hold count is greater than zero, somebody has |
|
746 |
* obtained a new reference on this znode while we were |
|
747 |
* processing it here, so we are done. If we still have |
|
748 |
* mapped pages then we are also done, since we don't |
|
749 |
* want to inactivate the znode until the pages get pushed. |
|
750 |
* |
|
751 |
* XXX - if vn_has_cached_data(vp) is true, but count == 0, |
|
752 |
* this seems like it would leave the znode hanging with |
|
753 |
* no chance to go inactive... |
|
754 |
*/ |
|
755 |
mutex_exit(&vp->v_lock); |
|
756 |
mutex_exit(&zp->z_lock); |
|
757 |
ZFS_OBJ_HOLD_EXIT(zfsvfs, z_id); |
|
758 |
return; |
|
759 |
} |
|
760 |
mutex_exit(&vp->v_lock); |
|
761 |
zp->z_active = 0; |
|
762 |
||
763 |
/* |
|
764 |
* If this was the last reference to a file with no links, |
|
765 |
* remove the file from the file system. |
|
766 |
*/ |
|
767 |
if (zp->z_reap) { |
|
768 |
mutex_exit(&zp->z_lock); |
|
769 |
ZFS_OBJ_HOLD_EXIT(zfsvfs, z_id); |
|
770 |
/* XATTR files are not put on the delete queue */ |
|
771 |
if (zp->z_phys->zp_flags & ZFS_XATTR) { |
|
772 |
zfs_rmnode(zp); |
|
773 |
} else { |
|
774 |
mutex_enter(&zfsvfs->z_delete_head.z_mutex); |
|
775 |
list_insert_tail(&zfsvfs->z_delete_head.z_znodes, zp); |
|
776 |
zfsvfs->z_delete_head.z_znode_count++; |
|
777 |
cv_broadcast(&zfsvfs->z_delete_head.z_cv); |
|
778 |
mutex_exit(&zfsvfs->z_delete_head.z_mutex); |
|
779 |
} |
|
780 |
VFS_RELE(zfsvfs->z_vfs); |
|
781 |
return; |
|
782 |
} |
|
1544 | 783 |
ASSERT(zp->z_phys); |
784 |
ASSERT(zp->z_dbuf_held); |
|
789 | 785 |
|
1544 | 786 |
zp->z_dbuf_held = 0; |
789 | 787 |
mutex_exit(&zp->z_lock); |
1544 | 788 |
dmu_buf_rele(zp->z_dbuf, NULL); |
789 | 789 |
ZFS_OBJ_HOLD_EXIT(zfsvfs, z_id); |
1544 | 790 |
VFS_RELE(zfsvfs->z_vfs); |
789 | 791 |
} |
792 |
||
793 |
void |
|
794 |
zfs_znode_free(znode_t *zp) |
|
795 |
{ |
|
796 |
zfsvfs_t *zfsvfs = zp->z_zfsvfs; |
|
797 |
||
798 |
mutex_enter(&zfsvfs->z_znodes_lock); |
|
799 |
list_remove(&zfsvfs->z_all_znodes, zp); |
|
800 |
mutex_exit(&zfsvfs->z_znodes_lock); |
|
801 |
||
802 |
kmem_cache_free(znode_cache, zp); |
|
803 |
} |
|
804 |
||
805 |
void |
|
806 |
zfs_time_stamper_locked(znode_t *zp, uint_t flag, dmu_tx_t *tx) |
|
807 |
{ |
|
808 |
timestruc_t now; |
|
809 |
||
810 |
ASSERT(MUTEX_HELD(&zp->z_lock)); |
|
811 |
||
812 |
gethrestime(&now); |
|
813 |
||
814 |
if (tx) { |
|
815 |
dmu_buf_will_dirty(zp->z_dbuf, tx); |
|
816 |
zp->z_atime_dirty = 0; |
|
817 |
zp->z_seq++; |
|
818 |
} else { |
|
819 |
zp->z_atime_dirty = 1; |
|
820 |
} |
|
821 |
||
822 |
if (flag & AT_ATIME) |
|
823 |
ZFS_TIME_ENCODE(&now, zp->z_phys->zp_atime); |
|
824 |
||
825 |
if (flag & AT_MTIME) |
|
826 |
ZFS_TIME_ENCODE(&now, zp->z_phys->zp_mtime); |
|
827 |
||
828 |
if (flag & AT_CTIME) |
|
829 |
ZFS_TIME_ENCODE(&now, zp->z_phys->zp_ctime); |
|
830 |
} |
|
831 |
||
832 |
/* |
|
833 |
* Update the requested znode timestamps with the current time. |
|
834 |
* If we are in a transaction, then go ahead and mark the znode |
|
835 |
* dirty in the transaction so the timestamps will go to disk. |
|
836 |
* Otherwise, we will get pushed next time the znode is updated |
|
837 |
* in a transaction, or when this znode eventually goes inactive. |
|
838 |
* |
|
839 |
* Why is this OK? |
|
840 |
* 1 - Only the ACCESS time is ever updated outside of a transaction. |
|
841 |
* 2 - Multiple consecutive updates will be collapsed into a single |
|
842 |
* znode update by the transaction grouping semantics of the DMU. |
|
843 |
*/ |
|
844 |
void |
|
845 |
zfs_time_stamper(znode_t *zp, uint_t flag, dmu_tx_t *tx) |
|
846 |
{ |
|
847 |
mutex_enter(&zp->z_lock); |
|
848 |
zfs_time_stamper_locked(zp, flag, tx); |
|
849 |
mutex_exit(&zp->z_lock); |
|
850 |
} |
|
851 |
||
852 |
/* |
|
1669 | 853 |
* Grow the block size for a file. |
789 | 854 |
* |
855 |
* IN: zp - znode of file to free data in. |
|
856 |
* size - requested block size |
|
857 |
* tx - open transaction. |
|
858 |
* |
|
859 |
* NOTE: this function assumes that the znode is write locked. |
|
860 |
*/ |
|
1669 | 861 |
void |
789 | 862 |
zfs_grow_blocksize(znode_t *zp, uint64_t size, dmu_tx_t *tx) |
863 |
{ |
|
864 |
int error; |
|
865 |
u_longlong_t dummy; |
|
866 |
||
867 |
if (size <= zp->z_blksz) |
|
1669 | 868 |
return; |
789 | 869 |
/* |
870 |
* If the file size is already greater than the current blocksize, |
|
871 |
* we will not grow. If there is more than one block in a file, |
|
872 |
* the blocksize cannot change. |
|
873 |
*/ |
|
874 |
if (zp->z_blksz && zp->z_phys->zp_size > zp->z_blksz) |
|
1669 | 875 |
return; |
789 | 876 |
|
877 |
error = dmu_object_set_blocksize(zp->z_zfsvfs->z_os, zp->z_id, |
|
878 |
size, 0, tx); |
|
879 |
if (error == ENOTSUP) |
|
1669 | 880 |
return; |
789 | 881 |
ASSERT3U(error, ==, 0); |
882 |
||
883 |
/* What blocksize did we actually get? */ |
|
884 |
dmu_object_size_from_db(zp->z_dbuf, &zp->z_blksz, &dummy); |
|
885 |
} |
|
886 |
||
887 |
/* |
|
888 |
* This is a dummy interface used when pvn_vplist_dirty() should *not* |
|
889 |
* be calling back into the fs for a putpage(). E.g.: when truncating |
|
890 |
* a file, the pages being "thrown away* don't need to be written out. |
|
891 |
*/ |
|
892 |
/* ARGSUSED */ |
|
893 |
static int |
|
894 |
zfs_no_putpage(vnode_t *vp, page_t *pp, u_offset_t *offp, size_t *lenp, |
|
895 |
int flags, cred_t *cr) |
|
896 |
{ |
|
897 |
ASSERT(0); |
|
898 |
return (0); |
|
899 |
} |
|
900 |
||
901 |
/* |
|
1669 | 902 |
* Free space in a file. |
789 | 903 |
* |
904 |
* IN: zp - znode of file to free data in. |
|
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
905 |
* off - start of section to free. |
789 | 906 |
* len - length of section to free (0 => to EOF). |
907 |
* flag - current file open mode flags. |
|
908 |
* |
|
909 |
* RETURN: 0 if success |
|
910 |
* error code if failure |
|
911 |
*/ |
|
912 |
int |
|
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
913 |
zfs_freesp(znode_t *zp, uint64_t off, uint64_t len, int flag, boolean_t log) |
789 | 914 |
{ |
915 |
vnode_t *vp = ZTOV(zp); |
|
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
916 |
dmu_tx_t *tx; |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
917 |
zfsvfs_t *zfsvfs = zp->z_zfsvfs; |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
918 |
zilog_t *zilog = zfsvfs->z_log; |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
919 |
rl_t *rl; |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
920 |
uint64_t seq = 0; |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
921 |
uint64_t end = off + len; |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
922 |
uint64_t size, new_blksz; |
1669 | 923 |
int error; |
789 | 924 |
|
1394
e8d500b79ced
6381600 tc_open.021 in mstc testsuite is returning -1 when run on a zfs
marks
parents:
869
diff
changeset
|
925 |
if (ZTOV(zp)->v_type == VFIFO) |
e8d500b79ced
6381600 tc_open.021 in mstc testsuite is returning -1 when run on a zfs
marks
parents:
869
diff
changeset
|
926 |
return (0); |
e8d500b79ced
6381600 tc_open.021 in mstc testsuite is returning -1 when run on a zfs
marks
parents:
869
diff
changeset
|
927 |
|
789 | 928 |
/* |
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
929 |
* If we will change zp_size then lock the whole file, |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
930 |
* otherwise just lock the range being freed. |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
931 |
*/ |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
932 |
if (len == 0 || off + len > zp->z_phys->zp_size) { |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
933 |
rl = zfs_range_lock(zp, 0, UINT64_MAX, RL_WRITER); |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
934 |
} else { |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
935 |
rl = zfs_range_lock(zp, off, len, RL_WRITER); |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
936 |
/* recheck, in case zp_size changed */ |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
937 |
if (off + len > zp->z_phys->zp_size) { |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
938 |
/* lost race: file size changed, lock whole file */ |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
939 |
zfs_range_unlock(zp, rl); |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
940 |
rl = zfs_range_lock(zp, 0, UINT64_MAX, RL_WRITER); |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
941 |
} |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
942 |
} |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
943 |
|
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
944 |
/* |
789 | 945 |
* Nothing to do if file already at desired length. |
946 |
*/ |
|
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
947 |
size = zp->z_phys->zp_size; |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
948 |
if (len == 0 && size == off) { |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
949 |
zfs_range_unlock(zp, rl); |
789 | 950 |
return (0); |
951 |
} |
|
952 |
||
953 |
/* |
|
954 |
* Check for any locks in the region to be freed. |
|
955 |
*/ |
|
956 |
if (MANDLOCK(vp, (mode_t)zp->z_phys->zp_mode)) { |
|
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
957 |
uint64_t start = off; |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
958 |
uint64_t extent = len; |
789 | 959 |
|
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
960 |
if (off > size) { |
789 | 961 |
start = size; |
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
962 |
extent += off - size; |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
963 |
} else if (len == 0) { |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
964 |
extent = size - off; |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
965 |
} |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
966 |
if (error = chklock(vp, FWRITE, start, extent, flag, NULL)) { |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
967 |
zfs_range_unlock(zp, rl); |
789 | 968 |
return (error); |
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
969 |
} |
789 | 970 |
} |
971 |
||
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
972 |
tx = dmu_tx_create(zfsvfs->z_os); |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
973 |
dmu_tx_hold_bonus(tx, zp->z_id); |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
974 |
new_blksz = 0; |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
975 |
if (end > size && |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
976 |
(!ISP2(zp->z_blksz) || zp->z_blksz < zfsvfs->z_max_blksz)) { |
789 | 977 |
/* |
978 |
* We are growing the file past the current block size. |
|
979 |
*/ |
|
980 |
if (zp->z_blksz > zp->z_zfsvfs->z_max_blksz) { |
|
981 |
ASSERT(!ISP2(zp->z_blksz)); |
|
982 |
new_blksz = MIN(end, SPA_MAXBLOCKSIZE); |
|
983 |
} else { |
|
984 |
new_blksz = MIN(end, zp->z_zfsvfs->z_max_blksz); |
|
985 |
} |
|
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
986 |
dmu_tx_hold_write(tx, zp->z_id, 0, MIN(end, new_blksz)); |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
987 |
} else if (off < size) { |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
988 |
/* |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
989 |
* If len == 0, we are truncating the file. |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
990 |
*/ |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
991 |
dmu_tx_hold_free(tx, zp->z_id, off, len ? len : DMU_OBJECT_END); |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
992 |
} |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
993 |
|
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
994 |
error = dmu_tx_assign(tx, zfsvfs->z_assign); |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
995 |
if (error) { |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
996 |
dmu_tx_abort(tx); |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
997 |
zfs_range_unlock(zp, rl); |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
998 |
return (error); |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
999 |
} |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1000 |
|
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1001 |
if (new_blksz) |
1669 | 1002 |
zfs_grow_blocksize(zp, new_blksz, tx); |
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1003 |
|
789 | 1004 |
if (end > size || len == 0) |
1005 |
zp->z_phys->zp_size = end; |
|
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1006 |
|
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1007 |
if (off < size) { |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1008 |
objset_t *os = zfsvfs->z_os; |
1936
b6ded90e4d4b
6398177 zfs: poor nightly build performance in 32-bit mode (high disk activity)
maybee
parents:
1878
diff
changeset
|
1009 |
uint64_t rlen = len; |
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1010 |
|
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1011 |
if (len == 0) |
1936
b6ded90e4d4b
6398177 zfs: poor nightly build performance in 32-bit mode (high disk activity)
maybee
parents:
1878
diff
changeset
|
1012 |
rlen = -1; |
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1013 |
else if (end > size) |
1936
b6ded90e4d4b
6398177 zfs: poor nightly build performance in 32-bit mode (high disk activity)
maybee
parents:
1878
diff
changeset
|
1014 |
rlen = size - off; |
b6ded90e4d4b
6398177 zfs: poor nightly build performance in 32-bit mode (high disk activity)
maybee
parents:
1878
diff
changeset
|
1015 |
VERIFY(0 == dmu_free_range(os, zp->z_id, off, rlen, tx)); |
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1016 |
} |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1017 |
|
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1018 |
if (log) { |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1019 |
zfs_time_stamper(zp, CONTENT_MODIFIED, tx); |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1020 |
seq = zfs_log_truncate(zilog, tx, TX_TRUNCATE, zp, off, len); |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1021 |
} |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1022 |
|
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1023 |
zfs_range_unlock(zp, rl); |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1024 |
|
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1025 |
dmu_tx_commit(tx); |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1026 |
|
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1027 |
if (log) |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1028 |
zil_commit(zilog, seq, 0); |
789 | 1029 |
|
1030 |
/* |
|
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1031 |
* Clear any mapped pages in the truncated region. This has to |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1032 |
* happen outside of the transaction to avoid the possibility of |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1033 |
* a deadlock with someone trying to push a page that we are |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1034 |
* about to invalidate. |
789 | 1035 |
*/ |
1036 |
rw_enter(&zp->z_map_lock, RW_WRITER); |
|
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1037 |
if (off < size && vn_has_cached_data(vp)) { |
789 | 1038 |
page_t *pp; |
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1039 |
uint64_t start = off & PAGEMASK; |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1040 |
int poff = off & PAGEOFFSET; |
789 | 1041 |
|
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1042 |
if (poff != 0 && (pp = page_lookup(vp, start, SE_SHARED))) { |
789 | 1043 |
/* |
1044 |
* We need to zero a partial page. |
|
1045 |
*/ |
|
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1046 |
pagezero(pp, poff, PAGESIZE - poff); |
789 | 1047 |
start += PAGESIZE; |
1048 |
page_unlock(pp); |
|
1049 |
} |
|
1050 |
error = pvn_vplist_dirty(vp, start, zfs_no_putpage, |
|
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1051 |
B_INVAL | B_TRUNC, NULL); |
789 | 1052 |
ASSERT(error == 0); |
1053 |
} |
|
1054 |
rw_exit(&zp->z_map_lock); |
|
1055 |
||
1056 |
return (0); |
|
1057 |
} |
|
1058 |
||
1059 |
void |
|
1060 |
zfs_create_fs(objset_t *os, cred_t *cr, dmu_tx_t *tx) |
|
1061 |
{ |
|
1062 |
zfsvfs_t zfsvfs; |
|
1063 |
uint64_t moid, doid, roid = 0; |
|
1760 | 1064 |
uint64_t version = ZPL_VERSION; |
789 | 1065 |
int error; |
1066 |
znode_t *rootzp = NULL; |
|
1067 |
vnode_t *vp; |
|
1068 |
vattr_t vattr; |
|
1069 |
||
1070 |
/* |
|
1071 |
* First attempt to create master node. |
|
1072 |
*/ |
|
1544 | 1073 |
/* |
1074 |
* In an empty objset, there are no blocks to read and thus |
|
1075 |
* there can be no i/o errors (which we assert below). |
|
1076 |
*/ |
|
789 | 1077 |
moid = MASTER_NODE_OBJ; |
1078 |
error = zap_create_claim(os, moid, DMU_OT_MASTER_NODE, |
|
1079 |
DMU_OT_NONE, 0, tx); |
|
1080 |
ASSERT(error == 0); |
|
1081 |
||
1082 |
/* |
|
1083 |
* Set starting attributes. |
|
1084 |
*/ |
|
1085 |
||
1760 | 1086 |
error = zap_update(os, moid, ZPL_VERSION_OBJ, 8, 1, &version, tx); |
789 | 1087 |
ASSERT(error == 0); |
1088 |
||
1089 |
/* |
|
1090 |
* Create a delete queue. |
|
1091 |
*/ |
|
1092 |
doid = zap_create(os, DMU_OT_DELETE_QUEUE, DMU_OT_NONE, 0, tx); |
|
1093 |
||
1094 |
error = zap_add(os, moid, ZFS_DELETE_QUEUE, 8, 1, &doid, tx); |
|
1095 |
ASSERT(error == 0); |
|
1096 |
||
1097 |
/* |
|
1098 |
* Create root znode. Create minimal znode/vnode/zfsvfs |
|
1099 |
* to allow zfs_mknode to work. |
|
1100 |
*/ |
|
1101 |
vattr.va_mask = AT_MODE|AT_UID|AT_GID|AT_TYPE; |
|
1102 |
vattr.va_type = VDIR; |
|
1103 |
vattr.va_mode = S_IFDIR|0755; |
|
1104 |
vattr.va_uid = 0; |
|
1105 |
vattr.va_gid = 3; |
|
1106 |
||
1107 |
rootzp = kmem_cache_alloc(znode_cache, KM_SLEEP); |
|
1108 |
rootzp->z_zfsvfs = &zfsvfs; |
|
1109 |
rootzp->z_active = 1; |
|
1110 |
rootzp->z_reap = 0; |
|
1111 |
rootzp->z_atime_dirty = 0; |
|
1112 |
rootzp->z_dbuf_held = 0; |
|
1113 |
||
1114 |
vp = ZTOV(rootzp); |
|
1115 |
vn_reinit(vp); |
|
1116 |
vp->v_type = VDIR; |
|
1117 |
||
1118 |
bzero(&zfsvfs, sizeof (zfsvfs_t)); |
|
1119 |
||
1120 |
zfsvfs.z_os = os; |
|
1121 |
zfsvfs.z_assign = TXG_NOWAIT; |
|
1122 |
zfsvfs.z_parent = &zfsvfs; |
|
1123 |
||
1124 |
mutex_init(&zfsvfs.z_znodes_lock, NULL, MUTEX_DEFAULT, NULL); |
|
1125 |
list_create(&zfsvfs.z_all_znodes, sizeof (znode_t), |
|
1126 |
offsetof(znode_t, z_link_node)); |
|
1127 |
||
1128 |
zfs_mknode(rootzp, &vattr, &roid, tx, cr, IS_ROOT_NODE, NULL, 0); |
|
1129 |
ASSERT3U(rootzp->z_id, ==, roid); |
|
1130 |
error = zap_add(os, moid, ZFS_ROOT_OBJ, 8, 1, &roid, tx); |
|
1131 |
ASSERT(error == 0); |
|
1132 |
||
1133 |
ZTOV(rootzp)->v_count = 0; |
|
1134 |
kmem_cache_free(znode_cache, rootzp); |
|
1135 |
} |