author | Mark Shellenbaum <Mark.Shellenbaum@Sun.COM> |
Tue, 03 Nov 2009 11:02:16 -0700 | |
changeset 10938 | 270624bd70f1 |
parent 10793 | 34709091de6d |
child 11249 | 6c30f7dfc97b |
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 |
/* |
|
8636
7e4ce9158df3
6551866 deadlock between zfs_write(), zfs_freesp(), and zfs_putapage()
Mark Maybee <Mark.Maybee@Sun.COM>
parents:
8227
diff
changeset
|
22 |
* Copyright 2009 Sun Microsystems, Inc. All rights reserved. |
789 | 23 |
* Use is subject to license terms. |
24 |
*/ |
|
25 |
||
4144
068f395736ad
6465105 ZFS does not update timestamps upon the creat() of an existing file
peteh
parents:
4105
diff
changeset
|
26 |
/* Portions Copyright 2007 Jeremy Teo */ |
068f395736ad
6465105 ZFS does not update timestamps upon the creat() of an existing file
peteh
parents:
4105
diff
changeset
|
27 |
|
3444
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
28 |
#ifdef _KERNEL |
789 | 29 |
#include <sys/types.h> |
30 |
#include <sys/param.h> |
|
31 |
#include <sys/time.h> |
|
32 |
#include <sys/systm.h> |
|
33 |
#include <sys/sysmacros.h> |
|
34 |
#include <sys/resource.h> |
|
35 |
#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
|
36 |
#include <sys/mkdev.h> |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
37 |
#include <sys/u8_textprep.h> |
6492
903545192033
6654808 FIGNORECASE lookups in a zfs xattr dir don't provide 'realname' data
timh
parents:
5844
diff
changeset
|
38 |
#include <sys/dsl_dataset.h> |
789 | 39 |
#include <sys/vfs.h> |
3898
c788126f2a20
PSARC/2007/124 Strong Type-Checking for VFS Operation Registration Mechanism
rsb
parents:
3897
diff
changeset
|
40 |
#include <sys/vfs_opreg.h> |
789 | 41 |
#include <sys/vnode.h> |
42 |
#include <sys/file.h> |
|
43 |
#include <sys/kmem.h> |
|
44 |
#include <sys/errno.h> |
|
45 |
#include <sys/unistd.h> |
|
46 |
#include <sys/mode.h> |
|
47 |
#include <sys/atomic.h> |
|
48 |
#include <vm/pvn.h> |
|
49 |
#include "fs/fs_subr.h" |
|
50 |
#include <sys/zfs_dir.h> |
|
51 |
#include <sys/zfs_acl.h> |
|
52 |
#include <sys/zfs_ioctl.h> |
|
1669 | 53 |
#include <sys/zfs_rlock.h> |
5331 | 54 |
#include <sys/zfs_fuid.h> |
3444
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
55 |
#include <sys/fs/zfs.h> |
5331 | 56 |
#include <sys/kidmap.h> |
3444
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
57 |
#endif /* _KERNEL */ |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
58 |
|
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
59 |
#include <sys/dmu.h> |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
60 |
#include <sys/refcount.h> |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
61 |
#include <sys/stat.h> |
789 | 62 |
#include <sys/zap.h> |
3444
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
63 |
#include <sys/zfs_znode.h> |
789 | 64 |
|
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
65 |
#include "zfs_prop.h" |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
66 |
|
3444
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
67 |
/* |
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
68 |
* Define ZNODE_STATS to turn on statistic gathering. By default, it is only |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
69 |
* turned on when DEBUG is also defined. |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
70 |
*/ |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
71 |
#ifdef DEBUG |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
72 |
#define ZNODE_STATS |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
73 |
#endif /* DEBUG */ |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
74 |
|
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
75 |
#ifdef ZNODE_STATS |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
76 |
#define ZNODE_STAT_ADD(stat) ((stat)++) |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
77 |
#else |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
78 |
#define ZNODE_STAT_ADD(stat) /* nothing */ |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
79 |
#endif /* ZNODE_STATS */ |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
80 |
|
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
81 |
#define POINTER_IS_VALID(p) (!((uintptr_t)(p) & 0x3)) |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
82 |
#define POINTER_INVALIDATE(pp) (*(pp) = (void *)((uintptr_t)(*(pp)) | 0x1)) |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
83 |
|
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
84 |
/* |
3444
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
85 |
* Functions needed for userland (ie: libzpool) are not put under |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
86 |
* #ifdef_KERNEL; the rest of the functions have dependencies |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
87 |
* (such as VFS logic) that will not compile easily in userland. |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
88 |
*/ |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
89 |
#ifdef _KERNEL |
9788
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
90 |
/* |
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
91 |
* Needed to close a small window in zfs_znode_move() that allows the zfsvfs to |
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
92 |
* be freed before it can be safely accessed. |
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
93 |
*/ |
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
94 |
krwlock_t zfsvfs_lock; |
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
95 |
|
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
96 |
static kmem_cache_t *znode_cache = NULL; |
789 | 97 |
|
98 |
/*ARGSUSED*/ |
|
99 |
static void |
|
5642
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
100 |
znode_evict_error(dmu_buf_t *dbuf, void *user_ptr) |
789 | 101 |
{ |
5642
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
102 |
/* |
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
103 |
* We should never drop all dbuf refs without first clearing |
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
104 |
* the eviction callback. |
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
105 |
*/ |
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
106 |
panic("evicting znode %p\n", user_ptr); |
789 | 107 |
} |
108 |
||
109 |
/*ARGSUSED*/ |
|
110 |
static int |
|
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
111 |
zfs_znode_cache_constructor(void *buf, void *arg, int kmflags) |
789 | 112 |
{ |
113 |
znode_t *zp = buf; |
|
114 |
||
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
115 |
ASSERT(!POINTER_IS_VALID(zp->z_zfsvfs)); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
116 |
|
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
117 |
zp->z_vnode = vn_alloc(kmflags); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
118 |
if (zp->z_vnode == NULL) { |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
119 |
return (-1); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
120 |
} |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
121 |
ZTOV(zp)->v_data = zp; |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
122 |
|
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
123 |
list_link_init(&zp->z_link_node); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
124 |
|
789 | 125 |
mutex_init(&zp->z_lock, NULL, MUTEX_DEFAULT, NULL); |
1669 | 126 |
rw_init(&zp->z_parent_lock, NULL, RW_DEFAULT, NULL); |
3897
278bade789ba
6437750 panic: db->db_buf==0||arc_referenced(db->db_buf), file: dbuf.c,line:1539
maybee
parents:
3461
diff
changeset
|
127 |
rw_init(&zp->z_name_lock, NULL, RW_DEFAULT, NULL); |
789 | 128 |
mutex_init(&zp->z_acl_lock, NULL, MUTEX_DEFAULT, NULL); |
1669 | 129 |
|
130 |
mutex_init(&zp->z_range_lock, NULL, MUTEX_DEFAULT, NULL); |
|
131 |
avl_create(&zp->z_range_avl, zfs_range_compare, |
|
132 |
sizeof (rl_t), offsetof(rl_t, r_node)); |
|
133 |
||
5446 | 134 |
zp->z_dbuf = NULL; |
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
135 |
zp->z_dirlocks = NULL; |
9981
b4907297e740
6775100 stat() performance on files on zfs should be improved
Tim Haley <Tim.Haley@Sun.COM>
parents:
9788
diff
changeset
|
136 |
zp->z_acl_cached = NULL; |
789 | 137 |
return (0); |
138 |
} |
|
139 |
||
140 |
/*ARGSUSED*/ |
|
141 |
static void |
|
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
142 |
zfs_znode_cache_destructor(void *buf, void *arg) |
789 | 143 |
{ |
144 |
znode_t *zp = buf; |
|
145 |
||
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
146 |
ASSERT(!POINTER_IS_VALID(zp->z_zfsvfs)); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
147 |
ASSERT(ZTOV(zp)->v_data == zp); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
148 |
vn_free(ZTOV(zp)); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
149 |
ASSERT(!list_link_active(&zp->z_link_node)); |
789 | 150 |
mutex_destroy(&zp->z_lock); |
1669 | 151 |
rw_destroy(&zp->z_parent_lock); |
3897
278bade789ba
6437750 panic: db->db_buf==0||arc_referenced(db->db_buf), file: dbuf.c,line:1539
maybee
parents:
3461
diff
changeset
|
152 |
rw_destroy(&zp->z_name_lock); |
789 | 153 |
mutex_destroy(&zp->z_acl_lock); |
1669 | 154 |
avl_destroy(&zp->z_range_avl); |
4831
41ec732c6d9f
6584470 zdb needs to initialize the bpl_lock mutex
gw25295
parents:
4577
diff
changeset
|
155 |
mutex_destroy(&zp->z_range_lock); |
789 | 156 |
|
5446 | 157 |
ASSERT(zp->z_dbuf == NULL); |
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
158 |
ASSERT(zp->z_dirlocks == NULL); |
10143
d2d432dfe597
6857433 memory leaks found at: zfs_acl_alloc/zfs_acl_node_alloc
Tim Haley <Tim.Haley@Sun.COM>
parents:
9981
diff
changeset
|
159 |
ASSERT(zp->z_acl_cached == NULL); |
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
160 |
} |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
161 |
|
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
162 |
#ifdef ZNODE_STATS |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
163 |
static struct { |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
164 |
uint64_t zms_zfsvfs_invalid; |
9788
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
165 |
uint64_t zms_zfsvfs_recheck1; |
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
166 |
uint64_t zms_zfsvfs_unmounted; |
9788
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
167 |
uint64_t zms_zfsvfs_recheck2; |
7579
c91803605019
6744863 race between zfs_znode_move() and zfs_zget()
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
7240
diff
changeset
|
168 |
uint64_t zms_obj_held; |
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
169 |
uint64_t zms_vnode_locked; |
7579
c91803605019
6744863 race between zfs_znode_move() and zfs_zget()
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
7240
diff
changeset
|
170 |
uint64_t zms_not_only_dnlc; |
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
171 |
} znode_move_stats; |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
172 |
#endif /* ZNODE_STATS */ |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
173 |
|
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
174 |
static void |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
175 |
zfs_znode_move_impl(znode_t *ozp, znode_t *nzp) |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
176 |
{ |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
177 |
vnode_t *vp; |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
178 |
|
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
179 |
/* Copy fields. */ |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
180 |
nzp->z_zfsvfs = ozp->z_zfsvfs; |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
181 |
|
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
182 |
/* Swap vnodes. */ |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
183 |
vp = nzp->z_vnode; |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
184 |
nzp->z_vnode = ozp->z_vnode; |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
185 |
ozp->z_vnode = vp; /* let destructor free the overwritten vnode */ |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
186 |
ZTOV(ozp)->v_data = ozp; |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
187 |
ZTOV(nzp)->v_data = nzp; |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
188 |
|
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
189 |
nzp->z_id = ozp->z_id; |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
190 |
ASSERT(ozp->z_dirlocks == NULL); /* znode not in use */ |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
191 |
ASSERT(avl_numnodes(&ozp->z_range_avl) == 0); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
192 |
nzp->z_unlinked = ozp->z_unlinked; |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
193 |
nzp->z_atime_dirty = ozp->z_atime_dirty; |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
194 |
nzp->z_zn_prefetch = ozp->z_zn_prefetch; |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
195 |
nzp->z_blksz = ozp->z_blksz; |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
196 |
nzp->z_seq = ozp->z_seq; |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
197 |
nzp->z_mapcnt = ozp->z_mapcnt; |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
198 |
nzp->z_last_itx = ozp->z_last_itx; |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
199 |
nzp->z_gen = ozp->z_gen; |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
200 |
nzp->z_sync_cnt = ozp->z_sync_cnt; |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
201 |
nzp->z_phys = ozp->z_phys; |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
202 |
nzp->z_dbuf = ozp->z_dbuf; |
10250
b179ceb34b62
6867395 zpool_upgrade_007_pos testcase panic'd with BAD TRAP: type=e (#pf Page fault)
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10143
diff
changeset
|
203 |
|
b179ceb34b62
6867395 zpool_upgrade_007_pos testcase panic'd with BAD TRAP: type=e (#pf Page fault)
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10143
diff
changeset
|
204 |
/* |
10269
2788675568fd
6868276 zfs_rezget() can be hazardous when znode has a cached ACL
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10250
diff
changeset
|
205 |
* Since this is just an idle znode and kmem is already dealing with |
2788675568fd
6868276 zfs_rezget() can be hazardous when znode has a cached ACL
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10250
diff
changeset
|
206 |
* memory pressure, release any cached ACL. |
10250
b179ceb34b62
6867395 zpool_upgrade_007_pos testcase panic'd with BAD TRAP: type=e (#pf Page fault)
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10143
diff
changeset
|
207 |
*/ |
b179ceb34b62
6867395 zpool_upgrade_007_pos testcase panic'd with BAD TRAP: type=e (#pf Page fault)
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10143
diff
changeset
|
208 |
if (ozp->z_acl_cached) { |
b179ceb34b62
6867395 zpool_upgrade_007_pos testcase panic'd with BAD TRAP: type=e (#pf Page fault)
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10143
diff
changeset
|
209 |
zfs_acl_free(ozp->z_acl_cached); |
b179ceb34b62
6867395 zpool_upgrade_007_pos testcase panic'd with BAD TRAP: type=e (#pf Page fault)
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10143
diff
changeset
|
210 |
ozp->z_acl_cached = NULL; |
b179ceb34b62
6867395 zpool_upgrade_007_pos testcase panic'd with BAD TRAP: type=e (#pf Page fault)
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10143
diff
changeset
|
211 |
} |
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
212 |
|
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
213 |
/* Update back pointers. */ |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
214 |
(void) dmu_buf_update_user(nzp->z_dbuf, ozp, nzp, &nzp->z_phys, |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
215 |
znode_evict_error); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
216 |
|
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
217 |
/* |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
218 |
* Invalidate the original znode by clearing fields that provide a |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
219 |
* pointer back to the znode. Set the low bit of the vfs pointer to |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
220 |
* ensure that zfs_znode_move() recognizes the znode as invalid in any |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
221 |
* subsequent callback. |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
222 |
*/ |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
223 |
ozp->z_dbuf = NULL; |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
224 |
POINTER_INVALIDATE(&ozp->z_zfsvfs); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
225 |
} |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
226 |
|
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
227 |
/*ARGSUSED*/ |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
228 |
static kmem_cbrc_t |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
229 |
zfs_znode_move(void *buf, void *newbuf, size_t size, void *arg) |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
230 |
{ |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
231 |
znode_t *ozp = buf, *nzp = newbuf; |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
232 |
zfsvfs_t *zfsvfs; |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
233 |
vnode_t *vp; |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
234 |
|
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
235 |
/* |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
236 |
* The znode is on the file system's list of known znodes if the vfs |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
237 |
* pointer is valid. We set the low bit of the vfs pointer when freeing |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
238 |
* the znode to invalidate it, and the memory patterns written by kmem |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
239 |
* (baddcafe and deadbeef) set at least one of the two low bits. A newly |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
240 |
* created znode sets the vfs pointer last of all to indicate that the |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
241 |
* znode is known and in a valid state to be moved by this function. |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
242 |
*/ |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
243 |
zfsvfs = ozp->z_zfsvfs; |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
244 |
if (!POINTER_IS_VALID(zfsvfs)) { |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
245 |
ZNODE_STAT_ADD(znode_move_stats.zms_zfsvfs_invalid); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
246 |
return (KMEM_CBRC_DONT_KNOW); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
247 |
} |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
248 |
|
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
249 |
/* |
9788
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
250 |
* Close a small window in which it's possible that the filesystem could |
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
251 |
* be unmounted and freed, and zfsvfs, though valid in the previous |
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
252 |
* statement, could point to unrelated memory by the time we try to |
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
253 |
* prevent the filesystem from being unmounted. |
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
254 |
*/ |
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
255 |
rw_enter(&zfsvfs_lock, RW_WRITER); |
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
256 |
if (zfsvfs != ozp->z_zfsvfs) { |
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
257 |
rw_exit(&zfsvfs_lock); |
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
258 |
ZNODE_STAT_ADD(znode_move_stats.zms_zfsvfs_recheck1); |
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
259 |
return (KMEM_CBRC_DONT_KNOW); |
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
260 |
} |
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
261 |
|
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
262 |
/* |
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
263 |
* If the znode is still valid, then so is the file system. We know that |
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
264 |
* no valid file system can be freed while we hold zfsvfs_lock, so we |
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
265 |
* can safely ensure that the filesystem is not and will not be |
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
266 |
* unmounted. The next statement is equivalent to ZFS_ENTER(). |
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
267 |
*/ |
9396
f41cf682d0d3
PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
9179
diff
changeset
|
268 |
rrw_enter(&zfsvfs->z_teardown_lock, RW_READER, FTAG); |
f41cf682d0d3
PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
9179
diff
changeset
|
269 |
if (zfsvfs->z_unmounted) { |
f41cf682d0d3
PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
9179
diff
changeset
|
270 |
ZFS_EXIT(zfsvfs); |
9788
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
271 |
rw_exit(&zfsvfs_lock); |
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
272 |
ZNODE_STAT_ADD(znode_move_stats.zms_zfsvfs_unmounted); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
273 |
return (KMEM_CBRC_DONT_KNOW); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
274 |
} |
9788
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
275 |
rw_exit(&zfsvfs_lock); |
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
276 |
|
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
277 |
mutex_enter(&zfsvfs->z_znodes_lock); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
278 |
/* |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
279 |
* Recheck the vfs pointer in case the znode was removed just before |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
280 |
* acquiring the lock. |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
281 |
*/ |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
282 |
if (zfsvfs != ozp->z_zfsvfs) { |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
283 |
mutex_exit(&zfsvfs->z_znodes_lock); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
284 |
ZFS_EXIT(zfsvfs); |
9788
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
285 |
ZNODE_STAT_ADD(znode_move_stats.zms_zfsvfs_recheck2); |
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
286 |
return (KMEM_CBRC_DONT_KNOW); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
287 |
} |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
288 |
|
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
289 |
/* |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
290 |
* At this point we know that as long as we hold z_znodes_lock, the |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
291 |
* znode cannot be freed and fields within the znode can be safely |
7579
c91803605019
6744863 race between zfs_znode_move() and zfs_zget()
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
7240
diff
changeset
|
292 |
* accessed. Now, prevent a race with zfs_zget(). |
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
293 |
*/ |
7579
c91803605019
6744863 race between zfs_znode_move() and zfs_zget()
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
7240
diff
changeset
|
294 |
if (ZFS_OBJ_HOLD_TRYENTER(zfsvfs, ozp->z_id) == 0) { |
c91803605019
6744863 race between zfs_znode_move() and zfs_zget()
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
7240
diff
changeset
|
295 |
mutex_exit(&zfsvfs->z_znodes_lock); |
c91803605019
6744863 race between zfs_znode_move() and zfs_zget()
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
7240
diff
changeset
|
296 |
ZFS_EXIT(zfsvfs); |
c91803605019
6744863 race between zfs_znode_move() and zfs_zget()
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
7240
diff
changeset
|
297 |
ZNODE_STAT_ADD(znode_move_stats.zms_obj_held); |
c91803605019
6744863 race between zfs_znode_move() and zfs_zget()
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
7240
diff
changeset
|
298 |
return (KMEM_CBRC_LATER); |
c91803605019
6744863 race between zfs_znode_move() and zfs_zget()
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
7240
diff
changeset
|
299 |
} |
c91803605019
6744863 race between zfs_znode_move() and zfs_zget()
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
7240
diff
changeset
|
300 |
|
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
301 |
vp = ZTOV(ozp); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
302 |
if (mutex_tryenter(&vp->v_lock) == 0) { |
7579
c91803605019
6744863 race between zfs_znode_move() and zfs_zget()
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
7240
diff
changeset
|
303 |
ZFS_OBJ_HOLD_EXIT(zfsvfs, ozp->z_id); |
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
304 |
mutex_exit(&zfsvfs->z_znodes_lock); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
305 |
ZFS_EXIT(zfsvfs); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
306 |
ZNODE_STAT_ADD(znode_move_stats.zms_vnode_locked); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
307 |
return (KMEM_CBRC_LATER); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
308 |
} |
7579
c91803605019
6744863 race between zfs_znode_move() and zfs_zget()
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
7240
diff
changeset
|
309 |
|
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
310 |
/* Only move znodes that are referenced _only_ by the DNLC. */ |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
311 |
if (vp->v_count != 1 || !vn_in_dnlc(vp)) { |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
312 |
mutex_exit(&vp->v_lock); |
7579
c91803605019
6744863 race between zfs_znode_move() and zfs_zget()
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
7240
diff
changeset
|
313 |
ZFS_OBJ_HOLD_EXIT(zfsvfs, ozp->z_id); |
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
314 |
mutex_exit(&zfsvfs->z_znodes_lock); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
315 |
ZFS_EXIT(zfsvfs); |
7579
c91803605019
6744863 race between zfs_znode_move() and zfs_zget()
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
7240
diff
changeset
|
316 |
ZNODE_STAT_ADD(znode_move_stats.zms_not_only_dnlc); |
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
317 |
return (KMEM_CBRC_LATER); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
318 |
} |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
319 |
|
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
320 |
/* |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
321 |
* The znode is known and in a valid state to move. We're holding the |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
322 |
* locks needed to execute the critical section. |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
323 |
*/ |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
324 |
zfs_znode_move_impl(ozp, nzp); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
325 |
mutex_exit(&vp->v_lock); |
7579
c91803605019
6744863 race between zfs_znode_move() and zfs_zget()
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
7240
diff
changeset
|
326 |
ZFS_OBJ_HOLD_EXIT(zfsvfs, ozp->z_id); |
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
327 |
|
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
328 |
list_link_replace(&ozp->z_link_node, &nzp->z_link_node); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
329 |
mutex_exit(&zfsvfs->z_znodes_lock); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
330 |
ZFS_EXIT(zfsvfs); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
331 |
|
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
332 |
return (KMEM_CBRC_YES); |
789 | 333 |
} |
334 |
||
335 |
void |
|
336 |
zfs_znode_init(void) |
|
337 |
{ |
|
338 |
/* |
|
339 |
* Initialize zcache |
|
340 |
*/ |
|
9788
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
341 |
rw_init(&zfsvfs_lock, NULL, RW_DEFAULT, NULL); |
789 | 342 |
ASSERT(znode_cache == NULL); |
343 |
znode_cache = kmem_cache_create("zfs_znode_cache", |
|
344 |
sizeof (znode_t), 0, zfs_znode_cache_constructor, |
|
345 |
zfs_znode_cache_destructor, NULL, NULL, NULL, 0); |
|
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
346 |
kmem_cache_set_move(znode_cache, zfs_znode_move); |
789 | 347 |
} |
348 |
||
349 |
void |
|
350 |
zfs_znode_fini(void) |
|
351 |
{ |
|
352 |
/* |
|
353 |
* Cleanup vfs & vnode ops |
|
354 |
*/ |
|
355 |
zfs_remove_op_tables(); |
|
356 |
||
357 |
/* |
|
358 |
* Cleanup zcache |
|
359 |
*/ |
|
360 |
if (znode_cache) |
|
361 |
kmem_cache_destroy(znode_cache); |
|
362 |
znode_cache = NULL; |
|
9788
f660bc44f2e8
6843700 zfs_znode_move() does not ensure valid file system pointer
Tom Erickson <Tom.Erickson@Sun.COM>
parents:
9396
diff
changeset
|
363 |
rw_destroy(&zfsvfs_lock); |
789 | 364 |
} |
365 |
||
366 |
struct vnodeops *zfs_dvnodeops; |
|
367 |
struct vnodeops *zfs_fvnodeops; |
|
368 |
struct vnodeops *zfs_symvnodeops; |
|
369 |
struct vnodeops *zfs_xdvnodeops; |
|
370 |
struct vnodeops *zfs_evnodeops; |
|
8845
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
371 |
struct vnodeops *zfs_sharevnodeops; |
789 | 372 |
|
373 |
void |
|
374 |
zfs_remove_op_tables() |
|
375 |
{ |
|
376 |
/* |
|
377 |
* Remove vfs ops |
|
378 |
*/ |
|
379 |
ASSERT(zfsfstype); |
|
380 |
(void) vfs_freevfsops_by_type(zfsfstype); |
|
381 |
zfsfstype = 0; |
|
382 |
||
383 |
/* |
|
384 |
* Remove vnode ops |
|
385 |
*/ |
|
386 |
if (zfs_dvnodeops) |
|
387 |
vn_freevnodeops(zfs_dvnodeops); |
|
388 |
if (zfs_fvnodeops) |
|
389 |
vn_freevnodeops(zfs_fvnodeops); |
|
390 |
if (zfs_symvnodeops) |
|
391 |
vn_freevnodeops(zfs_symvnodeops); |
|
392 |
if (zfs_xdvnodeops) |
|
393 |
vn_freevnodeops(zfs_xdvnodeops); |
|
394 |
if (zfs_evnodeops) |
|
395 |
vn_freevnodeops(zfs_evnodeops); |
|
8845
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
396 |
if (zfs_sharevnodeops) |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
397 |
vn_freevnodeops(zfs_sharevnodeops); |
789 | 398 |
|
399 |
zfs_dvnodeops = NULL; |
|
400 |
zfs_fvnodeops = NULL; |
|
401 |
zfs_symvnodeops = NULL; |
|
402 |
zfs_xdvnodeops = NULL; |
|
403 |
zfs_evnodeops = NULL; |
|
8845
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
404 |
zfs_sharevnodeops = NULL; |
789 | 405 |
} |
406 |
||
407 |
extern const fs_operation_def_t zfs_dvnodeops_template[]; |
|
408 |
extern const fs_operation_def_t zfs_fvnodeops_template[]; |
|
409 |
extern const fs_operation_def_t zfs_xdvnodeops_template[]; |
|
410 |
extern const fs_operation_def_t zfs_symvnodeops_template[]; |
|
411 |
extern const fs_operation_def_t zfs_evnodeops_template[]; |
|
8845
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
412 |
extern const fs_operation_def_t zfs_sharevnodeops_template[]; |
789 | 413 |
|
414 |
int |
|
415 |
zfs_create_op_tables() |
|
416 |
{ |
|
417 |
int error; |
|
418 |
||
419 |
/* |
|
420 |
* zfs_dvnodeops can be set if mod_remove() calls mod_installfs() |
|
421 |
* due to a failure to remove the the 2nd modlinkage (zfs_modldrv). |
|
422 |
* In this case we just return as the ops vectors are already set up. |
|
423 |
*/ |
|
424 |
if (zfs_dvnodeops) |
|
425 |
return (0); |
|
426 |
||
427 |
error = vn_make_ops(MNTTYPE_ZFS, zfs_dvnodeops_template, |
|
428 |
&zfs_dvnodeops); |
|
429 |
if (error) |
|
430 |
return (error); |
|
431 |
||
432 |
error = vn_make_ops(MNTTYPE_ZFS, zfs_fvnodeops_template, |
|
433 |
&zfs_fvnodeops); |
|
434 |
if (error) |
|
435 |
return (error); |
|
436 |
||
437 |
error = vn_make_ops(MNTTYPE_ZFS, zfs_symvnodeops_template, |
|
438 |
&zfs_symvnodeops); |
|
439 |
if (error) |
|
440 |
return (error); |
|
441 |
||
442 |
error = vn_make_ops(MNTTYPE_ZFS, zfs_xdvnodeops_template, |
|
443 |
&zfs_xdvnodeops); |
|
444 |
if (error) |
|
445 |
return (error); |
|
446 |
||
447 |
error = vn_make_ops(MNTTYPE_ZFS, zfs_evnodeops_template, |
|
448 |
&zfs_evnodeops); |
|
8845
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
449 |
if (error) |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
450 |
return (error); |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
451 |
|
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
452 |
error = vn_make_ops(MNTTYPE_ZFS, zfs_sharevnodeops_template, |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
453 |
&zfs_sharevnodeops); |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
454 |
|
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
455 |
return (error); |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
456 |
} |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
457 |
|
9030
243fd360d81f
6815893 hang mounting a dataset after booting into a new boot environment
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
8845
diff
changeset
|
458 |
int |
8845
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
459 |
zfs_create_share_dir(zfsvfs_t *zfsvfs, dmu_tx_t *tx) |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
460 |
{ |
9179
d8fbd96b79b3
6790064 zfs needs to determine uid and gid earlier in create process
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
9030
diff
changeset
|
461 |
zfs_acl_ids_t acl_ids; |
8845
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
462 |
vattr_t vattr; |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
463 |
znode_t *sharezp; |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
464 |
vnode_t *vp; |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
465 |
znode_t *zp; |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
466 |
int error; |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
467 |
|
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
468 |
vattr.va_mask = AT_MODE|AT_UID|AT_GID|AT_TYPE; |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
469 |
vattr.va_type = VDIR; |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
470 |
vattr.va_mode = S_IFDIR|0555; |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
471 |
vattr.va_uid = crgetuid(kcred); |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
472 |
vattr.va_gid = crgetgid(kcred); |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
473 |
|
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
474 |
sharezp = kmem_cache_alloc(znode_cache, KM_SLEEP); |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
475 |
sharezp->z_unlinked = 0; |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
476 |
sharezp->z_atime_dirty = 0; |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
477 |
sharezp->z_zfsvfs = zfsvfs; |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
478 |
|
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
479 |
vp = ZTOV(sharezp); |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
480 |
vn_reinit(vp); |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
481 |
vp->v_type = VDIR; |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
482 |
|
9179
d8fbd96b79b3
6790064 zfs needs to determine uid and gid earlier in create process
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
9030
diff
changeset
|
483 |
VERIFY(0 == zfs_acl_ids_create(sharezp, IS_ROOT_NODE, &vattr, |
d8fbd96b79b3
6790064 zfs needs to determine uid and gid earlier in create process
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
9030
diff
changeset
|
484 |
kcred, NULL, &acl_ids)); |
8845
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
485 |
zfs_mknode(sharezp, &vattr, tx, kcred, IS_ROOT_NODE, |
9179
d8fbd96b79b3
6790064 zfs needs to determine uid and gid earlier in create process
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
9030
diff
changeset
|
486 |
&zp, 0, &acl_ids); |
8845
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
487 |
ASSERT3P(zp, ==, sharezp); |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
488 |
ASSERT(!vn_in_dnlc(ZTOV(sharezp))); /* not valid to move */ |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
489 |
POINTER_INVALIDATE(&sharezp->z_zfsvfs); |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
490 |
error = zap_add(zfsvfs->z_os, MASTER_NODE_OBJ, |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
491 |
ZFS_SHARES_DIR, 8, 1, &sharezp->z_id, tx); |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
492 |
zfsvfs->z_shares_dir = sharezp->z_id; |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
493 |
|
9179
d8fbd96b79b3
6790064 zfs needs to determine uid and gid earlier in create process
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
9030
diff
changeset
|
494 |
zfs_acl_ids_free(&acl_ids); |
8845
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
495 |
ZTOV(sharezp)->v_count = 0; |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
496 |
dmu_buf_rele(sharezp->z_dbuf, NULL); |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
497 |
sharezp->z_dbuf = NULL; |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
498 |
kmem_cache_free(znode_cache, sharezp); |
789 | 499 |
|
500 |
return (error); |
|
501 |
} |
|
502 |
||
503 |
/* |
|
1816
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
504 |
* 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
|
505 |
* 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
|
506 |
*/ |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
507 |
#ifndef NBITSMINOR64 |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
508 |
#define NBITSMINOR64 32 |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
509 |
#endif |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
510 |
#ifndef MAXMAJ64 |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
511 |
#define MAXMAJ64 0xffffffffUL |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
512 |
#endif |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
513 |
#ifndef MAXMIN64 |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
514 |
#define MAXMIN64 0xffffffffUL |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
515 |
#endif |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
516 |
|
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
517 |
/* |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
518 |
* 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
|
519 |
* 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
|
520 |
* 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
|
521 |
* 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
|
522 |
* 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
|
523 |
* 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
|
524 |
*/ |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
525 |
static uint64_t |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
526 |
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
|
527 |
{ |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
528 |
#ifndef _LP64 |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
529 |
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
|
530 |
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
|
531 |
((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
|
532 |
#else |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
533 |
return (dev); |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
534 |
#endif |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
535 |
} |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
536 |
|
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
537 |
/* |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
538 |
* 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
|
539 |
* 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
|
540 |
* 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
|
541 |
* 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
|
542 |
* 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
|
543 |
*/ |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
544 |
dev_t |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
545 |
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
|
546 |
{ |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
547 |
#ifndef _LP64 |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
548 |
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
|
549 |
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
|
550 |
|
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
551 |
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
|
552 |
return (NODEV32); |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
553 |
|
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
554 |
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
|
555 |
#else |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
556 |
return (dev); |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
557 |
#endif |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
558 |
} |
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
559 |
|
5446 | 560 |
static void |
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
561 |
zfs_znode_dmu_init(zfsvfs_t *zfsvfs, znode_t *zp, dmu_buf_t *db) |
5446 | 562 |
{ |
563 |
znode_t *nzp; |
|
564 |
||
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
565 |
ASSERT(!POINTER_IS_VALID(zp->z_zfsvfs) || (zfsvfs == zp->z_zfsvfs)); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
566 |
ASSERT(MUTEX_HELD(ZFS_OBJ_MUTEX(zfsvfs, zp->z_id))); |
5446 | 567 |
|
568 |
mutex_enter(&zp->z_lock); |
|
569 |
||
570 |
ASSERT(zp->z_dbuf == NULL); |
|
10269
2788675568fd
6868276 zfs_rezget() can be hazardous when znode has a cached ACL
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10250
diff
changeset
|
571 |
ASSERT(zp->z_acl_cached == NULL); |
5446 | 572 |
zp->z_dbuf = db; |
5642
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
573 |
nzp = dmu_buf_set_user_ie(db, zp, &zp->z_phys, znode_evict_error); |
5446 | 574 |
|
575 |
/* |
|
576 |
* there should be no |
|
577 |
* concurrent zgets on this object. |
|
578 |
*/ |
|
579 |
if (nzp != NULL) |
|
7240
c4957ab6a78e
6698108 Sun Studio 12 finds many lint errors in ON source.
rh87107
parents:
7046
diff
changeset
|
580 |
panic("existing znode %p for dbuf %p", (void *)nzp, (void *)db); |
5446 | 581 |
|
582 |
/* |
|
583 |
* Slap on VROOT if we are the root znode |
|
584 |
*/ |
|
585 |
if (zp->z_id == zfsvfs->z_root) |
|
586 |
ZTOV(zp)->v_flag |= VROOT; |
|
587 |
||
588 |
mutex_exit(&zp->z_lock); |
|
589 |
vn_exists(ZTOV(zp)); |
|
590 |
} |
|
591 |
||
5642
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
592 |
void |
5446 | 593 |
zfs_znode_dmu_fini(znode_t *zp) |
594 |
{ |
|
595 |
dmu_buf_t *db = zp->z_dbuf; |
|
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
596 |
ASSERT(MUTEX_HELD(ZFS_OBJ_MUTEX(zp->z_zfsvfs, zp->z_id)) || |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
597 |
zp->z_unlinked || |
5642
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
598 |
RW_WRITE_HELD(&zp->z_zfsvfs->z_teardown_inactive_lock)); |
5446 | 599 |
ASSERT(zp->z_dbuf != NULL); |
600 |
zp->z_dbuf = NULL; |
|
5642
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
601 |
VERIFY(zp == dmu_buf_update_user(db, zp, NULL, NULL, NULL)); |
5446 | 602 |
dmu_buf_rele(db, NULL); |
603 |
} |
|
604 |
||
1816
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
605 |
/* |
789 | 606 |
* Construct a new znode/vnode and intialize. |
607 |
* |
|
608 |
* This does not do a call to dmu_set_user() that is |
|
609 |
* up to the caller to do, in case you don't want to |
|
610 |
* return the znode |
|
611 |
*/ |
|
1544 | 612 |
static znode_t * |
5446 | 613 |
zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz) |
789 | 614 |
{ |
615 |
znode_t *zp; |
|
616 |
vnode_t *vp; |
|
617 |
||
618 |
zp = kmem_cache_alloc(znode_cache, KM_SLEEP); |
|
619 |
||
620 |
ASSERT(zp->z_dirlocks == NULL); |
|
5446 | 621 |
ASSERT(zp->z_dbuf == NULL); |
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
622 |
ASSERT(!POINTER_IS_VALID(zp->z_zfsvfs)); |
789 | 623 |
|
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
624 |
/* |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
625 |
* Defer setting z_zfsvfs until the znode is ready to be a candidate for |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
626 |
* the zfs_znode_move() callback. |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
627 |
*/ |
5446 | 628 |
zp->z_phys = NULL; |
3461 | 629 |
zp->z_unlinked = 0; |
789 | 630 |
zp->z_atime_dirty = 0; |
631 |
zp->z_mapcnt = 0; |
|
632 |
zp->z_last_itx = 0; |
|
5446 | 633 |
zp->z_id = db->db_object; |
789 | 634 |
zp->z_blksz = blksz; |
635 |
zp->z_seq = 0x7A4653; |
|
3063
b252896b372b
6341569 zio_alloc_blk() vdev distribution performs badly
perrin
parents:
2885
diff
changeset
|
636 |
zp->z_sync_cnt = 0; |
5446 | 637 |
|
638 |
vp = ZTOV(zp); |
|
639 |
vn_reinit(vp); |
|
640 |
||
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
641 |
zfs_znode_dmu_init(zfsvfs, zp, db); |
5446 | 642 |
|
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
643 |
zp->z_gen = zp->z_phys->zp_gen; |
789 | 644 |
|
645 |
vp->v_vfsp = zfsvfs->z_parent->z_vfs; |
|
646 |
vp->v_type = IFTOVT((mode_t)zp->z_phys->zp_mode); |
|
647 |
||
648 |
switch (vp->v_type) { |
|
649 |
case VDIR: |
|
650 |
if (zp->z_phys->zp_flags & ZFS_XATTR) { |
|
651 |
vn_setops(vp, zfs_xdvnodeops); |
|
652 |
vp->v_flag |= V_XATTRDIR; |
|
5446 | 653 |
} else { |
789 | 654 |
vn_setops(vp, zfs_dvnodeops); |
5446 | 655 |
} |
869
dc133b87dfb3
6297285 znode prefetching in zfs_readdir causes 5x performance degradation for 'ls'
perrin
parents:
789
diff
changeset
|
656 |
zp->z_zn_prefetch = B_TRUE; /* z_prefetch default is enabled */ |
789 | 657 |
break; |
658 |
case VBLK: |
|
659 |
case VCHR: |
|
1816
8c14b56c8515
6408482 64-bit system can't read some 32-bit dev_ts created on zfs
marks
parents:
1760
diff
changeset
|
660 |
vp->v_rdev = zfs_cmpldev(zp->z_phys->zp_rdev); |
789 | 661 |
/*FALLTHROUGH*/ |
662 |
case VFIFO: |
|
663 |
case VSOCK: |
|
664 |
case VDOOR: |
|
665 |
vn_setops(vp, zfs_fvnodeops); |
|
666 |
break; |
|
667 |
case VREG: |
|
668 |
vp->v_flag |= VMODSORT; |
|
8845
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
669 |
if (zp->z_phys->zp_parent == zfsvfs->z_shares_dir) |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
670 |
vn_setops(vp, zfs_sharevnodeops); |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
671 |
else |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
672 |
vn_setops(vp, zfs_fvnodeops); |
789 | 673 |
break; |
674 |
case VLNK: |
|
675 |
vn_setops(vp, zfs_symvnodeops); |
|
676 |
break; |
|
677 |
default: |
|
678 |
vn_setops(vp, zfs_evnodeops); |
|
679 |
break; |
|
680 |
} |
|
681 |
||
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
682 |
mutex_enter(&zfsvfs->z_znodes_lock); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
683 |
list_insert_tail(&zfsvfs->z_all_znodes, zp); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
684 |
membar_producer(); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
685 |
/* |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
686 |
* Everything else must be valid before assigning z_zfsvfs makes the |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
687 |
* znode eligible for zfs_znode_move(). |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
688 |
*/ |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
689 |
zp->z_zfsvfs = zfsvfs; |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
690 |
mutex_exit(&zfsvfs->z_znodes_lock); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
691 |
|
5642
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
692 |
VFS_HOLD(zfsvfs->z_vfs); |
789 | 693 |
return (zp); |
694 |
} |
|
695 |
||
696 |
/* |
|
697 |
* Create a new DMU object to hold a zfs znode. |
|
698 |
* |
|
699 |
* IN: dzp - parent directory for new znode |
|
700 |
* vap - file attributes for new znode |
|
701 |
* tx - dmu transaction id for zap operations |
|
702 |
* cr - credentials of caller |
|
703 |
* flag - flags: |
|
704 |
* IS_ROOT_NODE - new object will be root |
|
705 |
* IS_XATTR - new object is an attribute |
|
706 |
* IS_REPLAY - intent log replay |
|
5331 | 707 |
* bonuslen - length of bonus buffer |
708 |
* setaclp - File/Dir initial ACL |
|
709 |
* fuidp - Tracks fuid allocation. |
|
789 | 710 |
* |
5446 | 711 |
* OUT: zpp - allocated znode |
789 | 712 |
* |
713 |
*/ |
|
714 |
void |
|
5446 | 715 |
zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr, |
9179
d8fbd96b79b3
6790064 zfs needs to determine uid and gid earlier in create process
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
9030
diff
changeset
|
716 |
uint_t flag, znode_t **zpp, int bonuslen, zfs_acl_ids_t *acl_ids) |
789 | 717 |
{ |
5446 | 718 |
dmu_buf_t *db; |
789 | 719 |
znode_phys_t *pzp; |
720 |
zfsvfs_t *zfsvfs = dzp->z_zfsvfs; |
|
721 |
timestruc_t now; |
|
5446 | 722 |
uint64_t gen, obj; |
789 | 723 |
int err; |
724 |
||
725 |
ASSERT(vap && (vap->va_mask & (AT_TYPE|AT_MODE)) == (AT_TYPE|AT_MODE)); |
|
726 |
||
8227 | 727 |
if (zfsvfs->z_replay) { |
5446 | 728 |
obj = vap->va_nodeid; |
789 | 729 |
flag |= IS_REPLAY; |
730 |
now = vap->va_ctime; /* see zfs_replay_create() */ |
|
731 |
gen = vap->va_nblocks; /* ditto */ |
|
732 |
} else { |
|
5446 | 733 |
obj = 0; |
789 | 734 |
gethrestime(&now); |
735 |
gen = dmu_tx_get_txg(tx); |
|
736 |
} |
|
737 |
||
738 |
/* |
|
739 |
* Create a new DMU object. |
|
740 |
*/ |
|
1544 | 741 |
/* |
742 |
* There's currently no mechanism for pre-reading the blocks that will |
|
743 |
* be to needed allocate a new object, so we accept the small chance |
|
744 |
* that there will be an i/o error and we will fail one of the |
|
745 |
* assertions below. |
|
746 |
*/ |
|
789 | 747 |
if (vap->va_type == VDIR) { |
748 |
if (flag & IS_REPLAY) { |
|
5446 | 749 |
err = zap_create_claim_norm(zfsvfs->z_os, obj, |
5331 | 750 |
zfsvfs->z_norm, DMU_OT_DIRECTORY_CONTENTS, |
789 | 751 |
DMU_OT_ZNODE, sizeof (znode_phys_t) + bonuslen, tx); |
752 |
ASSERT3U(err, ==, 0); |
|
753 |
} else { |
|
5446 | 754 |
obj = zap_create_norm(zfsvfs->z_os, |
5331 | 755 |
zfsvfs->z_norm, DMU_OT_DIRECTORY_CONTENTS, |
789 | 756 |
DMU_OT_ZNODE, sizeof (znode_phys_t) + bonuslen, tx); |
757 |
} |
|
758 |
} else { |
|
759 |
if (flag & IS_REPLAY) { |
|
5446 | 760 |
err = dmu_object_claim(zfsvfs->z_os, obj, |
789 | 761 |
DMU_OT_PLAIN_FILE_CONTENTS, 0, |
762 |
DMU_OT_ZNODE, sizeof (znode_phys_t) + bonuslen, tx); |
|
763 |
ASSERT3U(err, ==, 0); |
|
764 |
} else { |
|
5446 | 765 |
obj = dmu_object_alloc(zfsvfs->z_os, |
789 | 766 |
DMU_OT_PLAIN_FILE_CONTENTS, 0, |
767 |
DMU_OT_ZNODE, sizeof (znode_phys_t) + bonuslen, tx); |
|
768 |
} |
|
769 |
} |
|
10938
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
770 |
|
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
771 |
ZFS_OBJ_HOLD_ENTER(zfsvfs, obj); |
5446 | 772 |
VERIFY(0 == dmu_bonus_hold(zfsvfs->z_os, obj, NULL, &db)); |
773 |
dmu_buf_will_dirty(db, tx); |
|
789 | 774 |
|
775 |
/* |
|
776 |
* Initialize the znode physical data to zero. |
|
777 |
*/ |
|
5446 | 778 |
ASSERT(db->db_size >= sizeof (znode_phys_t)); |
779 |
bzero(db->db_data, db->db_size); |
|
780 |
pzp = db->db_data; |
|
789 | 781 |
|
782 |
/* |
|
783 |
* If this is the root, fix up the half-initialized parent pointer |
|
784 |
* to reference the just-allocated physical data area. |
|
785 |
*/ |
|
786 |
if (flag & IS_ROOT_NODE) { |
|
5642
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
787 |
dzp->z_dbuf = db; |
789 | 788 |
dzp->z_phys = pzp; |
5446 | 789 |
dzp->z_id = obj; |
789 | 790 |
} |
791 |
||
792 |
/* |
|
793 |
* If parent is an xattr, so am I. |
|
794 |
*/ |
|
795 |
if (dzp->z_phys->zp_flags & ZFS_XATTR) |
|
796 |
flag |= IS_XATTR; |
|
797 |
||
798 |
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
|
799 |
pzp->zp_rdev = zfs_expldev(vap->va_rdev); |
789 | 800 |
} |
801 |
||
5331 | 802 |
if (zfsvfs->z_use_fuids) |
803 |
pzp->zp_flags = ZFS_ARCHIVE | ZFS_AV_MODIFIED; |
|
804 |
||
789 | 805 |
if (vap->va_type == VDIR) { |
806 |
pzp->zp_size = 2; /* contents ("." and "..") */ |
|
807 |
pzp->zp_links = (flag & (IS_ROOT_NODE | IS_XATTR)) ? 2 : 1; |
|
808 |
} |
|
809 |
||
810 |
pzp->zp_parent = dzp->z_id; |
|
811 |
if (flag & IS_XATTR) |
|
812 |
pzp->zp_flags |= ZFS_XATTR; |
|
813 |
||
814 |
pzp->zp_gen = gen; |
|
815 |
||
816 |
ZFS_TIME_ENCODE(&now, pzp->zp_crtime); |
|
817 |
ZFS_TIME_ENCODE(&now, pzp->zp_ctime); |
|
818 |
||
819 |
if (vap->va_mask & AT_ATIME) { |
|
820 |
ZFS_TIME_ENCODE(&vap->va_atime, pzp->zp_atime); |
|
821 |
} else { |
|
822 |
ZFS_TIME_ENCODE(&now, pzp->zp_atime); |
|
823 |
} |
|
824 |
||
825 |
if (vap->va_mask & AT_MTIME) { |
|
826 |
ZFS_TIME_ENCODE(&vap->va_mtime, pzp->zp_mtime); |
|
827 |
} else { |
|
828 |
ZFS_TIME_ENCODE(&now, pzp->zp_mtime); |
|
829 |
} |
|
10938
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
830 |
pzp->zp_uid = acl_ids->z_fuid; |
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
831 |
pzp->zp_gid = acl_ids->z_fgid; |
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
832 |
pzp->zp_mode = acl_ids->z_mode; |
5642
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
833 |
if (!(flag & IS_ROOT_NODE)) { |
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
834 |
*zpp = zfs_znode_alloc(zfsvfs, db, 0); |
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
835 |
} else { |
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
836 |
/* |
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
837 |
* If we are creating the root node, the "parent" we |
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
838 |
* passed in is the znode for the root. |
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
839 |
*/ |
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
840 |
*zpp = dzp; |
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
841 |
} |
9179
d8fbd96b79b3
6790064 zfs needs to determine uid and gid earlier in create process
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
9030
diff
changeset
|
842 |
VERIFY(0 == zfs_aclset_common(*zpp, acl_ids->z_aclp, cr, tx)); |
d8fbd96b79b3
6790064 zfs needs to determine uid and gid earlier in create process
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
9030
diff
changeset
|
843 |
if (vap->va_mask & AT_XVATTR) |
d8fbd96b79b3
6790064 zfs needs to determine uid and gid earlier in create process
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
9030
diff
changeset
|
844 |
zfs_xvattr_set(*zpp, (xvattr_t *)vap); |
10938
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
845 |
|
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
846 |
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj); |
789 | 847 |
} |
848 |
||
5331 | 849 |
void |
850 |
zfs_xvattr_set(znode_t *zp, xvattr_t *xvap) |
|
851 |
{ |
|
852 |
xoptattr_t *xoap; |
|
853 |
||
854 |
xoap = xva_getxoptattr(xvap); |
|
855 |
ASSERT(xoap); |
|
856 |
||
857 |
if (XVA_ISSET_REQ(xvap, XAT_CREATETIME)) { |
|
858 |
ZFS_TIME_ENCODE(&xoap->xoa_createtime, zp->z_phys->zp_crtime); |
|
859 |
XVA_SET_RTN(xvap, XAT_CREATETIME); |
|
860 |
} |
|
861 |
if (XVA_ISSET_REQ(xvap, XAT_READONLY)) { |
|
862 |
ZFS_ATTR_SET(zp, ZFS_READONLY, xoap->xoa_readonly); |
|
863 |
XVA_SET_RTN(xvap, XAT_READONLY); |
|
864 |
} |
|
865 |
if (XVA_ISSET_REQ(xvap, XAT_HIDDEN)) { |
|
866 |
ZFS_ATTR_SET(zp, ZFS_HIDDEN, xoap->xoa_hidden); |
|
867 |
XVA_SET_RTN(xvap, XAT_HIDDEN); |
|
868 |
} |
|
869 |
if (XVA_ISSET_REQ(xvap, XAT_SYSTEM)) { |
|
870 |
ZFS_ATTR_SET(zp, ZFS_SYSTEM, xoap->xoa_system); |
|
871 |
XVA_SET_RTN(xvap, XAT_SYSTEM); |
|
872 |
} |
|
873 |
if (XVA_ISSET_REQ(xvap, XAT_ARCHIVE)) { |
|
874 |
ZFS_ATTR_SET(zp, ZFS_ARCHIVE, xoap->xoa_archive); |
|
875 |
XVA_SET_RTN(xvap, XAT_ARCHIVE); |
|
876 |
} |
|
877 |
if (XVA_ISSET_REQ(xvap, XAT_IMMUTABLE)) { |
|
878 |
ZFS_ATTR_SET(zp, ZFS_IMMUTABLE, xoap->xoa_immutable); |
|
879 |
XVA_SET_RTN(xvap, XAT_IMMUTABLE); |
|
880 |
} |
|
881 |
if (XVA_ISSET_REQ(xvap, XAT_NOUNLINK)) { |
|
882 |
ZFS_ATTR_SET(zp, ZFS_NOUNLINK, xoap->xoa_nounlink); |
|
883 |
XVA_SET_RTN(xvap, XAT_NOUNLINK); |
|
884 |
} |
|
885 |
if (XVA_ISSET_REQ(xvap, XAT_APPENDONLY)) { |
|
886 |
ZFS_ATTR_SET(zp, ZFS_APPENDONLY, xoap->xoa_appendonly); |
|
887 |
XVA_SET_RTN(xvap, XAT_APPENDONLY); |
|
888 |
} |
|
889 |
if (XVA_ISSET_REQ(xvap, XAT_NODUMP)) { |
|
890 |
ZFS_ATTR_SET(zp, ZFS_NODUMP, xoap->xoa_nodump); |
|
891 |
XVA_SET_RTN(xvap, XAT_NODUMP); |
|
892 |
} |
|
893 |
if (XVA_ISSET_REQ(xvap, XAT_OPAQUE)) { |
|
894 |
ZFS_ATTR_SET(zp, ZFS_OPAQUE, xoap->xoa_opaque); |
|
895 |
XVA_SET_RTN(xvap, XAT_OPAQUE); |
|
896 |
} |
|
897 |
if (XVA_ISSET_REQ(xvap, XAT_AV_QUARANTINED)) { |
|
898 |
ZFS_ATTR_SET(zp, ZFS_AV_QUARANTINED, |
|
899 |
xoap->xoa_av_quarantined); |
|
900 |
XVA_SET_RTN(xvap, XAT_AV_QUARANTINED); |
|
901 |
} |
|
902 |
if (XVA_ISSET_REQ(xvap, XAT_AV_MODIFIED)) { |
|
903 |
ZFS_ATTR_SET(zp, ZFS_AV_MODIFIED, xoap->xoa_av_modified); |
|
904 |
XVA_SET_RTN(xvap, XAT_AV_MODIFIED); |
|
905 |
} |
|
906 |
if (XVA_ISSET_REQ(xvap, XAT_AV_SCANSTAMP)) { |
|
907 |
(void) memcpy(zp->z_phys + 1, xoap->xoa_av_scanstamp, |
|
908 |
sizeof (xoap->xoa_av_scanstamp)); |
|
909 |
zp->z_phys->zp_flags |= ZFS_BONUS_SCANSTAMP; |
|
910 |
XVA_SET_RTN(xvap, XAT_AV_SCANSTAMP); |
|
911 |
} |
|
10793
34709091de6d
6886081 Solaris needs reparse point support (PSARC 2009/387)
Dai Ngo <dai.ngo@sun.com>
parents:
10269
diff
changeset
|
912 |
if (XVA_ISSET_REQ(xvap, XAT_REPARSE)) { |
34709091de6d
6886081 Solaris needs reparse point support (PSARC 2009/387)
Dai Ngo <dai.ngo@sun.com>
parents:
10269
diff
changeset
|
913 |
ZFS_ATTR_SET(zp, ZFS_REPARSE, xoap->xoa_reparse); |
34709091de6d
6886081 Solaris needs reparse point support (PSARC 2009/387)
Dai Ngo <dai.ngo@sun.com>
parents:
10269
diff
changeset
|
914 |
XVA_SET_RTN(xvap, XAT_REPARSE); |
34709091de6d
6886081 Solaris needs reparse point support (PSARC 2009/387)
Dai Ngo <dai.ngo@sun.com>
parents:
10269
diff
changeset
|
915 |
} |
5331 | 916 |
} |
917 |
||
789 | 918 |
int |
919 |
zfs_zget(zfsvfs_t *zfsvfs, uint64_t obj_num, znode_t **zpp) |
|
920 |
{ |
|
921 |
dmu_object_info_t doi; |
|
922 |
dmu_buf_t *db; |
|
923 |
znode_t *zp; |
|
1544 | 924 |
int err; |
789 | 925 |
|
926 |
*zpp = NULL; |
|
927 |
||
928 |
ZFS_OBJ_HOLD_ENTER(zfsvfs, obj_num); |
|
929 |
||
1544 | 930 |
err = dmu_bonus_hold(zfsvfs->z_os, obj_num, NULL, &db); |
931 |
if (err) { |
|
789 | 932 |
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); |
1544 | 933 |
return (err); |
789 | 934 |
} |
935 |
||
936 |
dmu_object_info_from_db(db, &doi); |
|
937 |
if (doi.doi_bonus_type != DMU_OT_ZNODE || |
|
938 |
doi.doi_bonus_size < sizeof (znode_phys_t)) { |
|
1544 | 939 |
dmu_buf_rele(db, NULL); |
789 | 940 |
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); |
941 |
return (EINVAL); |
|
942 |
} |
|
943 |
||
944 |
zp = dmu_buf_get_user(db); |
|
945 |
if (zp != NULL) { |
|
946 |
mutex_enter(&zp->z_lock); |
|
947 |
||
5446 | 948 |
/* |
949 |
* Since we do immediate eviction of the z_dbuf, we |
|
950 |
* should never find a dbuf with a znode that doesn't |
|
951 |
* know about the dbuf. |
|
952 |
*/ |
|
953 |
ASSERT3P(zp->z_dbuf, ==, db); |
|
789 | 954 |
ASSERT3U(zp->z_id, ==, obj_num); |
3461 | 955 |
if (zp->z_unlinked) { |
5446 | 956 |
err = ENOENT; |
789 | 957 |
} else { |
5446 | 958 |
VN_HOLD(ZTOV(zp)); |
959 |
*zpp = zp; |
|
960 |
err = 0; |
|
789 | 961 |
} |
5446 | 962 |
dmu_buf_rele(db, NULL); |
789 | 963 |
mutex_exit(&zp->z_lock); |
1544 | 964 |
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); |
5446 | 965 |
return (err); |
789 | 966 |
} |
967 |
||
968 |
/* |
|
969 |
* Not found create new znode/vnode |
|
10938
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
970 |
* but only if file exists. |
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
971 |
* |
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
972 |
* There is a small window where zfs_vget() could |
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
973 |
* find this object while a file create is still in |
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
974 |
* progress. Since a gen number can never be zero |
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
975 |
* we will check that to determine if its an allocated |
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
976 |
* file. |
789 | 977 |
*/ |
10938
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
978 |
|
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
979 |
if (((znode_phys_t *)db->db_data)->zp_gen != 0) { |
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
980 |
zp = zfs_znode_alloc(zfsvfs, db, doi.doi_data_block_size); |
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
981 |
*zpp = zp; |
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
982 |
err = 0; |
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
983 |
} else { |
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
984 |
dmu_buf_rele(db, NULL); |
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
985 |
err = ENOENT; |
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
986 |
} |
1544 | 987 |
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); |
10938
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
988 |
return (err); |
789 | 989 |
} |
990 |
||
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
991 |
int |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
992 |
zfs_rezget(znode_t *zp) |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
993 |
{ |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
994 |
zfsvfs_t *zfsvfs = zp->z_zfsvfs; |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
995 |
dmu_object_info_t doi; |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
996 |
dmu_buf_t *db; |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
997 |
uint64_t obj_num = zp->z_id; |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
998 |
int err; |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
999 |
|
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1000 |
ZFS_OBJ_HOLD_ENTER(zfsvfs, obj_num); |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1001 |
|
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1002 |
err = dmu_bonus_hold(zfsvfs->z_os, obj_num, NULL, &db); |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1003 |
if (err) { |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1004 |
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1005 |
return (err); |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1006 |
} |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1007 |
|
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1008 |
dmu_object_info_from_db(db, &doi); |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1009 |
if (doi.doi_bonus_type != DMU_OT_ZNODE || |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1010 |
doi.doi_bonus_size < sizeof (znode_phys_t)) { |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1011 |
dmu_buf_rele(db, NULL); |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1012 |
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1013 |
return (EINVAL); |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1014 |
} |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1015 |
|
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1016 |
if (((znode_phys_t *)db->db_data)->zp_gen != zp->z_gen) { |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1017 |
dmu_buf_rele(db, NULL); |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1018 |
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1019 |
return (EIO); |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1020 |
} |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1021 |
|
10269
2788675568fd
6868276 zfs_rezget() can be hazardous when znode has a cached ACL
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10250
diff
changeset
|
1022 |
mutex_enter(&zp->z_acl_lock); |
2788675568fd
6868276 zfs_rezget() can be hazardous when znode has a cached ACL
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10250
diff
changeset
|
1023 |
if (zp->z_acl_cached) { |
2788675568fd
6868276 zfs_rezget() can be hazardous when znode has a cached ACL
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10250
diff
changeset
|
1024 |
zfs_acl_free(zp->z_acl_cached); |
2788675568fd
6868276 zfs_rezget() can be hazardous when znode has a cached ACL
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10250
diff
changeset
|
1025 |
zp->z_acl_cached = NULL; |
2788675568fd
6868276 zfs_rezget() can be hazardous when znode has a cached ACL
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10250
diff
changeset
|
1026 |
} |
2788675568fd
6868276 zfs_rezget() can be hazardous when znode has a cached ACL
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10250
diff
changeset
|
1027 |
mutex_exit(&zp->z_acl_lock); |
2788675568fd
6868276 zfs_rezget() can be hazardous when znode has a cached ACL
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10250
diff
changeset
|
1028 |
|
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
1029 |
zfs_znode_dmu_init(zfsvfs, zp, db); |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1030 |
zp->z_unlinked = (zp->z_phys->zp_links == 0); |
5844
51eed00be2b0
6649002 panic "accessing past end of object" after online recv/rollback
ek110237
parents:
5745
diff
changeset
|
1031 |
zp->z_blksz = doi.doi_data_block_size; |
5326
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1032 |
|
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1033 |
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1034 |
|
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1035 |
return (0); |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1036 |
} |
6752aa2bd5bc
6425096 want online 'zfs recv' (read only and read/write)
ek110237
parents:
4831
diff
changeset
|
1037 |
|
789 | 1038 |
void |
1039 |
zfs_znode_delete(znode_t *zp, dmu_tx_t *tx) |
|
1040 |
{ |
|
1041 |
zfsvfs_t *zfsvfs = zp->z_zfsvfs; |
|
6992 | 1042 |
objset_t *os = zfsvfs->z_os; |
5446 | 1043 |
uint64_t obj = zp->z_id; |
6992 | 1044 |
uint64_t acl_obj = zp->z_phys->zp_acl.z_acl_extern_obj; |
789 | 1045 |
|
5446 | 1046 |
ZFS_OBJ_HOLD_ENTER(zfsvfs, obj); |
6992 | 1047 |
if (acl_obj) |
1048 |
VERIFY(0 == dmu_object_free(os, acl_obj, tx)); |
|
1049 |
VERIFY(0 == dmu_object_free(os, obj, tx)); |
|
5446 | 1050 |
zfs_znode_dmu_fini(zp); |
1051 |
ZFS_OBJ_HOLD_EXIT(zfsvfs, obj); |
|
5642
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
1052 |
zfs_znode_free(zp); |
789 | 1053 |
} |
1054 |
||
1055 |
void |
|
1056 |
zfs_zinactive(znode_t *zp) |
|
1057 |
{ |
|
1058 |
vnode_t *vp = ZTOV(zp); |
|
1059 |
zfsvfs_t *zfsvfs = zp->z_zfsvfs; |
|
1060 |
uint64_t z_id = zp->z_id; |
|
1061 |
||
5446 | 1062 |
ASSERT(zp->z_dbuf && zp->z_phys); |
789 | 1063 |
|
1064 |
/* |
|
1065 |
* Don't allow a zfs_zget() while were trying to release this znode |
|
1066 |
*/ |
|
1067 |
ZFS_OBJ_HOLD_ENTER(zfsvfs, z_id); |
|
1068 |
||
1069 |
mutex_enter(&zp->z_lock); |
|
1070 |
mutex_enter(&vp->v_lock); |
|
1071 |
vp->v_count--; |
|
1072 |
if (vp->v_count > 0 || vn_has_cached_data(vp)) { |
|
1073 |
/* |
|
1074 |
* If the hold count is greater than zero, somebody has |
|
1075 |
* obtained a new reference on this znode while we were |
|
1076 |
* processing it here, so we are done. If we still have |
|
1077 |
* mapped pages then we are also done, since we don't |
|
1078 |
* want to inactivate the znode until the pages get pushed. |
|
1079 |
* |
|
1080 |
* XXX - if vn_has_cached_data(vp) is true, but count == 0, |
|
1081 |
* this seems like it would leave the znode hanging with |
|
1082 |
* no chance to go inactive... |
|
1083 |
*/ |
|
1084 |
mutex_exit(&vp->v_lock); |
|
1085 |
mutex_exit(&zp->z_lock); |
|
1086 |
ZFS_OBJ_HOLD_EXIT(zfsvfs, z_id); |
|
1087 |
return; |
|
1088 |
} |
|
1089 |
mutex_exit(&vp->v_lock); |
|
1090 |
||
1091 |
/* |
|
1092 |
* If this was the last reference to a file with no links, |
|
1093 |
* remove the file from the file system. |
|
1094 |
*/ |
|
3461 | 1095 |
if (zp->z_unlinked) { |
789 | 1096 |
mutex_exit(&zp->z_lock); |
1097 |
ZFS_OBJ_HOLD_EXIT(zfsvfs, z_id); |
|
3461 | 1098 |
zfs_rmnode(zp); |
789 | 1099 |
return; |
1100 |
} |
|
1101 |
mutex_exit(&zp->z_lock); |
|
5446 | 1102 |
zfs_znode_dmu_fini(zp); |
789 | 1103 |
ZFS_OBJ_HOLD_EXIT(zfsvfs, z_id); |
5642
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
1104 |
zfs_znode_free(zp); |
789 | 1105 |
} |
1106 |
||
1107 |
void |
|
1108 |
zfs_znode_free(znode_t *zp) |
|
1109 |
{ |
|
1110 |
zfsvfs_t *zfsvfs = zp->z_zfsvfs; |
|
1111 |
||
5642
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
1112 |
vn_invalid(ZTOV(zp)); |
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
1113 |
|
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
1114 |
ASSERT(ZTOV(zp)->v_count == 0); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
1115 |
|
789 | 1116 |
mutex_enter(&zfsvfs->z_znodes_lock); |
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
1117 |
POINTER_INVALIDATE(&zp->z_zfsvfs); |
789 | 1118 |
list_remove(&zfsvfs->z_all_znodes, zp); |
1119 |
mutex_exit(&zfsvfs->z_znodes_lock); |
|
1120 |
||
9981
b4907297e740
6775100 stat() performance on files on zfs should be improved
Tim Haley <Tim.Haley@Sun.COM>
parents:
9788
diff
changeset
|
1121 |
if (zp->z_acl_cached) { |
b4907297e740
6775100 stat() performance on files on zfs should be improved
Tim Haley <Tim.Haley@Sun.COM>
parents:
9788
diff
changeset
|
1122 |
zfs_acl_free(zp->z_acl_cached); |
b4907297e740
6775100 stat() performance on files on zfs should be improved
Tim Haley <Tim.Haley@Sun.COM>
parents:
9788
diff
changeset
|
1123 |
zp->z_acl_cached = NULL; |
b4907297e740
6775100 stat() performance on files on zfs should be improved
Tim Haley <Tim.Haley@Sun.COM>
parents:
9788
diff
changeset
|
1124 |
} |
b4907297e740
6775100 stat() performance on files on zfs should be improved
Tim Haley <Tim.Haley@Sun.COM>
parents:
9788
diff
changeset
|
1125 |
|
789 | 1126 |
kmem_cache_free(znode_cache, zp); |
5642
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
1127 |
|
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
1128 |
VFS_RELE(zfsvfs->z_vfs); |
789 | 1129 |
} |
1130 |
||
1131 |
void |
|
1132 |
zfs_time_stamper_locked(znode_t *zp, uint_t flag, dmu_tx_t *tx) |
|
1133 |
{ |
|
1134 |
timestruc_t now; |
|
1135 |
||
1136 |
ASSERT(MUTEX_HELD(&zp->z_lock)); |
|
1137 |
||
1138 |
gethrestime(&now); |
|
1139 |
||
1140 |
if (tx) { |
|
1141 |
dmu_buf_will_dirty(zp->z_dbuf, tx); |
|
1142 |
zp->z_atime_dirty = 0; |
|
1143 |
zp->z_seq++; |
|
1144 |
} else { |
|
1145 |
zp->z_atime_dirty = 1; |
|
1146 |
} |
|
1147 |
||
1148 |
if (flag & AT_ATIME) |
|
1149 |
ZFS_TIME_ENCODE(&now, zp->z_phys->zp_atime); |
|
1150 |
||
5331 | 1151 |
if (flag & AT_MTIME) { |
789 | 1152 |
ZFS_TIME_ENCODE(&now, zp->z_phys->zp_mtime); |
5331 | 1153 |
if (zp->z_zfsvfs->z_use_fuids) |
1154 |
zp->z_phys->zp_flags |= (ZFS_ARCHIVE | ZFS_AV_MODIFIED); |
|
1155 |
} |
|
789 | 1156 |
|
5331 | 1157 |
if (flag & AT_CTIME) { |
789 | 1158 |
ZFS_TIME_ENCODE(&now, zp->z_phys->zp_ctime); |
5331 | 1159 |
if (zp->z_zfsvfs->z_use_fuids) |
1160 |
zp->z_phys->zp_flags |= ZFS_ARCHIVE; |
|
1161 |
} |
|
789 | 1162 |
} |
1163 |
||
1164 |
/* |
|
1165 |
* Update the requested znode timestamps with the current time. |
|
1166 |
* If we are in a transaction, then go ahead and mark the znode |
|
1167 |
* dirty in the transaction so the timestamps will go to disk. |
|
1168 |
* Otherwise, we will get pushed next time the znode is updated |
|
1169 |
* in a transaction, or when this znode eventually goes inactive. |
|
1170 |
* |
|
1171 |
* Why is this OK? |
|
1172 |
* 1 - Only the ACCESS time is ever updated outside of a transaction. |
|
1173 |
* 2 - Multiple consecutive updates will be collapsed into a single |
|
1174 |
* znode update by the transaction grouping semantics of the DMU. |
|
1175 |
*/ |
|
1176 |
void |
|
1177 |
zfs_time_stamper(znode_t *zp, uint_t flag, dmu_tx_t *tx) |
|
1178 |
{ |
|
1179 |
mutex_enter(&zp->z_lock); |
|
1180 |
zfs_time_stamper_locked(zp, flag, tx); |
|
1181 |
mutex_exit(&zp->z_lock); |
|
1182 |
} |
|
1183 |
||
1184 |
/* |
|
1669 | 1185 |
* Grow the block size for a file. |
789 | 1186 |
* |
1187 |
* IN: zp - znode of file to free data in. |
|
1188 |
* size - requested block size |
|
1189 |
* tx - open transaction. |
|
1190 |
* |
|
1191 |
* NOTE: this function assumes that the znode is write locked. |
|
1192 |
*/ |
|
1669 | 1193 |
void |
789 | 1194 |
zfs_grow_blocksize(znode_t *zp, uint64_t size, dmu_tx_t *tx) |
1195 |
{ |
|
1196 |
int error; |
|
1197 |
u_longlong_t dummy; |
|
1198 |
||
1199 |
if (size <= zp->z_blksz) |
|
1669 | 1200 |
return; |
789 | 1201 |
/* |
1202 |
* If the file size is already greater than the current blocksize, |
|
1203 |
* we will not grow. If there is more than one block in a file, |
|
1204 |
* the blocksize cannot change. |
|
1205 |
*/ |
|
1206 |
if (zp->z_blksz && zp->z_phys->zp_size > zp->z_blksz) |
|
1669 | 1207 |
return; |
789 | 1208 |
|
1209 |
error = dmu_object_set_blocksize(zp->z_zfsvfs->z_os, zp->z_id, |
|
1210 |
size, 0, tx); |
|
1211 |
if (error == ENOTSUP) |
|
1669 | 1212 |
return; |
789 | 1213 |
ASSERT3U(error, ==, 0); |
1214 |
||
1215 |
/* What blocksize did we actually get? */ |
|
1216 |
dmu_object_size_from_db(zp->z_dbuf, &zp->z_blksz, &dummy); |
|
1217 |
} |
|
1218 |
||
1219 |
/* |
|
1220 |
* This is a dummy interface used when pvn_vplist_dirty() should *not* |
|
1221 |
* be calling back into the fs for a putpage(). E.g.: when truncating |
|
1222 |
* a file, the pages being "thrown away* don't need to be written out. |
|
1223 |
*/ |
|
1224 |
/* ARGSUSED */ |
|
1225 |
static int |
|
1226 |
zfs_no_putpage(vnode_t *vp, page_t *pp, u_offset_t *offp, size_t *lenp, |
|
1227 |
int flags, cred_t *cr) |
|
1228 |
{ |
|
1229 |
ASSERT(0); |
|
1230 |
return (0); |
|
1231 |
} |
|
1232 |
||
1233 |
/* |
|
6992 | 1234 |
* Increase the file length |
789 | 1235 |
* |
1236 |
* IN: zp - znode of file to free data in. |
|
6992 | 1237 |
* end - new end-of-file |
789 | 1238 |
* |
1239 |
* RETURN: 0 if success |
|
1240 |
* error code if failure |
|
1241 |
*/ |
|
6992 | 1242 |
static int |
1243 |
zfs_extend(znode_t *zp, uint64_t end) |
|
789 | 1244 |
{ |
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1245 |
zfsvfs_t *zfsvfs = zp->z_zfsvfs; |
6992 | 1246 |
dmu_tx_t *tx; |
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1247 |
rl_t *rl; |
6992 | 1248 |
uint64_t newblksz; |
1669 | 1249 |
int error; |
789 | 1250 |
|
1251 |
/* |
|
6992 | 1252 |
* We will change zp_size, lock the whole file. |
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1253 |
*/ |
6992 | 1254 |
rl = zfs_range_lock(zp, 0, UINT64_MAX, RL_WRITER); |
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1255 |
|
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1256 |
/* |
789 | 1257 |
* Nothing to do if file already at desired length. |
1258 |
*/ |
|
6992 | 1259 |
if (end <= zp->z_phys->zp_size) { |
2237 | 1260 |
zfs_range_unlock(rl); |
789 | 1261 |
return (0); |
1262 |
} |
|
6992 | 1263 |
top: |
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1264 |
tx = dmu_tx_create(zfsvfs->z_os); |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1265 |
dmu_tx_hold_bonus(tx, zp->z_id); |
6992 | 1266 |
if (end > zp->z_blksz && |
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1267 |
(!ISP2(zp->z_blksz) || zp->z_blksz < zfsvfs->z_max_blksz)) { |
789 | 1268 |
/* |
1269 |
* We are growing the file past the current block size. |
|
1270 |
*/ |
|
1271 |
if (zp->z_blksz > zp->z_zfsvfs->z_max_blksz) { |
|
1272 |
ASSERT(!ISP2(zp->z_blksz)); |
|
6992 | 1273 |
newblksz = MIN(end, SPA_MAXBLOCKSIZE); |
789 | 1274 |
} else { |
6992 | 1275 |
newblksz = MIN(end, zp->z_zfsvfs->z_max_blksz); |
789 | 1276 |
} |
6992 | 1277 |
dmu_tx_hold_write(tx, zp->z_id, 0, newblksz); |
1278 |
} else { |
|
1279 |
newblksz = 0; |
|
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1280 |
} |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1281 |
|
8227 | 1282 |
error = dmu_tx_assign(tx, TXG_NOWAIT); |
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1283 |
if (error) { |
8227 | 1284 |
if (error == ERESTART) { |
2113
0510bb40c993
6430121 3-way deadlock involving tc_lock within zfs
ahrens
parents:
1936
diff
changeset
|
1285 |
dmu_tx_wait(tx); |
6992 | 1286 |
dmu_tx_abort(tx); |
1287 |
goto top; |
|
1288 |
} |
|
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1289 |
dmu_tx_abort(tx); |
2237 | 1290 |
zfs_range_unlock(rl); |
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1291 |
return (error); |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1292 |
} |
6992 | 1293 |
dmu_buf_will_dirty(zp->z_dbuf, tx); |
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1294 |
|
6992 | 1295 |
if (newblksz) |
1296 |
zfs_grow_blocksize(zp, newblksz, tx); |
|
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1297 |
|
6992 | 1298 |
zp->z_phys->zp_size = end; |
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1299 |
|
2237 | 1300 |
zfs_range_unlock(rl); |
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1301 |
|
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1302 |
dmu_tx_commit(tx); |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1303 |
|
6992 | 1304 |
return (0); |
1305 |
} |
|
1306 |
||
1307 |
/* |
|
1308 |
* Free space in a file. |
|
1309 |
* |
|
1310 |
* IN: zp - znode of file to free data in. |
|
1311 |
* off - start of section to free. |
|
1312 |
* len - length of section to free. |
|
1313 |
* |
|
1314 |
* RETURN: 0 if success |
|
1315 |
* error code if failure |
|
1316 |
*/ |
|
1317 |
static int |
|
1318 |
zfs_free_range(znode_t *zp, uint64_t off, uint64_t len) |
|
1319 |
{ |
|
1320 |
zfsvfs_t *zfsvfs = zp->z_zfsvfs; |
|
1321 |
rl_t *rl; |
|
1322 |
int error; |
|
1323 |
||
1324 |
/* |
|
1325 |
* Lock the range being freed. |
|
1326 |
*/ |
|
1327 |
rl = zfs_range_lock(zp, off, len, RL_WRITER); |
|
1328 |
||
1329 |
/* |
|
1330 |
* Nothing to do if file already at desired length. |
|
1331 |
*/ |
|
1332 |
if (off >= zp->z_phys->zp_size) { |
|
1333 |
zfs_range_unlock(rl); |
|
1334 |
return (0); |
|
1335 |
} |
|
1336 |
||
1337 |
if (off + len > zp->z_phys->zp_size) |
|
1338 |
len = zp->z_phys->zp_size - off; |
|
1339 |
||
1340 |
error = dmu_free_long_range(zfsvfs->z_os, zp->z_id, off, len); |
|
1341 |
||
1342 |
zfs_range_unlock(rl); |
|
1343 |
||
1344 |
return (error); |
|
1345 |
} |
|
1346 |
||
1347 |
/* |
|
1348 |
* Truncate a file |
|
1349 |
* |
|
1350 |
* IN: zp - znode of file to free data in. |
|
1351 |
* end - new end-of-file. |
|
1352 |
* |
|
1353 |
* RETURN: 0 if success |
|
1354 |
* error code if failure |
|
1355 |
*/ |
|
1356 |
static int |
|
1357 |
zfs_trunc(znode_t *zp, uint64_t end) |
|
1358 |
{ |
|
1359 |
zfsvfs_t *zfsvfs = zp->z_zfsvfs; |
|
1360 |
vnode_t *vp = ZTOV(zp); |
|
1361 |
dmu_tx_t *tx; |
|
1362 |
rl_t *rl; |
|
1363 |
int error; |
|
1364 |
||
1365 |
/* |
|
1366 |
* We will change zp_size, lock the whole file. |
|
1367 |
*/ |
|
1368 |
rl = zfs_range_lock(zp, 0, UINT64_MAX, RL_WRITER); |
|
1369 |
||
1370 |
/* |
|
1371 |
* Nothing to do if file already at desired length. |
|
1372 |
*/ |
|
1373 |
if (end >= zp->z_phys->zp_size) { |
|
1374 |
zfs_range_unlock(rl); |
|
1375 |
return (0); |
|
1376 |
} |
|
1377 |
||
1378 |
error = dmu_free_long_range(zfsvfs->z_os, zp->z_id, end, -1); |
|
1379 |
if (error) { |
|
1380 |
zfs_range_unlock(rl); |
|
1381 |
return (error); |
|
1382 |
} |
|
1383 |
top: |
|
1384 |
tx = dmu_tx_create(zfsvfs->z_os); |
|
1385 |
dmu_tx_hold_bonus(tx, zp->z_id); |
|
8227 | 1386 |
error = dmu_tx_assign(tx, TXG_NOWAIT); |
6992 | 1387 |
if (error) { |
8227 | 1388 |
if (error == ERESTART) { |
6992 | 1389 |
dmu_tx_wait(tx); |
1390 |
dmu_tx_abort(tx); |
|
1391 |
goto top; |
|
1392 |
} |
|
1393 |
dmu_tx_abort(tx); |
|
1394 |
zfs_range_unlock(rl); |
|
1395 |
return (error); |
|
1396 |
} |
|
1397 |
dmu_buf_will_dirty(zp->z_dbuf, tx); |
|
1398 |
||
1399 |
zp->z_phys->zp_size = end; |
|
1400 |
||
1401 |
dmu_tx_commit(tx); |
|
1402 |
||
789 | 1403 |
/* |
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1404 |
* Clear any mapped pages in the truncated region. This has to |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1405 |
* happen outside of the transaction to avoid the possibility of |
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1406 |
* 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
|
1407 |
* about to invalidate. |
789 | 1408 |
*/ |
6992 | 1409 |
if (vn_has_cached_data(vp)) { |
789 | 1410 |
page_t *pp; |
6992 | 1411 |
uint64_t start = end & PAGEMASK; |
1412 |
int poff = end & PAGEOFFSET; |
|
789 | 1413 |
|
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1414 |
if (poff != 0 && (pp = page_lookup(vp, start, SE_SHARED))) { |
789 | 1415 |
/* |
1416 |
* We need to zero a partial page. |
|
1417 |
*/ |
|
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1418 |
pagezero(pp, poff, PAGESIZE - poff); |
789 | 1419 |
start += PAGESIZE; |
1420 |
page_unlock(pp); |
|
1421 |
} |
|
1422 |
error = pvn_vplist_dirty(vp, start, zfs_no_putpage, |
|
1878
c22df0f5603f
6413573 deadlock between fsflush() and zfs_create()
maybee
parents:
1816
diff
changeset
|
1423 |
B_INVAL | B_TRUNC, NULL); |
789 | 1424 |
ASSERT(error == 0); |
1425 |
} |
|
8636
7e4ce9158df3
6551866 deadlock between zfs_write(), zfs_freesp(), and zfs_putapage()
Mark Maybee <Mark.Maybee@Sun.COM>
parents:
8227
diff
changeset
|
1426 |
|
7e4ce9158df3
6551866 deadlock between zfs_write(), zfs_freesp(), and zfs_putapage()
Mark Maybee <Mark.Maybee@Sun.COM>
parents:
8227
diff
changeset
|
1427 |
zfs_range_unlock(rl); |
789 | 1428 |
|
1429 |
return (0); |
|
1430 |
} |
|
1431 |
||
6992 | 1432 |
/* |
1433 |
* Free space in a file |
|
1434 |
* |
|
1435 |
* IN: zp - znode of file to free data in. |
|
1436 |
* off - start of range |
|
1437 |
* len - end of range (0 => EOF) |
|
1438 |
* flag - current file open mode flags. |
|
1439 |
* log - TRUE if this action should be logged |
|
1440 |
* |
|
1441 |
* RETURN: 0 if success |
|
1442 |
* error code if failure |
|
1443 |
*/ |
|
1444 |
int |
|
1445 |
zfs_freesp(znode_t *zp, uint64_t off, uint64_t len, int flag, boolean_t log) |
|
1446 |
{ |
|
1447 |
vnode_t *vp = ZTOV(zp); |
|
1448 |
dmu_tx_t *tx; |
|
1449 |
zfsvfs_t *zfsvfs = zp->z_zfsvfs; |
|
1450 |
zilog_t *zilog = zfsvfs->z_log; |
|
1451 |
int error; |
|
1452 |
||
1453 |
if (off > zp->z_phys->zp_size) { |
|
1454 |
error = zfs_extend(zp, off+len); |
|
1455 |
if (error == 0 && log) |
|
1456 |
goto log; |
|
1457 |
else |
|
1458 |
return (error); |
|
1459 |
} |
|
1460 |
||
1461 |
/* |
|
1462 |
* Check for any locks in the region to be freed. |
|
1463 |
*/ |
|
1464 |
if (MANDLOCK(vp, (mode_t)zp->z_phys->zp_mode)) { |
|
1465 |
uint64_t length = (len ? len : zp->z_phys->zp_size - off); |
|
1466 |
if (error = chklock(vp, FWRITE, off, length, flag, NULL)) |
|
1467 |
return (error); |
|
1468 |
} |
|
1469 |
||
1470 |
if (len == 0) { |
|
1471 |
error = zfs_trunc(zp, off); |
|
1472 |
} else { |
|
1473 |
if ((error = zfs_free_range(zp, off, len)) == 0 && |
|
1474 |
off + len > zp->z_phys->zp_size) |
|
1475 |
error = zfs_extend(zp, off+len); |
|
1476 |
} |
|
1477 |
if (error || !log) |
|
1478 |
return (error); |
|
1479 |
log: |
|
1480 |
tx = dmu_tx_create(zfsvfs->z_os); |
|
1481 |
dmu_tx_hold_bonus(tx, zp->z_id); |
|
8227 | 1482 |
error = dmu_tx_assign(tx, TXG_NOWAIT); |
6992 | 1483 |
if (error) { |
8227 | 1484 |
if (error == ERESTART) { |
6992 | 1485 |
dmu_tx_wait(tx); |
1486 |
dmu_tx_abort(tx); |
|
1487 |
goto log; |
|
1488 |
} |
|
1489 |
dmu_tx_abort(tx); |
|
1490 |
return (error); |
|
1491 |
} |
|
1492 |
||
1493 |
zfs_time_stamper(zp, CONTENT_MODIFIED, tx); |
|
1494 |
zfs_log_truncate(zilog, tx, TX_TRUNCATE, zp, off, len); |
|
1495 |
||
1496 |
dmu_tx_commit(tx); |
|
1497 |
return (0); |
|
1498 |
} |
|
1499 |
||
789 | 1500 |
void |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1501 |
zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplprops, dmu_tx_t *tx) |
789 | 1502 |
{ |
1503 |
zfsvfs_t zfsvfs; |
|
9396
f41cf682d0d3
PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
9179
diff
changeset
|
1504 |
uint64_t moid, obj, version; |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1505 |
uint64_t sense = ZFS_CASE_SENSITIVE; |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1506 |
uint64_t norm = 0; |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1507 |
nvpair_t *elem; |
789 | 1508 |
int error; |
10938
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
1509 |
int i; |
789 | 1510 |
znode_t *rootzp = NULL; |
1511 |
vnode_t *vp; |
|
1512 |
vattr_t vattr; |
|
5446 | 1513 |
znode_t *zp; |
9179
d8fbd96b79b3
6790064 zfs needs to determine uid and gid earlier in create process
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
9030
diff
changeset
|
1514 |
zfs_acl_ids_t acl_ids; |
789 | 1515 |
|
1516 |
/* |
|
1517 |
* First attempt to create master node. |
|
1518 |
*/ |
|
1544 | 1519 |
/* |
1520 |
* In an empty objset, there are no blocks to read and thus |
|
1521 |
* there can be no i/o errors (which we assert below). |
|
1522 |
*/ |
|
789 | 1523 |
moid = MASTER_NODE_OBJ; |
1524 |
error = zap_create_claim(os, moid, DMU_OT_MASTER_NODE, |
|
1525 |
DMU_OT_NONE, 0, tx); |
|
1526 |
ASSERT(error == 0); |
|
1527 |
||
1528 |
/* |
|
1529 |
* Set starting attributes. |
|
1530 |
*/ |
|
9396
f41cf682d0d3
PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
9179
diff
changeset
|
1531 |
if (spa_version(dmu_objset_spa(os)) >= SPA_VERSION_USERSPACE) |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1532 |
version = ZPL_VERSION; |
9396
f41cf682d0d3
PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
9179
diff
changeset
|
1533 |
else if (spa_version(dmu_objset_spa(os)) >= SPA_VERSION_FUID) |
f41cf682d0d3
PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
9179
diff
changeset
|
1534 |
version = ZPL_VERSION_USERSPACE - 1; |
7046
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1535 |
else |
361307ae060d
6343667 scrub/resilver has to start over when a snapshot is taken
ahrens
parents:
6992
diff
changeset
|
1536 |
version = ZPL_VERSION_FUID - 1; |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1537 |
elem = NULL; |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1538 |
while ((elem = nvlist_next_nvpair(zplprops, elem)) != NULL) { |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1539 |
/* For the moment we expect all zpl props to be uint64_ts */ |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1540 |
uint64_t val; |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1541 |
char *name; |
789 | 1542 |
|
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1543 |
ASSERT(nvpair_type(elem) == DATA_TYPE_UINT64); |
5520
70184f49637e
6633610 cannot successfully 'zpool create' on non-debug bits after 6622831
timh
parents:
5498
diff
changeset
|
1544 |
VERIFY(nvpair_value_uint64(elem, &val) == 0); |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1545 |
name = nvpair_name(elem); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1546 |
if (strcmp(name, zfs_prop_to_name(ZFS_PROP_VERSION)) == 0) { |
9396
f41cf682d0d3
PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
9179
diff
changeset
|
1547 |
if (val < version) |
f41cf682d0d3
PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
9179
diff
changeset
|
1548 |
version = val; |
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1549 |
} else { |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1550 |
error = zap_update(os, moid, name, 8, 1, &val, tx); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1551 |
} |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1552 |
ASSERT(error == 0); |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1553 |
if (strcmp(name, zfs_prop_to_name(ZFS_PROP_NORMALIZE)) == 0) |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1554 |
norm = val; |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1555 |
else if (strcmp(name, zfs_prop_to_name(ZFS_PROP_CASE)) == 0) |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1556 |
sense = val; |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1557 |
} |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1558 |
ASSERT(version != 0); |
9396
f41cf682d0d3
PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
9179
diff
changeset
|
1559 |
error = zap_update(os, moid, ZPL_VERSION_STR, 8, 1, &version, tx); |
789 | 1560 |
|
1561 |
/* |
|
1562 |
* Create a delete queue. |
|
1563 |
*/ |
|
9396
f41cf682d0d3
PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
9179
diff
changeset
|
1564 |
obj = zap_create(os, DMU_OT_UNLINKED_SET, DMU_OT_NONE, 0, tx); |
789 | 1565 |
|
9396
f41cf682d0d3
PSARC/2009/204 ZFS user/group quotas & space accounting
Matthew Ahrens <Matthew.Ahrens@Sun.COM>
parents:
9179
diff
changeset
|
1566 |
error = zap_add(os, moid, ZFS_UNLINKED_SET, 8, 1, &obj, tx); |
789 | 1567 |
ASSERT(error == 0); |
1568 |
||
1569 |
/* |
|
1570 |
* Create root znode. Create minimal znode/vnode/zfsvfs |
|
1571 |
* to allow zfs_mknode to work. |
|
1572 |
*/ |
|
1573 |
vattr.va_mask = AT_MODE|AT_UID|AT_GID|AT_TYPE; |
|
1574 |
vattr.va_type = VDIR; |
|
1575 |
vattr.va_mode = S_IFDIR|0755; |
|
4543 | 1576 |
vattr.va_uid = crgetuid(cr); |
1577 |
vattr.va_gid = crgetgid(cr); |
|
789 | 1578 |
|
1579 |
rootzp = kmem_cache_alloc(znode_cache, KM_SLEEP); |
|
3461 | 1580 |
rootzp->z_unlinked = 0; |
789 | 1581 |
rootzp->z_atime_dirty = 0; |
1582 |
||
1583 |
vp = ZTOV(rootzp); |
|
1584 |
vn_reinit(vp); |
|
1585 |
vp->v_type = VDIR; |
|
1586 |
||
1587 |
bzero(&zfsvfs, sizeof (zfsvfs_t)); |
|
1588 |
||
1589 |
zfsvfs.z_os = os; |
|
1590 |
zfsvfs.z_parent = &zfsvfs; |
|
5331 | 1591 |
zfsvfs.z_version = version; |
1592 |
zfsvfs.z_use_fuids = USE_FUIDS(version, os); |
|
1593 |
zfsvfs.z_norm = norm; |
|
5498
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1594 |
/* |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1595 |
* Fold case on file systems that are always or sometimes case |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1596 |
* insensitive. |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1597 |
*/ |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1598 |
if (sense == ZFS_CASE_INSENSITIVE || sense == ZFS_CASE_MIXED) |
334b476844ca
6622831 normalization properties are not preserved by "zfs send"
timh
parents:
5446
diff
changeset
|
1599 |
zfsvfs.z_norm |= U8_TEXTPREP_TOUPPER; |
789 | 1600 |
|
1601 |
mutex_init(&zfsvfs.z_znodes_lock, NULL, MUTEX_DEFAULT, NULL); |
|
1602 |
list_create(&zfsvfs.z_all_znodes, sizeof (znode_t), |
|
1603 |
offsetof(znode_t, z_link_node)); |
|
1604 |
||
10938
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
1605 |
for (i = 0; i != ZFS_OBJ_MTX_SZ; i++) |
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
1606 |
mutex_init(&zfsvfs.z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL); |
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
1607 |
|
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
1608 |
ASSERT(!POINTER_IS_VALID(rootzp->z_zfsvfs)); |
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
1609 |
rootzp->z_zfsvfs = &zfsvfs; |
9179
d8fbd96b79b3
6790064 zfs needs to determine uid and gid earlier in create process
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
9030
diff
changeset
|
1610 |
VERIFY(0 == zfs_acl_ids_create(rootzp, IS_ROOT_NODE, &vattr, |
d8fbd96b79b3
6790064 zfs needs to determine uid and gid earlier in create process
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
9030
diff
changeset
|
1611 |
cr, NULL, &acl_ids)); |
d8fbd96b79b3
6790064 zfs needs to determine uid and gid earlier in create process
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
9030
diff
changeset
|
1612 |
zfs_mknode(rootzp, &vattr, tx, cr, IS_ROOT_NODE, &zp, 0, &acl_ids); |
5642
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
1613 |
ASSERT3P(zp, ==, rootzp); |
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
1614 |
ASSERT(!vn_in_dnlc(ZTOV(rootzp))); /* not valid to move */ |
5446 | 1615 |
error = zap_add(os, moid, ZFS_ROOT_OBJ, 8, 1, &rootzp->z_id, tx); |
789 | 1616 |
ASSERT(error == 0); |
9179
d8fbd96b79b3
6790064 zfs needs to determine uid and gid earlier in create process
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
9030
diff
changeset
|
1617 |
zfs_acl_ids_free(&acl_ids); |
6712
79afecec3f3c
6554564 slab allocator cannot release slabs with lonely buffers
tomee
parents:
6492
diff
changeset
|
1618 |
POINTER_INVALIDATE(&rootzp->z_zfsvfs); |
789 | 1619 |
|
1620 |
ZTOV(rootzp)->v_count = 0; |
|
5642
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
1621 |
dmu_buf_rele(rootzp->z_dbuf, NULL); |
504c84876fda
6513209 Destroying pools under stress caused a hang in arc_flush
maybee
parents:
5520
diff
changeset
|
1622 |
rootzp->z_dbuf = NULL; |
789 | 1623 |
kmem_cache_free(znode_cache, rootzp); |
8845
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
1624 |
|
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
1625 |
/* |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
1626 |
* Create shares directory |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
1627 |
*/ |
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
1628 |
|
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
1629 |
error = zfs_create_share_dir(&zfsvfs, tx); |
9179
d8fbd96b79b3
6790064 zfs needs to determine uid and gid earlier in create process
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
9030
diff
changeset
|
1630 |
|
8845
91af0d9c0790
6800942 smb_session_create() incorrectly stores IP addresses
Alan Wright <amw@Sun.COM>
parents:
8636
diff
changeset
|
1631 |
ASSERT(error == 0); |
10938
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
1632 |
|
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
1633 |
for (i = 0; i != ZFS_OBJ_MTX_SZ; i++) |
270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
Mark Shellenbaum <Mark.Shellenbaum@Sun.COM>
parents:
10793
diff
changeset
|
1634 |
mutex_destroy(&zfsvfs.z_hold_mtx[i]); |
789 | 1635 |
} |
5331 | 1636 |
|
3444
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1637 |
#endif /* _KERNEL */ |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1638 |
/* |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1639 |
* Given an object number, return its parent object number and whether |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1640 |
* or not the object is an extended attribute directory. |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1641 |
*/ |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1642 |
static int |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1643 |
zfs_obj_to_pobj(objset_t *osp, uint64_t obj, uint64_t *pobjp, int *is_xattrdir) |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1644 |
{ |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1645 |
dmu_buf_t *db; |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1646 |
dmu_object_info_t doi; |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1647 |
znode_phys_t *zp; |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1648 |
int error; |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1649 |
|
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1650 |
if ((error = dmu_bonus_hold(osp, obj, FTAG, &db)) != 0) |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1651 |
return (error); |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1652 |
|
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1653 |
dmu_object_info_from_db(db, &doi); |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1654 |
if (doi.doi_bonus_type != DMU_OT_ZNODE || |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1655 |
doi.doi_bonus_size < sizeof (znode_phys_t)) { |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1656 |
dmu_buf_rele(db, FTAG); |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1657 |
return (EINVAL); |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1658 |
} |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1659 |
|
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1660 |
zp = db->db_data; |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1661 |
*pobjp = zp->zp_parent; |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1662 |
*is_xattrdir = ((zp->zp_flags & ZFS_XATTR) != 0) && |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1663 |
S_ISDIR(zp->zp_mode); |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1664 |
dmu_buf_rele(db, FTAG); |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1665 |
|
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1666 |
return (0); |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1667 |
} |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1668 |
|
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1669 |
int |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1670 |
zfs_obj_to_path(objset_t *osp, uint64_t obj, char *buf, int len) |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1671 |
{ |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1672 |
char *path = buf + len - 1; |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1673 |
int error; |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1674 |
|
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1675 |
*path = '\0'; |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1676 |
|
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1677 |
for (;;) { |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1678 |
uint64_t pobj; |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1679 |
char component[MAXNAMELEN + 2]; |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1680 |
size_t complen; |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1681 |
int is_xattrdir; |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1682 |
|
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1683 |
if ((error = zfs_obj_to_pobj(osp, obj, &pobj, |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1684 |
&is_xattrdir)) != 0) |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1685 |
break; |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1686 |
|
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1687 |
if (pobj == obj) { |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1688 |
if (path[0] != '/') |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1689 |
*--path = '/'; |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1690 |
break; |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1691 |
} |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1692 |
|
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1693 |
component[0] = '/'; |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1694 |
if (is_xattrdir) { |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1695 |
(void) sprintf(component + 1, "<xattrdir>"); |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1696 |
} else { |
4577 | 1697 |
error = zap_value_search(osp, pobj, obj, |
1698 |
ZFS_DIRENT_OBJ(-1ULL), component + 1); |
|
3444
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1699 |
if (error != 0) |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1700 |
break; |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1701 |
} |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1702 |
|
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1703 |
complen = strlen(component); |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1704 |
path -= complen; |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1705 |
ASSERT(path >= buf); |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1706 |
bcopy(component, path, complen); |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1707 |
obj = pobj; |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1708 |
} |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1709 |
|
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1710 |
if (error == 0) |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1711 |
(void) memmove(buf, path, buf + len - path); |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1712 |
return (error); |
dc160a70a50d
6410433 'zpool status -v' would be more useful with filenames
ek110237
parents:
3063
diff
changeset
|
1713 |
} |