Fri Jan 7 15:30:10 2011 UTC ()
in case unmount fails (it never should), do a full mountpoint dump


(pooka)
diff -r1.51 -r1.52 src/lib/libp2k/p2k.c

cvs diff -r1.51 -r1.52 src/lib/libp2k/p2k.c (switch to unified diff)

--- src/lib/libp2k/p2k.c 2011/01/07 11:15:30 1.51
+++ src/lib/libp2k/p2k.c 2011/01/07 15:30:09 1.52
@@ -1,1364 +1,1371 @@ @@ -1,1364 +1,1371 @@
1/* $NetBSD: p2k.c,v 1.51 2011/01/07 11:15:30 pooka Exp $ */ 1/* $NetBSD: p2k.c,v 1.52 2011/01/07 15:30:09 pooka Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2007, 2008, 2009 Antti Kantee. All Rights Reserved. 4 * Copyright (c) 2007, 2008, 2009 Antti Kantee. All Rights Reserved.
5 * 5 *
6 * Development of this software was supported by the 6 * Development of this software was supported by the
7 * Finnish Cultural Foundation. 7 * Finnish Cultural Foundation.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
17 * 17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE. 28 * SUCH DAMAGE.
29 */ 29 */
30 30
31/* 31/*
32 * puffs 2k, i.e. puffs 2 kernel. Converts the puffs protocol to 32 * puffs 2k, i.e. puffs 2 kernel. Converts the puffs protocol to
33 * the kernel vfs protocol and vice versa. 33 * the kernel vfs protocol and vice versa.
34 * 34 *
35 * A word about reference counting: puffs in the kernel is the king of 35 * A word about reference counting: puffs in the kernel is the king of
36 * reference counting. We must maintain a vnode alive and kicking 36 * reference counting. We must maintain a vnode alive and kicking
37 * until the kernel tells us to reclaim it. Therefore we make sure 37 * until the kernel tells us to reclaim it. Therefore we make sure
38 * we never accidentally lose a vnode. Before calling operations which 38 * we never accidentally lose a vnode. Before calling operations which
39 * decrease the refcount we always bump the refcount up to compensate. 39 * decrease the refcount we always bump the refcount up to compensate.
40 * Come inactive, if the file system thinks that the vnode should be 40 * Come inactive, if the file system thinks that the vnode should be
41 * put out of its misery, it will set the recycle flag. We use this 41 * put out of its misery, it will set the recycle flag. We use this
42 * to tell the kernel to reclaim the vnode. Only in reclaim do we 42 * to tell the kernel to reclaim the vnode. Only in reclaim do we
43 * really nuke the last reference. 43 * really nuke the last reference.
44 */ 44 */
45 45
46#include <sys/cdefs.h> 46#include <sys/cdefs.h>
47#include <sys/mount.h> 47#include <sys/mount.h>
48#include <sys/param.h> 48#include <sys/param.h>
49#include <sys/vnode.h> 49#include <sys/vnode.h>
50#include <sys/lock.h> 50#include <sys/lock.h>
51#include <sys/namei.h> 51#include <sys/namei.h>
52#include <sys/dirent.h> 52#include <sys/dirent.h>
53#include <sys/hash.h> 53#include <sys/hash.h>
54 54
55#include <assert.h> 55#include <assert.h>
56#include <errno.h> 56#include <errno.h>
57#include <puffs.h> 57#include <puffs.h>
58#include <stdlib.h> 58#include <stdlib.h>
59#include <stdio.h> 59#include <stdio.h>
60 60
61#include <rump/rump.h> 61#include <rump/rump.h>
62#include <rump/p2k.h> 62#include <rump/p2k.h>
63#include <rump/ukfs.h> 63#include <rump/ukfs.h>
64 64
65/* NetBSD-5 compat */ 65/* NetBSD-5 compat */
66#ifndef MOUNT_RUMPFS 66#ifndef MOUNT_RUMPFS
67#define MOUNT_RUMPFS "rumpfs" 67#define MOUNT_RUMPFS "rumpfs"
68#endif 68#endif
69 69
70PUFFSOP_PROTOS(p2k) 70PUFFSOP_PROTOS(p2k)
71 71
72LIST_HEAD(p2k_vp_hash, p2k_node); 72LIST_HEAD(p2k_vp_hash, p2k_node);
73#define NHASHBUCK (1<<16) 73#define NHASHBUCK (1<<16)
74struct p2k_mount { 74struct p2k_mount {
75 struct vnode *p2m_rvp; 75 struct vnode *p2m_rvp;
76 struct puffs_usermount *p2m_pu; 76 struct puffs_usermount *p2m_pu;
77 struct ukfs *p2m_ukfs; 77 struct ukfs *p2m_ukfs;
78 struct p2k_vp_hash p2m_vphash[NHASHBUCK]; 78 struct p2k_vp_hash p2m_vphash[NHASHBUCK];
79 struct mount *p2m_mp; 79 struct mount *p2m_mp;
80 int p2m_nvnodes; 80 int p2m_nvnodes;
81 int p2m_imtmpfsman; 81 int p2m_imtmpfsman;
82 bool p2m_hasdebug; 82 bool p2m_hasdebug;
83}; 83};
84 84
85struct p2k_node { 85struct p2k_node {
86 struct vnode *p2n_vp; 86 struct vnode *p2n_vp;
87 87
88 LIST_ENTRY(p2k_node) p2n_entries; 88 LIST_ENTRY(p2k_node) p2n_entries;
89}; 89};
90 90
91#define OPC2VP(opc) (((struct p2k_node *)opc)->p2n_vp) 91#define OPC2VP(opc) (((struct p2k_node *)opc)->p2n_vp)
92 92
93static int haswizard; 93static int haswizard;
94static uid_t wizarduid; 94static uid_t wizarduid;
95 95
96static struct kauth_cred * 96static struct kauth_cred *
97cred_create(const struct puffs_cred *pcr) 97cred_create(const struct puffs_cred *pcr)
98{ 98{
99 gid_t groups[NGROUPS]; 99 gid_t groups[NGROUPS];
100 uid_t uid; 100 uid_t uid;
101 gid_t gid; 101 gid_t gid;
102 short ngroups = __arraycount(groups); 102 short ngroups = __arraycount(groups);
103 103
104 if (haswizard) { 104 if (haswizard) {
105 uid = wizarduid; 105 uid = wizarduid;
106 } else { 106 } else {
107 if (puffs_cred_getuid(pcr, &uid) == -1) 107 if (puffs_cred_getuid(pcr, &uid) == -1)
108 uid = 0; 108 uid = 0;
109 } 109 }
110 if (puffs_cred_getgid(pcr, &gid) == -1) 110 if (puffs_cred_getgid(pcr, &gid) == -1)
111 gid = 0; 111 gid = 0;
112 puffs_cred_getgroups(pcr, groups, &ngroups); 112 puffs_cred_getgroups(pcr, groups, &ngroups);
113 113
114 /* LINTED: ngroups is ok */ 114 /* LINTED: ngroups is ok */
115 return rump_pub_cred_create(uid, gid, ngroups, groups); 115 return rump_pub_cred_create(uid, gid, ngroups, groups);
116} 116}
117 117
118static __inline void 118static __inline void
119cred_destroy(struct kauth_cred *cred) 119cred_destroy(struct kauth_cred *cred)
120{ 120{
121 121
122 rump_pub_cred_put(cred); 122 rump_pub_cred_put(cred);
123} 123}
124 124
125static struct componentname * 125static struct componentname *
126makecn(const struct puffs_cn *pcn) 126makecn(const struct puffs_cn *pcn)
127{ 127{
128 struct kauth_cred *cred; 128 struct kauth_cred *cred;
129 129
130 cred = cred_create(pcn->pcn_cred); 130 cred = cred_create(pcn->pcn_cred);
131 /* LINTED: prehistoric types in first two args */ 131 /* LINTED: prehistoric types in first two args */
132 return rump_pub_makecn(pcn->pcn_nameiop, pcn->pcn_flags, 132 return rump_pub_makecn(pcn->pcn_nameiop, pcn->pcn_flags,
133 pcn->pcn_name, pcn->pcn_namelen, cred, rump_pub_lwproc_curlwp()); 133 pcn->pcn_name, pcn->pcn_namelen, cred, rump_pub_lwproc_curlwp());
134} 134}
135 135
136static __inline void 136static __inline void
137freecn(struct componentname *cnp) 137freecn(struct componentname *cnp)
138{ 138{
139 139
140 rump_pub_freecn(cnp, RUMPCN_FREECRED); 140 rump_pub_freecn(cnp, RUMPCN_FREECRED);
141} 141}
142 142
143static void 143static void
144makelwp(struct puffs_usermount *pu) 144makelwp(struct puffs_usermount *pu)
145{ 145{
146 pid_t pid; 146 pid_t pid;
147 lwpid_t lid; 147 lwpid_t lid;
148 148
149 puffs_cc_getcaller(puffs_cc_getcc(pu), &pid, &lid); 149 puffs_cc_getcaller(puffs_cc_getcc(pu), &pid, &lid);
150 rump_pub_allbetsareoff_setid(pid, lid); 150 rump_pub_allbetsareoff_setid(pid, lid);
151} 151}
152 152
153static __inline struct p2k_vp_hash * 153static __inline struct p2k_vp_hash *
154gethash(struct p2k_mount *p2m, struct vnode *vp) 154gethash(struct p2k_mount *p2m, struct vnode *vp)
155{ 155{
156 uint32_t hash; 156 uint32_t hash;
157 157
158 hash = hash32_buf(&vp, sizeof(vp), HASH32_BUF_INIT); 158 hash = hash32_buf(&vp, sizeof(vp), HASH32_BUF_INIT);
159 return &p2m->p2m_vphash[hash % NHASHBUCK]; 159 return &p2m->p2m_vphash[hash % NHASHBUCK];
160} 160}
161 161
162/* 162/*
163 * Find node based on hash of vnode pointer. If vnode is found, 163 * Find node based on hash of vnode pointer. If vnode is found,
164 * releases one reference to vnode based on the fact that we just 164 * releases one reference to vnode based on the fact that we just
165 * performed a lookup for it. 165 * performed a lookup for it.
166 * 166 *
167 * If the optinal p2n_storage parameter is passed, it is used instead 167 * If the optinal p2n_storage parameter is passed, it is used instead
168 * of allocating more memory. This allows for easier error recovery. 168 * of allocating more memory. This allows for easier error recovery.
169 */ 169 */
170static struct p2k_node * 170static struct p2k_node *
171getp2n(struct p2k_mount *p2m, struct vnode *vp, bool initial, 171getp2n(struct p2k_mount *p2m, struct vnode *vp, bool initial,
172 struct p2k_node *p2n_storage) 172 struct p2k_node *p2n_storage)
173{ 173{
174 struct p2k_vp_hash *hl; 174 struct p2k_vp_hash *hl;
175 struct p2k_node *p2n = NULL; 175 struct p2k_node *p2n = NULL;
176 176
177 /* p2n_storage => initial */ 177 /* p2n_storage => initial */
178 assert(!p2n_storage || initial); 178 assert(!p2n_storage || initial);
179 179
180 hl = gethash(p2m, vp); 180 hl = gethash(p2m, vp);
181 if (!initial) 181 if (!initial)
182 LIST_FOREACH(p2n, hl, p2n_entries) 182 LIST_FOREACH(p2n, hl, p2n_entries)
183 if (p2n->p2n_vp == vp) 183 if (p2n->p2n_vp == vp)
184 break; 184 break;
185 185
186 hl = gethash(p2m, vp); 186 hl = gethash(p2m, vp);
187 if (p2n) { 187 if (p2n) {
188 rump_pub_vp_rele(vp); 188 rump_pub_vp_rele(vp);
189 } else { 189 } else {
190 if (p2n_storage) 190 if (p2n_storage)
191 p2n = p2n_storage; 191 p2n = p2n_storage;
192 else 192 else
193 p2n = malloc(sizeof(*p2n)); 193 p2n = malloc(sizeof(*p2n));
194 if (!p2n) { 194 if (!p2n) {
195 rump_pub_vp_rele(vp); 195 rump_pub_vp_rele(vp);
196 return NULL; 196 return NULL;
197 } 197 }
198 memset(p2n, 0, sizeof(*p2n)); 198 memset(p2n, 0, sizeof(*p2n));
199 LIST_INSERT_HEAD(hl, p2n, p2n_entries); 199 LIST_INSERT_HEAD(hl, p2n, p2n_entries);
200 p2n->p2n_vp = vp; 200 p2n->p2n_vp = vp;
201 } 201 }
202 return p2n; 202 return p2n;
203} 203}
204 204
205static void 205static void
206freep2n(struct p2k_node *p2n) 206freep2n(struct p2k_node *p2n)
207{ 207{
208 208
209 assert(p2n->p2n_vp == NULL); 209 assert(p2n->p2n_vp == NULL);
210 LIST_REMOVE(p2n, p2n_entries); 210 LIST_REMOVE(p2n, p2n_entries);
211 free(p2n); 211 free(p2n);
212} 212}
213 213
214/*ARGSUSED*/ 214/*ARGSUSED*/
215static void 215static void
216p2k_errcatcher(struct puffs_usermount *pu, uint8_t type, int error, 216p2k_errcatcher(struct puffs_usermount *pu, uint8_t type, int error,
217 const char *str, puffs_cookie_t cook) 217 const char *str, puffs_cookie_t cook)
218{ 218{
219 219
220 fprintf(stderr, "type %d, error %d, cookie %p (%s)\n", 220 fprintf(stderr, "type %d, error %d, cookie %p (%s)\n",
221 type, error, cook, str); 221 type, error, cook, str);
222 222
223 /* 223 /*
224 * Trap all EINVAL responses to lookup. It most likely means 224 * Trap all EINVAL responses to lookup. It most likely means
225 * that we supplied VNON/VBAD as the type. The real kernel 225 * that we supplied VNON/VBAD as the type. The real kernel
226 * doesn't panic from this either, but just handles it. 226 * doesn't panic from this either, but just handles it.
227 */ 227 */
228 if (type != PUFFS_VN_LOOKUP && error == EINVAL) 228 if (type != PUFFS_VN_LOOKUP && error == EINVAL)
229 abort(); 229 abort();
230} 230}
231 231
232/* just to avoid annoying loop when singlestepping */ 232/* just to avoid annoying loop when singlestepping */
233static struct p2k_mount * 233static struct p2k_mount *
234allocp2m(void) 234allocp2m(void)
235{ 235{
236 struct p2k_mount *p2m; 236 struct p2k_mount *p2m;
237 int i; 237 int i;
238 238
239 p2m = malloc(sizeof(*p2m)); 239 p2m = malloc(sizeof(*p2m));
240 if (p2m == NULL) 240 if (p2m == NULL)
241 return NULL; 241 return NULL;
242 memset(p2m, 0, sizeof(*p2m)); 242 memset(p2m, 0, sizeof(*p2m));
243 243
244 for (i = 0; i < NHASHBUCK; i++) 244 for (i = 0; i < NHASHBUCK; i++)
245 LIST_INIT(&p2m->p2m_vphash[i]); 245 LIST_INIT(&p2m->p2m_vphash[i]);
246 246
247 return p2m; 247 return p2m;
248} 248}
249 249
250struct p2k_mount * 250struct p2k_mount *
251p2k_init(uint32_t puffs_flags) 251p2k_init(uint32_t puffs_flags)
252{ 252{
253 struct puffs_ops *pops; 253 struct puffs_ops *pops;
254 struct p2k_mount *p2m; 254 struct p2k_mount *p2m;
255 char *envbuf; 255 char *envbuf;
256 bool dodaemon; 256 bool dodaemon;
257 bool hasdebug; 257 bool hasdebug;
258 258
259 PUFFSOP_INIT(pops); 259 PUFFSOP_INIT(pops);
260 260
261 PUFFSOP_SET(pops, p2k, fs, statvfs); 261 PUFFSOP_SET(pops, p2k, fs, statvfs);
262 PUFFSOP_SET(pops, p2k, fs, unmount); 262 PUFFSOP_SET(pops, p2k, fs, unmount);
263 PUFFSOP_SET(pops, p2k, fs, sync); 263 PUFFSOP_SET(pops, p2k, fs, sync);
264 PUFFSOP_SET(pops, p2k, fs, fhtonode); 264 PUFFSOP_SET(pops, p2k, fs, fhtonode);
265 PUFFSOP_SET(pops, p2k, fs, nodetofh); 265 PUFFSOP_SET(pops, p2k, fs, nodetofh);
266 PUFFSOP_SET(pops, p2k, fs, extattrctl); 266 PUFFSOP_SET(pops, p2k, fs, extattrctl);
267 267
268 PUFFSOP_SET(pops, p2k, node, lookup); 268 PUFFSOP_SET(pops, p2k, node, lookup);
269 PUFFSOP_SET(pops, p2k, node, create); 269 PUFFSOP_SET(pops, p2k, node, create);
270 PUFFSOP_SET(pops, p2k, node, mknod); 270 PUFFSOP_SET(pops, p2k, node, mknod);
271 PUFFSOP_SET(pops, p2k, node, open); 271 PUFFSOP_SET(pops, p2k, node, open);
272 PUFFSOP_SET(pops, p2k, node, close); 272 PUFFSOP_SET(pops, p2k, node, close);
273 PUFFSOP_SET(pops, p2k, node, access); 273 PUFFSOP_SET(pops, p2k, node, access);
274 PUFFSOP_SET(pops, p2k, node, getattr); 274 PUFFSOP_SET(pops, p2k, node, getattr);
275 PUFFSOP_SET(pops, p2k, node, setattr); 275 PUFFSOP_SET(pops, p2k, node, setattr);
276#if 0 276#if 0
277 PUFFSOP_SET(pops, p2k, node, poll); 277 PUFFSOP_SET(pops, p2k, node, poll);
278#endif 278#endif
279 PUFFSOP_SET(pops, p2k, node, mmap); 279 PUFFSOP_SET(pops, p2k, node, mmap);
280 PUFFSOP_SET(pops, p2k, node, fsync); 280 PUFFSOP_SET(pops, p2k, node, fsync);
281 PUFFSOP_SET(pops, p2k, node, seek); 281 PUFFSOP_SET(pops, p2k, node, seek);
282 PUFFSOP_SET(pops, p2k, node, remove); 282 PUFFSOP_SET(pops, p2k, node, remove);
283 PUFFSOP_SET(pops, p2k, node, link); 283 PUFFSOP_SET(pops, p2k, node, link);
284 PUFFSOP_SET(pops, p2k, node, rename); 284 PUFFSOP_SET(pops, p2k, node, rename);
285 PUFFSOP_SET(pops, p2k, node, mkdir); 285 PUFFSOP_SET(pops, p2k, node, mkdir);
286 PUFFSOP_SET(pops, p2k, node, rmdir); 286 PUFFSOP_SET(pops, p2k, node, rmdir);
287 PUFFSOP_SET(pops, p2k, node, symlink); 287 PUFFSOP_SET(pops, p2k, node, symlink);
288 PUFFSOP_SET(pops, p2k, node, readdir); 288 PUFFSOP_SET(pops, p2k, node, readdir);
289 PUFFSOP_SET(pops, p2k, node, readlink); 289 PUFFSOP_SET(pops, p2k, node, readlink);
290 PUFFSOP_SET(pops, p2k, node, read); 290 PUFFSOP_SET(pops, p2k, node, read);
291 PUFFSOP_SET(pops, p2k, node, write); 291 PUFFSOP_SET(pops, p2k, node, write);
292 292
293 PUFFSOP_SET(pops, p2k, node, pathconf); 293 PUFFSOP_SET(pops, p2k, node, pathconf);
294 294
295 PUFFSOP_SET(pops, p2k, node, inactive); 295 PUFFSOP_SET(pops, p2k, node, inactive);
296 PUFFSOP_SET(pops, p2k, node, reclaim); 296 PUFFSOP_SET(pops, p2k, node, reclaim);
297 297
298 PUFFSOP_SET(pops, p2k, node, getextattr); 298 PUFFSOP_SET(pops, p2k, node, getextattr);
299 PUFFSOP_SET(pops, p2k, node, setextattr); 299 PUFFSOP_SET(pops, p2k, node, setextattr);
300 PUFFSOP_SET(pops, p2k, node, listextattr); 300 PUFFSOP_SET(pops, p2k, node, listextattr);
301 PUFFSOP_SET(pops, p2k, node, deleteextattr); 301 PUFFSOP_SET(pops, p2k, node, deleteextattr);
302 302
303 dodaemon = true; 303 dodaemon = true;
304 hasdebug = false; 304 hasdebug = false;
305 305
306 if (getenv("P2K_DEBUG") != NULL) { 306 if (getenv("P2K_DEBUG") != NULL) {
307 puffs_flags |= PUFFS_FLAG_OPDUMP; 307 puffs_flags |= PUFFS_FLAG_OPDUMP;
308 dodaemon = false; 308 dodaemon = false;
309 hasdebug = true; 309 hasdebug = true;
310 } 310 }
311 if (getenv("P2K_NODETACH") != NULL) { 311 if (getenv("P2K_NODETACH") != NULL) {
312 dodaemon = false; 312 dodaemon = false;
313 } 313 }
314 if (getenv("P2K_NOCACHE_PAGE") != NULL) { 314 if (getenv("P2K_NOCACHE_PAGE") != NULL) {
315 puffs_flags |= PUFFS_KFLAG_NOCACHE_PAGE; 315 puffs_flags |= PUFFS_KFLAG_NOCACHE_PAGE;
316 } 316 }
317 if (getenv("P2K_NOCACHE_NAME") != NULL) { 317 if (getenv("P2K_NOCACHE_NAME") != NULL) {
318 puffs_flags |= PUFFS_KFLAG_NOCACHE_NAME; 318 puffs_flags |= PUFFS_KFLAG_NOCACHE_NAME;
319 } 319 }
320 if (getenv("P2K_NOCACHE") != NULL) { 320 if (getenv("P2K_NOCACHE") != NULL) {
321 puffs_flags |= PUFFS_KFLAG_NOCACHE; 321 puffs_flags |= PUFFS_KFLAG_NOCACHE;
322 } 322 }
323 if ((envbuf = getenv("P2K_WIZARDUID")) != NULL) { 323 if ((envbuf = getenv("P2K_WIZARDUID")) != NULL) {
324 /* default to 0 in error cases */ 324 /* default to 0 in error cases */
325 wizarduid = atoi(envbuf); 325 wizarduid = atoi(envbuf);
326 haswizard = 1; 326 haswizard = 1;
327 printf("P2K WIZARD MODE: using uid %d\n", wizarduid); 327 printf("P2K WIZARD MODE: using uid %d\n", wizarduid);
328 } 328 }
329 329
330 p2m = allocp2m(); 330 p2m = allocp2m();
331 if (p2m == NULL) 331 if (p2m == NULL)
332 return NULL; 332 return NULL;
333 p2m->p2m_pu = puffs_init(pops, PUFFS_DEFER, PUFFS_DEFER, 333 p2m->p2m_pu = puffs_init(pops, PUFFS_DEFER, PUFFS_DEFER,
334 PUFFS_DEFER, puffs_flags); 334 PUFFS_DEFER, puffs_flags);
335 if (p2m->p2m_pu == NULL) { 335 if (p2m->p2m_pu == NULL) {
336 int sverrno = errno; 336 int sverrno = errno;
337 free(p2m); 337 free(p2m);
338 errno = sverrno; 338 errno = sverrno;
339 return NULL; 339 return NULL;
340 } 340 }
341 p2m->p2m_hasdebug = hasdebug; 341 p2m->p2m_hasdebug = hasdebug;
342 342
343 if (dodaemon) { 343 if (dodaemon) {
344 if (puffs_daemon(p2m->p2m_pu, 1, 1) == -1) { 344 if (puffs_daemon(p2m->p2m_pu, 1, 1) == -1) {
345 int sverrno = errno; 345 int sverrno = errno;
346 p2k_cancel(p2m, sverrno); 346 p2k_cancel(p2m, sverrno);
347 errno = sverrno; 347 errno = sverrno;
348 p2m = NULL; 348 p2m = NULL;
349 } 349 }
350 } 350 }
351 if (p2m) 351 if (p2m)
352 rump_init(); 352 rump_init();
353 353
354 rump_pub_lwproc_rfork(RUMP_RFCFDG); 354 rump_pub_lwproc_rfork(RUMP_RFCFDG);
355 355
356 return p2m; 356 return p2m;
357} 357}
358 358
359void 359void
360p2k_cancel(struct p2k_mount *p2m, int error) 360p2k_cancel(struct p2k_mount *p2m, int error)
361{ 361{
362 362
363 puffs_cancel(p2m->p2m_pu, error); 363 puffs_cancel(p2m->p2m_pu, error);
364 free(p2m); 364 free(p2m);
365} 365}
366 366
367static int 367static int
368setupfs(struct p2k_mount *p2m, const char *vfsname, const char *devpath, 368setupfs(struct p2k_mount *p2m, const char *vfsname, const char *devpath,
369 struct ukfs_part *part, const char *mountpath, int mntflags, 369 struct ukfs_part *part, const char *mountpath, int mntflags,
370 void *arg, size_t alen) 370 void *arg, size_t alen)
371{ 371{
372 char partpath[UKFS_DEVICE_MAXPATHLEN]; 372 char partpath[UKFS_DEVICE_MAXPATHLEN];
373 char partbuf[UKFS_DEVICE_MAXSTR]; 373 char partbuf[UKFS_DEVICE_MAXSTR];
374 char typebuf[PUFFS_TYPELEN]; 374 char typebuf[PUFFS_TYPELEN];
375 struct puffs_usermount *pu = p2m->p2m_pu; 375 struct puffs_usermount *pu = p2m->p2m_pu;
376 struct p2k_node *p2n_root; 376 struct p2k_node *p2n_root;
377 struct ukfs *ukfs = NULL; 377 struct ukfs *ukfs = NULL;
378 extern int puffs_fakecc; 378 extern int puffs_fakecc;
379 int rv = -1, sverrno; 379 int rv = -1, sverrno;
380 380
381 strcpy(typebuf, "p2k|"); 381 strcpy(typebuf, "p2k|");
382 if (strcmp(vfsname, "puffs") == 0) { /* XXX */ 382 if (strcmp(vfsname, "puffs") == 0) { /* XXX */
383 struct puffs_kargs *args = arg; 383 struct puffs_kargs *args = arg;
384 strlcat(typebuf, args->pa_typename, sizeof(typebuf)); 384 strlcat(typebuf, args->pa_typename, sizeof(typebuf));
385 } else { 385 } else {
386 strlcat(typebuf, vfsname, sizeof(typebuf)); 386 strlcat(typebuf, vfsname, sizeof(typebuf));
387 } 387 }
388 388
389 strlcpy(partpath, devpath, sizeof(partpath)); 389 strlcpy(partpath, devpath, sizeof(partpath));
390 if (ukfs_part_tostring(part, partbuf, sizeof(partbuf))) { 390 if (ukfs_part_tostring(part, partbuf, sizeof(partbuf))) {
391 strlcat(partpath, partbuf, sizeof(partpath)); 391 strlcat(partpath, partbuf, sizeof(partpath));
392 } 392 }
393 puffs_setmntinfo(pu, partpath, typebuf); 393 puffs_setmntinfo(pu, partpath, typebuf);
394 394
395 if (ukfs_init() == -1) 395 if (ukfs_init() == -1)
396 goto out; 396 goto out;
397 397
398 /*  398 /*
399 * If we're mounting rumpfs, actually do no mount and redirect 399 * If we're mounting rumpfs, actually do no mount and redirect
400 * requests to rump fs namespace root. Strictly speaking, this 400 * requests to rump fs namespace root. Strictly speaking, this
401 * is not correct, but I don't think anyone will notice. 401 * is not correct, but I don't think anyone will notice.
402 * After all, we're mostly interested in things which reside 402 * After all, we're mostly interested in things which reside
403 * specifically on the rootfs, namely the contents of /dev 403 * specifically on the rootfs, namely the contents of /dev
404 */ 404 */
405 if (strcmp(vfsname, MOUNT_RUMPFS) == 0) { 405 if (strcmp(vfsname, MOUNT_RUMPFS) == 0) {
406 if ((rv = rump_pub_vfs_getmp("/", &p2m->p2m_mp)) != 0) { 406 if ((rv = rump_pub_vfs_getmp("/", &p2m->p2m_mp)) != 0) {
407 errno = rv; 407 errno = rv;
408 rv = -1; 408 rv = -1;
409 goto out; 409 goto out;
410 } 410 }
411 } else { 411 } else {
412 if (part != ukfs_part_na) 412 if (part != ukfs_part_na)
413 ukfs = ukfs_mount_disk(vfsname, devpath, part, 413 ukfs = ukfs_mount_disk(vfsname, devpath, part,
414 mountpath, mntflags, arg, alen); 414 mountpath, mntflags, arg, alen);
415 else 415 else
416 ukfs = ukfs_mount(vfsname, devpath, mountpath, mntflags, 416 ukfs = ukfs_mount(vfsname, devpath, mountpath, mntflags,
417 arg, alen); 417 arg, alen);
418 if (ukfs == NULL) 418 if (ukfs == NULL)
419 goto out; 419 goto out;
420 ukfs_setspecific(ukfs, p2m); 420 ukfs_setspecific(ukfs, p2m);
421 p2m->p2m_ukfs = ukfs; 421 p2m->p2m_ukfs = ukfs;
422 p2m->p2m_mp = ukfs_getmp(ukfs); 422 p2m->p2m_mp = ukfs_getmp(ukfs);
423 } 423 }
424 if ((rv = rump_pub_vfs_root(p2m->p2m_mp, &p2m->p2m_rvp, 0)) != 0) { 424 if ((rv = rump_pub_vfs_root(p2m->p2m_mp, &p2m->p2m_rvp, 0)) != 0) {
425 errno = rv; 425 errno = rv;
426 rv = -1; 426 rv = -1;
427 goto out; 427 goto out;
428 } 428 }
429 429
430 p2m->p2m_pu = pu; 430 p2m->p2m_pu = pu;
431 431
432 /* 432 /*
433 * Detect tmpfs. XXX: this is a kludge. See inactive(). 433 * Detect tmpfs. XXX: this is a kludge. See inactive().
434 * 434 *
435 * In reality we'd want "does file system use anon objects 435 * In reality we'd want "does file system use anon objects
436 * for storage?". But since tmpfs hides the anon object from 436 * for storage?". But since tmpfs hides the anon object from
437 * the public interface, we can't actually detect it sanely. 437 * the public interface, we can't actually detect it sanely.
438 * Therefore, use this kludge. 438 * Therefore, use this kludge.
439 */ 439 */
440 p2m->p2m_imtmpfsman = strcmp(vfsname, MOUNT_TMPFS) == 0; 440 p2m->p2m_imtmpfsman = strcmp(vfsname, MOUNT_TMPFS) == 0;
441 441
442 p2n_root = getp2n(p2m, p2m->p2m_rvp, true, NULL); 442 p2n_root = getp2n(p2m, p2m->p2m_rvp, true, NULL);
443 puffs_setfhsize(pu, 0, PUFFS_FHFLAG_PASSTHROUGH); 443 puffs_setfhsize(pu, 0, PUFFS_FHFLAG_PASSTHROUGH);
444 puffs_setstacksize(pu, PUFFS_STACKSIZE_MIN); 444 puffs_setstacksize(pu, PUFFS_STACKSIZE_MIN);
445 puffs_fakecc = 1; 445 puffs_fakecc = 1;
446 puffs_set_prepost(pu, makelwp, NULL); 446 puffs_set_prepost(pu, makelwp, NULL);
447 puffs_set_errnotify(pu, p2k_errcatcher); 447 puffs_set_errnotify(pu, p2k_errcatcher);
448 448
449 puffs_setspecific(pu, p2m); 449 puffs_setspecific(pu, p2m);
450 rv = puffs_mount(pu, mountpath, mntflags, p2n_root); 450 rv = puffs_mount(pu, mountpath, mntflags, p2n_root);
451 451
452 out: 452 out:
453 if (rv == -1) { 453 if (rv == -1) {
454 sverrno = errno; 454 sverrno = errno;
455 puffs_cancel(pu, sverrno); 455 puffs_cancel(pu, sverrno);
456 if (ukfs) 456 if (ukfs)
457 ukfs_release(p2m->p2m_ukfs, UKFS_RELFLAG_FORCE); 457 ukfs_release(p2m->p2m_ukfs, UKFS_RELFLAG_FORCE);
458 free(p2m); 458 free(p2m);
459 errno = sverrno; 459 errno = sverrno;
460 } 460 }
461 461
462 return rv; 462 return rv;
463} 463}
464 464
465int 465int
466p2k_mainloop(struct p2k_mount *p2m) 466p2k_mainloop(struct p2k_mount *p2m)
467{ 467{
468 int rv, sverrno; 468 int rv, sverrno;
469 469
470 rv = puffs_mainloop(p2m->p2m_pu); 470 rv = puffs_mainloop(p2m->p2m_pu);
471 sverrno = errno; 471 sverrno = errno;
472 puffs_exit(p2m->p2m_pu, 1); 472 puffs_exit(p2m->p2m_pu, 1);
473 if (p2m->p2m_ukfs) 473 if (p2m->p2m_ukfs)
474 ukfs_release(p2m->p2m_ukfs, UKFS_RELFLAG_FORCE); 474 ukfs_release(p2m->p2m_ukfs, UKFS_RELFLAG_FORCE);
475 free(p2m); 475 free(p2m);
476 476
477 if (rv == -1) 477 if (rv == -1)
478 errno = sverrno; 478 errno = sverrno;
479 return rv; 479 return rv;
480} 480}
481 481
482int 482int
483p2k_run_fs(const char *vfsname, const char *devpath, const char *mountpath, 483p2k_run_fs(const char *vfsname, const char *devpath, const char *mountpath,
484 int mntflags, void *arg, size_t alen, uint32_t puffs_flags) 484 int mntflags, void *arg, size_t alen, uint32_t puffs_flags)
485{ 485{
486 struct p2k_mount *p2m; 486 struct p2k_mount *p2m;
487 int rv; 487 int rv;
488 488
489 p2m = p2k_init(puffs_flags); 489 p2m = p2k_init(puffs_flags);
490 if (p2m == NULL) 490 if (p2m == NULL)
491 return -1; 491 return -1;
492 rv = setupfs(p2m, vfsname, devpath, ukfs_part_na, mountpath, 492 rv = setupfs(p2m, vfsname, devpath, ukfs_part_na, mountpath,
493 mntflags, arg, alen); 493 mntflags, arg, alen);
494 if (rv == -1) 494 if (rv == -1)
495 return rv; 495 return rv;
496 return p2k_mainloop(p2m); 496 return p2k_mainloop(p2m);
497} 497}
498 498
499int 499int
500p2k_run_diskfs(const char *vfsname, const char *devpath, struct ukfs_part *part, 500p2k_run_diskfs(const char *vfsname, const char *devpath, struct ukfs_part *part,
501 const char *mountpath, int mntflags, void *arg, size_t alen, 501 const char *mountpath, int mntflags, void *arg, size_t alen,
502 uint32_t puffs_flags) 502 uint32_t puffs_flags)
503{ 503{
504 struct p2k_mount *p2m; 504 struct p2k_mount *p2m;
505 int rv; 505 int rv;
506 506
507 p2m = p2k_init(puffs_flags); 507 p2m = p2k_init(puffs_flags);
508 if (p2m == NULL) 508 if (p2m == NULL)
509 return -1; 509 return -1;
510 rv = setupfs(p2m, vfsname, devpath, part, mountpath, mntflags, 510 rv = setupfs(p2m, vfsname, devpath, part, mountpath, mntflags,
511 arg, alen); 511 arg, alen);
512 if (rv == -1) 512 if (rv == -1)
513 return rv; 513 return rv;
514 return p2k_mainloop(p2m); 514 return p2k_mainloop(p2m);
515} 515}
516 516
517int 517int
518p2k_setup_fs(struct p2k_mount *p2m, const char *vfsname, const char *devpath, 518p2k_setup_fs(struct p2k_mount *p2m, const char *vfsname, const char *devpath,
519 const char *mountpath, int mntflags, void *arg, size_t alen) 519 const char *mountpath, int mntflags, void *arg, size_t alen)
520{ 520{
521 521
522 return setupfs(p2m, vfsname, devpath, ukfs_part_na, mountpath, 522 return setupfs(p2m, vfsname, devpath, ukfs_part_na, mountpath,
523 mntflags, arg, alen); 523 mntflags, arg, alen);
524} 524}
525 525
526int 526int
527p2k_setup_diskfs(struct p2k_mount *p2m, const char *vfsname, 527p2k_setup_diskfs(struct p2k_mount *p2m, const char *vfsname,
528 const char *devpath, struct ukfs_part *part, const char *mountpath, 528 const char *devpath, struct ukfs_part *part, const char *mountpath,
529 int mntflags, void *arg, size_t alen) 529 int mntflags, void *arg, size_t alen)
530{ 530{
531 531
532 return setupfs(p2m, vfsname, devpath, part, mountpath, mntflags, 532 return setupfs(p2m, vfsname, devpath, part, mountpath, mntflags,
533 arg, alen); 533 arg, alen);
534} 534}
535 535
536int 536int
537p2k_fs_statvfs(struct puffs_usermount *pu, struct statvfs *sbp) 537p2k_fs_statvfs(struct puffs_usermount *pu, struct statvfs *sbp)
538{ 538{
539 struct p2k_mount *p2m = puffs_getspecific(pu); 539 struct p2k_mount *p2m = puffs_getspecific(pu);
540 struct mount *mp = p2m->p2m_mp; 540 struct mount *mp = p2m->p2m_mp;
541 541
542 return rump_pub_vfs_statvfs(mp, sbp); 542 return rump_pub_vfs_statvfs(mp, sbp);
543} 543}
544 544
545/*ARGSUSED*/ 545/*ARGSUSED*/
546int 546int
547p2k_fs_unmount(struct puffs_usermount *pu, int flags) 547p2k_fs_unmount(struct puffs_usermount *pu, int flags)
548{ 548{
549 struct p2k_mount *p2m = puffs_getspecific(pu); 549 struct p2k_mount *p2m = puffs_getspecific(pu);
550 struct ukfs *fs = p2m->p2m_ukfs; 550 struct ukfs *fs = p2m->p2m_ukfs;
551 int error = 0; 551 int error = 0;
552 552
553 rump_pub_vp_rele(p2m->p2m_rvp); 553 rump_pub_vp_rele(p2m->p2m_rvp);
554 554
555 if (fs) { 555 if (fs) {
556 if (ukfs_release(fs, 0) != 0) { 556 if (ukfs_release(fs, 0) != 0) {
 557 struct statvfs svfsb;
 558
 559 if (p2m->p2m_hasdebug
 560 && p2k_fs_statvfs(pu, &svfsb) == 0) {
 561 printf("\nSOFT UNMOUNT FAILED, MP INFO DUMP\n");
 562 rump_pub_vfs_mount_print(svfsb.f_mntonname, 1);
 563 }
557 ukfs_release(fs, UKFS_RELFLAG_FORCE); 564 ukfs_release(fs, UKFS_RELFLAG_FORCE);
558 error = 0; 565 error = 0;
559 } 566 }
560 } 567 }
561 p2m->p2m_ukfs = NULL; 568 p2m->p2m_ukfs = NULL;
562 569
563 if (p2m->p2m_hasdebug) { 570 if (p2m->p2m_hasdebug) {
564 printf("-- rump kernel event counters --\n"); 571 printf("-- rump kernel event counters --\n");
565 rump_printevcnts(); 572 rump_printevcnts();
566 printf("-- end of event counters --\n"); 573 printf("-- end of event counters --\n");
567 } 574 }
568 575
569 return error; 576 return error;
570} 577}
571 578
572int 579int
573p2k_fs_sync(struct puffs_usermount *pu, int waitfor, 580p2k_fs_sync(struct puffs_usermount *pu, int waitfor,
574 const struct puffs_cred *pcr) 581 const struct puffs_cred *pcr)
575{ 582{
576 struct p2k_mount *p2m = puffs_getspecific(pu); 583 struct p2k_mount *p2m = puffs_getspecific(pu);
577 struct mount *mp = p2m->p2m_mp; 584 struct mount *mp = p2m->p2m_mp;
578 struct kauth_cred *cred; 585 struct kauth_cred *cred;
579 int rv; 586 int rv;
580 587
581 cred = cred_create(pcr); 588 cred = cred_create(pcr);
582 rv = rump_pub_vfs_sync(mp, waitfor, cred); 589 rv = rump_pub_vfs_sync(mp, waitfor, cred);
583 cred_destroy(cred); 590 cred_destroy(cred);
584 591
585 return rv; 592 return rv;
586} 593}
587 594
588/*ARGSUSED*/ 595/*ARGSUSED*/
589int 596int
590p2k_fs_fhtonode(struct puffs_usermount *pu, void *fid, size_t fidsize, 597p2k_fs_fhtonode(struct puffs_usermount *pu, void *fid, size_t fidsize,
591 struct puffs_newinfo *pni) 598 struct puffs_newinfo *pni)
592{ 599{
593 struct p2k_mount *p2m = puffs_getspecific(pu); 600 struct p2k_mount *p2m = puffs_getspecific(pu);
594 struct mount *mp = p2m->p2m_mp; 601 struct mount *mp = p2m->p2m_mp;
595 struct p2k_node *p2n; 602 struct p2k_node *p2n;
596 struct vnode *vp; 603 struct vnode *vp;
597 enum vtype vtype; 604 enum vtype vtype;
598 voff_t vsize; 605 voff_t vsize;
599 uint64_t rdev; /* XXX: allows running this on NetBSD 5.0 */ 606 uint64_t rdev; /* XXX: allows running this on NetBSD 5.0 */
600 int rv; 607 int rv;
601 608
602 rv = rump_pub_vfs_fhtovp(mp, fid, &vp); 609 rv = rump_pub_vfs_fhtovp(mp, fid, &vp);
603 if (rv) 610 if (rv)
604 return rv; 611 return rv;
605 RUMP_VOP_UNLOCK(vp); 612 RUMP_VOP_UNLOCK(vp);
606 613
607 p2n = getp2n(p2m, vp, false, NULL); 614 p2n = getp2n(p2m, vp, false, NULL);
608 if (p2n == NULL) 615 if (p2n == NULL)
609 return ENOMEM; 616 return ENOMEM;
610 617
611 puffs_newinfo_setcookie(pni, p2n); 618 puffs_newinfo_setcookie(pni, p2n);
612 rump_pub_getvninfo(vp, &vtype, &vsize, (void *)&rdev); 619 rump_pub_getvninfo(vp, &vtype, &vsize, (void *)&rdev);
613 puffs_newinfo_setvtype(pni, vtype); 620 puffs_newinfo_setvtype(pni, vtype);
614 puffs_newinfo_setsize(pni, vsize); 621 puffs_newinfo_setsize(pni, vsize);
615 /* LINTED: yea, it'll lose accuracy, but that's life */ 622 /* LINTED: yea, it'll lose accuracy, but that's life */
616 puffs_newinfo_setrdev(pni, rdev); 623 puffs_newinfo_setrdev(pni, rdev);
617 624
618 return 0; 625 return 0;
619} 626}
620 627
621/*ARGSUSED*/ 628/*ARGSUSED*/
622int 629int
623p2k_fs_nodetofh(struct puffs_usermount *pu, puffs_cookie_t cookie, void *fid, 630p2k_fs_nodetofh(struct puffs_usermount *pu, puffs_cookie_t cookie, void *fid,
624 size_t *fidsize) 631 size_t *fidsize)
625{ 632{
626 struct vnode *vp = OPC2VP(cookie); 633 struct vnode *vp = OPC2VP(cookie);
627 634
628 return rump_pub_vfs_vptofh(vp, fid, fidsize); 635 return rump_pub_vfs_vptofh(vp, fid, fidsize);
629} 636}
630 637
631int 638int
632p2k_fs_extattrctl(struct puffs_usermount *pu, int cmd, 639p2k_fs_extattrctl(struct puffs_usermount *pu, int cmd,
633 puffs_cookie_t cookie, int flags, 640 puffs_cookie_t cookie, int flags,
634 int attrnamespace, const char *attrname) 641 int attrnamespace, const char *attrname)
635{ 642{
636 struct p2k_mount *p2m = puffs_getspecific(pu); 643 struct p2k_mount *p2m = puffs_getspecific(pu);
637 struct mount *mp = p2m->p2m_mp; 644 struct mount *mp = p2m->p2m_mp;
638 struct vnode *vp; 645 struct vnode *vp;
639 646
640 if (flags & PUFFS_EXTATTRCTL_HASNODE) { 647 if (flags & PUFFS_EXTATTRCTL_HASNODE) {
641 vp = OPC2VP(cookie); 648 vp = OPC2VP(cookie);
642 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE | LK_RETRY); 649 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE | LK_RETRY);
643 } else { 650 } else {
644 vp = NULL; 651 vp = NULL;
645 } 652 }
646 653
647 /* vfsop unlocks (but doesn't release) vnode, so we're done here */ 654 /* vfsop unlocks (but doesn't release) vnode, so we're done here */
648 return rump_pub_vfs_extattrctl(mp, cmd, vp, attrnamespace, attrname); 655 return rump_pub_vfs_extattrctl(mp, cmd, vp, attrnamespace, attrname);
649} 656}
650 657
651/*ARGSUSED*/ 658/*ARGSUSED*/
652int 659int
653p2k_node_lookup(struct puffs_usermount *pu, puffs_cookie_t opc, 660p2k_node_lookup(struct puffs_usermount *pu, puffs_cookie_t opc,
654 struct puffs_newinfo *pni, const struct puffs_cn *pcn) 661 struct puffs_newinfo *pni, const struct puffs_cn *pcn)
655{ 662{
656 struct p2k_mount *p2m = puffs_getspecific(pu); 663 struct p2k_mount *p2m = puffs_getspecific(pu);
657 struct p2k_node *p2n_dir = opc, *p2n; 664 struct p2k_node *p2n_dir = opc, *p2n;
658 struct componentname *cn; 665 struct componentname *cn;
659 struct vnode *dvp = p2n_dir->p2n_vp, *vp; 666 struct vnode *dvp = p2n_dir->p2n_vp, *vp;
660 enum vtype vtype; 667 enum vtype vtype;
661 voff_t vsize; 668 voff_t vsize;
662 uint64_t rdev; /* XXX: uint64_t because of stack overwrite in compat */ 669 uint64_t rdev; /* XXX: uint64_t because of stack overwrite in compat */
663 int rv; 670 int rv;
664 671
665 cn = makecn(pcn); 672 cn = makecn(pcn);
666 RUMP_VOP_LOCK(dvp, LK_EXCLUSIVE); 673 RUMP_VOP_LOCK(dvp, LK_EXCLUSIVE);
667 rv = RUMP_VOP_LOOKUP(dvp, &vp, cn); 674 rv = RUMP_VOP_LOOKUP(dvp, &vp, cn);
668 RUMP_VOP_UNLOCK(dvp); 675 RUMP_VOP_UNLOCK(dvp);
669 freecn(cn); 676 freecn(cn);
670 677
671 if (rv) { 678 if (rv) {
672 if (rv == EJUSTRETURN) { 679 if (rv == EJUSTRETURN) {
673 rv = ENOENT; 680 rv = ENOENT;
674 } 681 }
675 return rv; 682 return rv;
676 } 683 }
677 RUMP_VOP_UNLOCK(vp); 684 RUMP_VOP_UNLOCK(vp);
678 685
679 p2n = getp2n(p2m, vp, false, NULL); 686 p2n = getp2n(p2m, vp, false, NULL);
680 if (p2n == NULL) { 687 if (p2n == NULL) {
681 return ENOMEM; 688 return ENOMEM;
682 } 689 }
683 690
684 puffs_newinfo_setcookie(pni, p2n); 691 puffs_newinfo_setcookie(pni, p2n);
685 rump_pub_getvninfo(vp, &vtype, &vsize, (void *)&rdev); 692 rump_pub_getvninfo(vp, &vtype, &vsize, (void *)&rdev);
686 puffs_newinfo_setvtype(pni, vtype); 693 puffs_newinfo_setvtype(pni, vtype);
687 puffs_newinfo_setsize(pni, vsize); 694 puffs_newinfo_setsize(pni, vsize);
688 /* LINTED: yea, it'll lose accuracy, but that's life */ 695 /* LINTED: yea, it'll lose accuracy, but that's life */
689 puffs_newinfo_setrdev(pni, rdev); 696 puffs_newinfo_setrdev(pni, rdev);
690 697
691 return 0; 698 return 0;
692} 699}
693 700
694#define VERS_TIMECHANGE 599000700 701#define VERS_TIMECHANGE 599000700
695static int 702static int
696needcompat(void) 703needcompat(void)
697{ 704{
698 705
699 /*LINTED*/ 706 /*LINTED*/
700 return __NetBSD_Version__ < VERS_TIMECHANGE 707 return __NetBSD_Version__ < VERS_TIMECHANGE
701 && rump_pub_getversion() >= VERS_TIMECHANGE; 708 && rump_pub_getversion() >= VERS_TIMECHANGE;
702} 709}
703 710
704#define DOCOMPAT(va, va_compat) \ 711#define DOCOMPAT(va, va_compat) \
705do { \ 712do { \
706 if (needcompat()) { \ 713 if (needcompat()) { \
707 va_compat = rump_pub_vattr_init(); \ 714 va_compat = rump_pub_vattr_init(); \
708 rump_pub_vattr50_to_vattr(va, va_compat); \ 715 rump_pub_vattr50_to_vattr(va, va_compat); \
709 } else { \ 716 } else { \
710 va_compat = __UNCONST(va); \ 717 va_compat = __UNCONST(va); \
711 } \ 718 } \
712} while (/*CONSTCOND*/0) 719} while (/*CONSTCOND*/0)
713 720
714#define UNDOCOMPAT(va_compat) \ 721#define UNDOCOMPAT(va_compat) \
715do { \ 722do { \
716 if (needcompat()) \ 723 if (needcompat()) \
717 rump_pub_vattr_free(va_compat); \ 724 rump_pub_vattr_free(va_compat); \
718} while (/*CONSTCOND*/0) 725} while (/*CONSTCOND*/0)
719 726
720static int 727static int
721do_makenode(struct puffs_usermount *pu, struct p2k_node *p2n_dir, 728do_makenode(struct puffs_usermount *pu, struct p2k_node *p2n_dir,
722 struct puffs_newinfo *pni, const struct puffs_cn *pcn, 729 struct puffs_newinfo *pni, const struct puffs_cn *pcn,
723 const struct vattr *vap, char *link_target, 730 const struct vattr *vap, char *link_target,
724 int (*makefn)(struct vnode *, struct vnode **, struct componentname *, 731 int (*makefn)(struct vnode *, struct vnode **, struct componentname *,
725 struct vattr *), 732 struct vattr *),
726 int (*symfn)(struct vnode *, struct vnode **, struct componentname *, 733 int (*symfn)(struct vnode *, struct vnode **, struct componentname *,
727 struct vattr *, char *)) 734 struct vattr *, char *))
728{ 735{
729 struct p2k_mount *p2m = puffs_getspecific(pu); 736 struct p2k_mount *p2m = puffs_getspecific(pu);
730 struct vnode *dvp = p2n_dir->p2n_vp; 737 struct vnode *dvp = p2n_dir->p2n_vp;
731 struct p2k_node *p2n; 738 struct p2k_node *p2n;
732 struct componentname *cn; 739 struct componentname *cn;
733 struct vattr *va_x; 740 struct vattr *va_x;
734 struct vnode *vp; 741 struct vnode *vp;
735 int rv; 742 int rv;
736 743
737 p2n = malloc(sizeof(*p2n)); 744 p2n = malloc(sizeof(*p2n));
738 if (p2n == NULL) 745 if (p2n == NULL)
739 return ENOMEM; 746 return ENOMEM;
740 DOCOMPAT(vap, va_x); 747 DOCOMPAT(vap, va_x);
741 748
742 cn = makecn(pcn); 749 cn = makecn(pcn);
743 RUMP_VOP_LOCK(dvp, LK_EXCLUSIVE); 750 RUMP_VOP_LOCK(dvp, LK_EXCLUSIVE);
744 rump_pub_vp_incref(dvp); 751 rump_pub_vp_incref(dvp);
745 if (makefn) { 752 if (makefn) {
746 rv = makefn(dvp, &vp, cn, va_x); 753 rv = makefn(dvp, &vp, cn, va_x);
747 } else { 754 } else {
748 rv = symfn(dvp, &vp, cn, va_x, link_target); 755 rv = symfn(dvp, &vp, cn, va_x, link_target);
749 } 756 }
750 assert(RUMP_VOP_ISLOCKED(dvp) == 0); 757 assert(RUMP_VOP_ISLOCKED(dvp) == 0);
751 freecn(cn); 758 freecn(cn);
752 759
753 if (rv == 0) { 760 if (rv == 0) {
754 RUMP_VOP_UNLOCK(vp); 761 RUMP_VOP_UNLOCK(vp);
755 p2n = getp2n(p2m, vp, true, p2n); 762 p2n = getp2n(p2m, vp, true, p2n);
756 puffs_newinfo_setcookie(pni, p2n); 763 puffs_newinfo_setcookie(pni, p2n);
757 } else { 764 } else {
758 free(p2n); 765 free(p2n);
759 } 766 }
760 767
761 UNDOCOMPAT(va_x); 768 UNDOCOMPAT(va_x);
762 769
763 return rv; 770 return rv;
764 771
765} 772}
766 773
767/*ARGSUSED*/ 774/*ARGSUSED*/
768int 775int
769p2k_node_create(struct puffs_usermount *pu, puffs_cookie_t opc, 776p2k_node_create(struct puffs_usermount *pu, puffs_cookie_t opc,
770 struct puffs_newinfo *pni, const struct puffs_cn *pcn, 777 struct puffs_newinfo *pni, const struct puffs_cn *pcn,
771 const struct vattr *vap) 778 const struct vattr *vap)
772{ 779{
773 780
774 return do_makenode(pu, opc, pni, pcn, vap, NULL, RUMP_VOP_CREATE, NULL); 781 return do_makenode(pu, opc, pni, pcn, vap, NULL, RUMP_VOP_CREATE, NULL);
775} 782}
776 783
777/*ARGSUSED*/ 784/*ARGSUSED*/
778int 785int
779p2k_node_mknod(struct puffs_usermount *pu, puffs_cookie_t opc, 786p2k_node_mknod(struct puffs_usermount *pu, puffs_cookie_t opc,
780 struct puffs_newinfo *pni, const struct puffs_cn *pcn, 787 struct puffs_newinfo *pni, const struct puffs_cn *pcn,
781 const struct vattr *vap) 788 const struct vattr *vap)
782{ 789{
783 790
784 return do_makenode(pu, opc, pni, pcn, vap, NULL, RUMP_VOP_MKNOD, NULL); 791 return do_makenode(pu, opc, pni, pcn, vap, NULL, RUMP_VOP_MKNOD, NULL);
785} 792}
786 793
787/*ARGSUSED*/ 794/*ARGSUSED*/
788int 795int
789p2k_node_open(struct puffs_usermount *pu, puffs_cookie_t opc, int mode, 796p2k_node_open(struct puffs_usermount *pu, puffs_cookie_t opc, int mode,
790 const struct puffs_cred *pcr) 797 const struct puffs_cred *pcr)
791{ 798{
792 struct vnode *vp = OPC2VP(opc); 799 struct vnode *vp = OPC2VP(opc);
793 struct kauth_cred *cred; 800 struct kauth_cred *cred;
794 int rv; 801 int rv;
795 802
796 cred = cred_create(pcr); 803 cred = cred_create(pcr);
797 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE); 804 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE);
798 rv = RUMP_VOP_OPEN(vp, mode, cred); 805 rv = RUMP_VOP_OPEN(vp, mode, cred);
799 RUMP_VOP_UNLOCK(vp); 806 RUMP_VOP_UNLOCK(vp);
800 cred_destroy(cred); 807 cred_destroy(cred);
801 808
802 return rv; 809 return rv;
803} 810}
804 811
805/*ARGSUSED*/ 812/*ARGSUSED*/
806int 813int
807p2k_node_close(struct puffs_usermount *pu, puffs_cookie_t opc, int flags, 814p2k_node_close(struct puffs_usermount *pu, puffs_cookie_t opc, int flags,
808 const struct puffs_cred *pcr) 815 const struct puffs_cred *pcr)
809{ 816{
810 struct vnode *vp = OPC2VP(opc); 817 struct vnode *vp = OPC2VP(opc);
811 struct kauth_cred *cred; 818 struct kauth_cred *cred;
812 819
813 cred = cred_create(pcr); 820 cred = cred_create(pcr);
814 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE); 821 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE);
815 RUMP_VOP_CLOSE(vp, flags, cred); 822 RUMP_VOP_CLOSE(vp, flags, cred);
816 RUMP_VOP_UNLOCK(vp); 823 RUMP_VOP_UNLOCK(vp);
817 cred_destroy(cred); 824 cred_destroy(cred);
818 825
819 return 0; 826 return 0;
820} 827}
821 828
822/*ARGSUSED*/ 829/*ARGSUSED*/
823int 830int
824p2k_node_access(struct puffs_usermount *pu, puffs_cookie_t opc, int mode, 831p2k_node_access(struct puffs_usermount *pu, puffs_cookie_t opc, int mode,
825 const struct puffs_cred *pcr) 832 const struct puffs_cred *pcr)
826{ 833{
827 struct vnode *vp = OPC2VP(opc); 834 struct vnode *vp = OPC2VP(opc);
828 struct kauth_cred *cred; 835 struct kauth_cred *cred;
829 int rv; 836 int rv;
830 837
831 cred = cred_create(pcr); 838 cred = cred_create(pcr);
832 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE); 839 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE);
833 rv = RUMP_VOP_ACCESS(vp, mode, cred); 840 rv = RUMP_VOP_ACCESS(vp, mode, cred);
834 RUMP_VOP_UNLOCK(vp); 841 RUMP_VOP_UNLOCK(vp);
835 cred_destroy(cred); 842 cred_destroy(cred);
836 843
837 return rv; 844 return rv;
838} 845}
839 846
840/*ARGSUSED*/ 847/*ARGSUSED*/
841int 848int
842p2k_node_getattr(struct puffs_usermount *pu, puffs_cookie_t opc, 849p2k_node_getattr(struct puffs_usermount *pu, puffs_cookie_t opc,
843 struct vattr *vap, const struct puffs_cred *pcr) 850 struct vattr *vap, const struct puffs_cred *pcr)
844{ 851{
845 struct vnode *vp = OPC2VP(opc); 852 struct vnode *vp = OPC2VP(opc);
846 struct kauth_cred *cred; 853 struct kauth_cred *cred;
847 struct vattr *va_x; 854 struct vattr *va_x;
848 int rv; 855 int rv;
849 856
850 /* "deadfs" */ 857 /* "deadfs" */
851 if (!vp) 858 if (!vp)
852 return 0; 859 return 0;
853 860
854 if (needcompat()) { 861 if (needcompat()) {
855 va_x = rump_pub_vattr_init(); 862 va_x = rump_pub_vattr_init();
856 } else { 863 } else {
857 va_x = vap; 864 va_x = vap;
858 } 865 }
859 866
860 cred = cred_create(pcr); 867 cred = cred_create(pcr);
861 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE); 868 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE);
862 rv = RUMP_VOP_GETATTR(vp, va_x, cred); 869 rv = RUMP_VOP_GETATTR(vp, va_x, cred);
863 RUMP_VOP_UNLOCK(vp); 870 RUMP_VOP_UNLOCK(vp);
864 cred_destroy(cred); 871 cred_destroy(cred);
865 872
866 if (needcompat()) { 873 if (needcompat()) {
867 rump_pub_vattr_to_vattr50(va_x, vap); 874 rump_pub_vattr_to_vattr50(va_x, vap);
868 rump_pub_vattr_free(va_x); 875 rump_pub_vattr_free(va_x);
869 } 876 }
870 877
871 return rv; 878 return rv;
872} 879}
873 880
874/*ARGSUSED*/ 881/*ARGSUSED*/
875int 882int
876p2k_node_setattr(struct puffs_usermount *pu, puffs_cookie_t opc, 883p2k_node_setattr(struct puffs_usermount *pu, puffs_cookie_t opc,
877 const struct vattr *vap, const struct puffs_cred *pcr) 884 const struct vattr *vap, const struct puffs_cred *pcr)
878{ 885{
879 struct vnode *vp = OPC2VP(opc); 886 struct vnode *vp = OPC2VP(opc);
880 struct kauth_cred *cred; 887 struct kauth_cred *cred;
881 struct vattr *va_x; 888 struct vattr *va_x;
882 int rv; 889 int rv;
883 890
884 /* "deadfs" */ 891 /* "deadfs" */
885 if (!vp) 892 if (!vp)
886 return 0; 893 return 0;
887 894
888 DOCOMPAT(vap, va_x); 895 DOCOMPAT(vap, va_x);
889 896
890 cred = cred_create(pcr); 897 cred = cred_create(pcr);
891 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE); 898 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE);
892 rv = RUMP_VOP_SETATTR(vp, va_x, cred); 899 rv = RUMP_VOP_SETATTR(vp, va_x, cred);
893 RUMP_VOP_UNLOCK(vp); 900 RUMP_VOP_UNLOCK(vp);
894 cred_destroy(cred); 901 cred_destroy(cred);
895 902
896 UNDOCOMPAT(va_x); 903 UNDOCOMPAT(va_x);
897 904
898 return rv; 905 return rv;
899} 906}
900 907
901/*ARGSUSED*/ 908/*ARGSUSED*/
902int 909int
903p2k_node_fsync(struct puffs_usermount *pu, puffs_cookie_t opc, 910p2k_node_fsync(struct puffs_usermount *pu, puffs_cookie_t opc,
904 const struct puffs_cred *pcr, int flags, off_t offlo, off_t offhi) 911 const struct puffs_cred *pcr, int flags, off_t offlo, off_t offhi)
905{ 912{
906 struct vnode *vp = OPC2VP(opc); 913 struct vnode *vp = OPC2VP(opc);
907 struct kauth_cred *cred; 914 struct kauth_cred *cred;
908 int rv; 915 int rv;
909 916
910 /* "deadfs" */ 917 /* "deadfs" */
911 if (!vp) 918 if (!vp)
912 return 0; 919 return 0;
913 920
914 cred = cred_create(pcr); 921 cred = cred_create(pcr);
915 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE); 922 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE);
916 rv = RUMP_VOP_FSYNC(vp, cred, flags, offlo, offhi); 923 rv = RUMP_VOP_FSYNC(vp, cred, flags, offlo, offhi);
917 RUMP_VOP_UNLOCK(vp); 924 RUMP_VOP_UNLOCK(vp);
918 cred_destroy(cred); 925 cred_destroy(cred);
919 926
920 return rv; 927 return rv;
921} 928}
922 929
923/*ARGSUSED*/ 930/*ARGSUSED*/
924int 931int
925p2k_node_mmap(struct puffs_usermount *pu, puffs_cookie_t opc, vm_prot_t flags, 932p2k_node_mmap(struct puffs_usermount *pu, puffs_cookie_t opc, vm_prot_t flags,
926 const struct puffs_cred *pcr) 933 const struct puffs_cred *pcr)
927{ 934{
928 struct kauth_cred *cred; 935 struct kauth_cred *cred;
929 int rv; 936 int rv;
930 937
931 cred = cred_create(pcr); 938 cred = cred_create(pcr);
932 rv = RUMP_VOP_MMAP(OPC2VP(opc), flags, cred); 939 rv = RUMP_VOP_MMAP(OPC2VP(opc), flags, cred);
933 cred_destroy(cred); 940 cred_destroy(cred);
934 941
935 return rv; 942 return rv;
936} 943}
937 944
938/*ARGSUSED*/ 945/*ARGSUSED*/
939int 946int
940p2k_node_seek(struct puffs_usermount *pu, puffs_cookie_t opc, 947p2k_node_seek(struct puffs_usermount *pu, puffs_cookie_t opc,
941 off_t oldoff, off_t newoff, const struct puffs_cred *pcr) 948 off_t oldoff, off_t newoff, const struct puffs_cred *pcr)
942{ 949{
943 struct vnode *vp = OPC2VP(opc); 950 struct vnode *vp = OPC2VP(opc);
944 struct kauth_cred *cred; 951 struct kauth_cred *cred;
945 int rv; 952 int rv;
946 953
947 cred = cred_create(pcr); 954 cred = cred_create(pcr);
948 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE); 955 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE);
949 rv = RUMP_VOP_SEEK(vp, oldoff, newoff, cred); 956 rv = RUMP_VOP_SEEK(vp, oldoff, newoff, cred);
950 RUMP_VOP_UNLOCK(vp); 957 RUMP_VOP_UNLOCK(vp);
951 cred_destroy(cred); 958 cred_destroy(cred);
952 959
953 return rv; 960 return rv;
954} 961}
955 962
956static int 963static int
957do_nukenode(struct p2k_node *p2n_dir, struct p2k_node *p2n, 964do_nukenode(struct p2k_node *p2n_dir, struct p2k_node *p2n,
958 const struct puffs_cn *pcn, 965 const struct puffs_cn *pcn,
959 int (*nukefn)(struct vnode *, struct vnode *, struct componentname *)) 966 int (*nukefn)(struct vnode *, struct vnode *, struct componentname *))
960{ 967{
961 struct vnode *dvp = p2n_dir->p2n_vp, *vp = p2n->p2n_vp; 968 struct vnode *dvp = p2n_dir->p2n_vp, *vp = p2n->p2n_vp;
962 struct componentname *cn; 969 struct componentname *cn;
963 int rv; 970 int rv;
964 971
965 cn = makecn(pcn); 972 cn = makecn(pcn);
966 RUMP_VOP_LOCK(dvp, LK_EXCLUSIVE); 973 RUMP_VOP_LOCK(dvp, LK_EXCLUSIVE);
967 rump_pub_vp_incref(dvp); 974 rump_pub_vp_incref(dvp);
968 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE); 975 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE);
969 rump_pub_vp_incref(vp); 976 rump_pub_vp_incref(vp);
970 rv = nukefn(dvp, vp, cn); 977 rv = nukefn(dvp, vp, cn);
971 assert(RUMP_VOP_ISLOCKED(dvp) == 0); 978 assert(RUMP_VOP_ISLOCKED(dvp) == 0);
972 assert(RUMP_VOP_ISLOCKED(vp) == 0); 979 assert(RUMP_VOP_ISLOCKED(vp) == 0);
973 freecn(cn); 980 freecn(cn);
974 981
975 return rv; 982 return rv;
976 983
977} 984}
978 985
979/*ARGSUSED*/ 986/*ARGSUSED*/
980int 987int
981p2k_node_remove(struct puffs_usermount *pu, puffs_cookie_t opc, 988p2k_node_remove(struct puffs_usermount *pu, puffs_cookie_t opc,
982 puffs_cookie_t targ, const struct puffs_cn *pcn) 989 puffs_cookie_t targ, const struct puffs_cn *pcn)
983{ 990{
984 991
985 return do_nukenode(opc, targ, pcn, RUMP_VOP_REMOVE); 992 return do_nukenode(opc, targ, pcn, RUMP_VOP_REMOVE);
986} 993}
987 994
988/*ARGSUSED*/ 995/*ARGSUSED*/
989int 996int
990p2k_node_link(struct puffs_usermount *pu, puffs_cookie_t opc, 997p2k_node_link(struct puffs_usermount *pu, puffs_cookie_t opc,
991 puffs_cookie_t targ, const struct puffs_cn *pcn) 998 puffs_cookie_t targ, const struct puffs_cn *pcn)
992{ 999{
993 struct vnode *dvp = OPC2VP(opc); 1000 struct vnode *dvp = OPC2VP(opc);
994 struct componentname *cn; 1001 struct componentname *cn;
995 int rv; 1002 int rv;
996 1003
997 cn = makecn(pcn); 1004 cn = makecn(pcn);
998 RUMP_VOP_LOCK(dvp, LK_EXCLUSIVE); 1005 RUMP_VOP_LOCK(dvp, LK_EXCLUSIVE);
999 rump_pub_vp_incref(dvp); 1006 rump_pub_vp_incref(dvp);
1000 rv = RUMP_VOP_LINK(dvp, OPC2VP(targ), cn); 1007 rv = RUMP_VOP_LINK(dvp, OPC2VP(targ), cn);
1001 freecn(cn); 1008 freecn(cn);
1002 1009
1003 return rv; 1010 return rv;
1004} 1011}
1005 1012
1006/*ARGSUSED*/ 1013/*ARGSUSED*/
1007int 1014int
1008p2k_node_rename(struct puffs_usermount *pu, 1015p2k_node_rename(struct puffs_usermount *pu,
1009 puffs_cookie_t src_dir, puffs_cookie_t src, 1016 puffs_cookie_t src_dir, puffs_cookie_t src,
1010 const struct puffs_cn *pcn_src, 1017 const struct puffs_cn *pcn_src,
1011 puffs_cookie_t targ_dir, puffs_cookie_t targ, 1018 puffs_cookie_t targ_dir, puffs_cookie_t targ,
1012 const struct puffs_cn *pcn_targ) 1019 const struct puffs_cn *pcn_targ)
1013{ 1020{
1014 struct vnode *dvp, *vp, *tdvp, *tvp = NULL; 1021 struct vnode *dvp, *vp, *tdvp, *tvp = NULL;
1015 struct componentname *cn_src, *cn_targ; 1022 struct componentname *cn_src, *cn_targ;
1016 int rv; 1023 int rv;
1017 1024
1018 cn_src = makecn(pcn_src); 1025 cn_src = makecn(pcn_src);
1019 cn_targ = makecn(pcn_targ); 1026 cn_targ = makecn(pcn_targ);
1020 1027
1021 dvp = OPC2VP(src_dir); 1028 dvp = OPC2VP(src_dir);
1022 vp = OPC2VP(src); 1029 vp = OPC2VP(src);
1023 tdvp = OPC2VP(targ_dir); 1030 tdvp = OPC2VP(targ_dir);
1024 if (targ) { 1031 if (targ) {
1025 tvp = OPC2VP(targ); 1032 tvp = OPC2VP(targ);
1026 } 1033 }
1027 1034
1028 rump_pub_vp_incref(dvp); 1035 rump_pub_vp_incref(dvp);
1029 rump_pub_vp_incref(vp); 1036 rump_pub_vp_incref(vp);
1030 RUMP_VOP_LOCK(tdvp, LK_EXCLUSIVE); 1037 RUMP_VOP_LOCK(tdvp, LK_EXCLUSIVE);
1031 rump_pub_vp_incref(tdvp); 1038 rump_pub_vp_incref(tdvp);
1032 if (tvp) { 1039 if (tvp) {
1033 RUMP_VOP_LOCK(tvp, LK_EXCLUSIVE); 1040 RUMP_VOP_LOCK(tvp, LK_EXCLUSIVE);
1034 rump_pub_vp_incref(tvp); 1041 rump_pub_vp_incref(tvp);
1035 } 1042 }
1036 rv = RUMP_VOP_RENAME(dvp, vp, cn_src, tdvp, tvp, cn_targ); 1043 rv = RUMP_VOP_RENAME(dvp, vp, cn_src, tdvp, tvp, cn_targ);
1037 assert(RUMP_VOP_ISLOCKED(tdvp) == 0); 1044 assert(RUMP_VOP_ISLOCKED(tdvp) == 0);
1038 if (tvp) { 1045 if (tvp) {
1039 assert(RUMP_VOP_ISLOCKED(tvp) == 0); 1046 assert(RUMP_VOP_ISLOCKED(tvp) == 0);
1040 } 1047 }
1041 freecn(cn_src); 1048 freecn(cn_src);
1042 freecn(cn_targ); 1049 freecn(cn_targ);
1043 1050
1044 return rv; 1051 return rv;
1045} 1052}
1046 1053
1047/*ARGSUSED*/ 1054/*ARGSUSED*/
1048int 1055int
1049p2k_node_mkdir(struct puffs_usermount *pu, puffs_cookie_t opc, 1056p2k_node_mkdir(struct puffs_usermount *pu, puffs_cookie_t opc,
1050 struct puffs_newinfo *pni, const struct puffs_cn *pcn, 1057 struct puffs_newinfo *pni, const struct puffs_cn *pcn,
1051 const struct vattr *vap) 1058 const struct vattr *vap)
1052{ 1059{
1053 1060
1054 return do_makenode(pu, opc, pni, pcn, vap, NULL, RUMP_VOP_MKDIR, NULL); 1061 return do_makenode(pu, opc, pni, pcn, vap, NULL, RUMP_VOP_MKDIR, NULL);
1055} 1062}
1056 1063
1057/*ARGSUSED*/ 1064/*ARGSUSED*/
1058int 1065int
1059p2k_node_rmdir(struct puffs_usermount *pu, puffs_cookie_t opc, 1066p2k_node_rmdir(struct puffs_usermount *pu, puffs_cookie_t opc,
1060 puffs_cookie_t targ, const struct puffs_cn *pcn) 1067 puffs_cookie_t targ, const struct puffs_cn *pcn)
1061{ 1068{
1062 1069
1063 return do_nukenode(opc, targ, pcn, RUMP_VOP_RMDIR); 1070 return do_nukenode(opc, targ, pcn, RUMP_VOP_RMDIR);
1064} 1071}
1065 1072
1066/*ARGSUSED*/ 1073/*ARGSUSED*/
1067int 1074int
1068p2k_node_symlink(struct puffs_usermount *pu, puffs_cookie_t opc, 1075p2k_node_symlink(struct puffs_usermount *pu, puffs_cookie_t opc,
1069 struct puffs_newinfo *pni, const struct puffs_cn *pcn, 1076 struct puffs_newinfo *pni, const struct puffs_cn *pcn,
1070 const struct vattr *vap, const char *link_target) 1077 const struct vattr *vap, const char *link_target)
1071{ 1078{
1072 1079
1073 return do_makenode(pu, opc, pni, pcn, vap, 1080 return do_makenode(pu, opc, pni, pcn, vap,
1074 __UNCONST(link_target), NULL, RUMP_VOP_SYMLINK); 1081 __UNCONST(link_target), NULL, RUMP_VOP_SYMLINK);
1075} 1082}
1076 1083
1077/*ARGSUSED*/ 1084/*ARGSUSED*/
1078int 1085int
1079p2k_node_readdir(struct puffs_usermount *pu, puffs_cookie_t opc, 1086p2k_node_readdir(struct puffs_usermount *pu, puffs_cookie_t opc,
1080 struct dirent *dent, off_t *readoff, size_t *reslen, 1087 struct dirent *dent, off_t *readoff, size_t *reslen,
1081 const struct puffs_cred *pcr, int *eofflag, 1088 const struct puffs_cred *pcr, int *eofflag,
1082 off_t *cookies, size_t *ncookies) 1089 off_t *cookies, size_t *ncookies)
1083{ 1090{
1084 struct vnode *vp = OPC2VP(opc); 1091 struct vnode *vp = OPC2VP(opc);
1085 struct kauth_cred *cred; 1092 struct kauth_cred *cred;
1086 struct uio *uio; 1093 struct uio *uio;
1087 off_t *vop_cookies; 1094 off_t *vop_cookies;
1088 int vop_ncookies; 1095 int vop_ncookies;
1089 int rv; 1096 int rv;
1090 1097
1091 cred = cred_create(pcr); 1098 cred = cred_create(pcr);
1092 uio = rump_pub_uio_setup(dent, *reslen, *readoff, RUMPUIO_READ); 1099 uio = rump_pub_uio_setup(dent, *reslen, *readoff, RUMPUIO_READ);
1093 RUMP_VOP_LOCK(vp, LK_SHARED); 1100 RUMP_VOP_LOCK(vp, LK_SHARED);
1094 if (cookies) { 1101 if (cookies) {
1095 rv = RUMP_VOP_READDIR(vp, uio, cred, eofflag, 1102 rv = RUMP_VOP_READDIR(vp, uio, cred, eofflag,
1096 &vop_cookies, &vop_ncookies); 1103 &vop_cookies, &vop_ncookies);
1097 memcpy(cookies, vop_cookies, vop_ncookies * sizeof(*cookies)); 1104 memcpy(cookies, vop_cookies, vop_ncookies * sizeof(*cookies));
1098 *ncookies = vop_ncookies; 1105 *ncookies = vop_ncookies;
1099 free(vop_cookies); 1106 free(vop_cookies);
1100 } else { 1107 } else {
1101 rv = RUMP_VOP_READDIR(vp, uio, cred, eofflag, NULL, NULL); 1108 rv = RUMP_VOP_READDIR(vp, uio, cred, eofflag, NULL, NULL);
1102 } 1109 }
1103 RUMP_VOP_UNLOCK(vp); 1110 RUMP_VOP_UNLOCK(vp);
1104 if (rv == 0) { 1111 if (rv == 0) {
1105 *reslen = rump_pub_uio_getresid(uio); 1112 *reslen = rump_pub_uio_getresid(uio);
1106 *readoff = rump_pub_uio_getoff(uio); 1113 *readoff = rump_pub_uio_getoff(uio);
1107 } 1114 }
1108 rump_pub_uio_free(uio); 1115 rump_pub_uio_free(uio);
1109 cred_destroy(cred); 1116 cred_destroy(cred);
1110 1117
1111 return rv; 1118 return rv;
1112} 1119}
1113 1120
1114/*ARGSUSED*/ 1121/*ARGSUSED*/
1115int 1122int
1116p2k_node_readlink(struct puffs_usermount *pu, puffs_cookie_t opc, 1123p2k_node_readlink(struct puffs_usermount *pu, puffs_cookie_t opc,
1117 const struct puffs_cred *pcr, char *linkname, size_t *linklen) 1124 const struct puffs_cred *pcr, char *linkname, size_t *linklen)
1118{ 1125{
1119 struct vnode *vp = OPC2VP(opc); 1126 struct vnode *vp = OPC2VP(opc);
1120 struct kauth_cred *cred; 1127 struct kauth_cred *cred;
1121 struct uio *uio; 1128 struct uio *uio;
1122 int rv; 1129 int rv;
1123 1130
1124 cred = cred_create(pcr); 1131 cred = cred_create(pcr);
1125 uio = rump_pub_uio_setup(linkname, *linklen, 0, RUMPUIO_READ); 1132 uio = rump_pub_uio_setup(linkname, *linklen, 0, RUMPUIO_READ);
1126 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE); 1133 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE);
1127 rv = RUMP_VOP_READLINK(vp, uio, cred); 1134 rv = RUMP_VOP_READLINK(vp, uio, cred);
1128 RUMP_VOP_UNLOCK(vp); 1135 RUMP_VOP_UNLOCK(vp);
1129 *linklen -= rump_pub_uio_free(uio); 1136 *linklen -= rump_pub_uio_free(uio);
1130 cred_destroy(cred); 1137 cred_destroy(cred);
1131 1138
1132 return rv; 1139 return rv;
1133} 1140}
1134 1141
1135/*ARGSUSED*/ 1142/*ARGSUSED*/
1136int 1143int
1137p2k_node_read(struct puffs_usermount *pu, puffs_cookie_t opc, 1144p2k_node_read(struct puffs_usermount *pu, puffs_cookie_t opc,
1138 uint8_t *buf, off_t offset, size_t *resid, 1145 uint8_t *buf, off_t offset, size_t *resid,
1139 const struct puffs_cred *pcr, int ioflag) 1146 const struct puffs_cred *pcr, int ioflag)
1140{ 1147{
1141 struct vnode *vp = OPC2VP(opc); 1148 struct vnode *vp = OPC2VP(opc);
1142 struct kauth_cred *cred; 1149 struct kauth_cred *cred;
1143 struct uio *uio; 1150 struct uio *uio;
1144 int rv; 1151 int rv;
1145 1152
1146 cred = cred_create(pcr); 1153 cred = cred_create(pcr);
1147 uio = rump_pub_uio_setup(buf, *resid, offset, RUMPUIO_READ); 1154 uio = rump_pub_uio_setup(buf, *resid, offset, RUMPUIO_READ);
1148 RUMP_VOP_LOCK(vp, LK_SHARED); 1155 RUMP_VOP_LOCK(vp, LK_SHARED);
1149 rv = RUMP_VOP_READ(vp, uio, ioflag, cred); 1156 rv = RUMP_VOP_READ(vp, uio, ioflag, cred);
1150 RUMP_VOP_UNLOCK(vp); 1157 RUMP_VOP_UNLOCK(vp);
1151 *resid = rump_pub_uio_free(uio); 1158 *resid = rump_pub_uio_free(uio);
1152 cred_destroy(cred); 1159 cred_destroy(cred);
1153 1160
1154 return rv; 1161 return rv;
1155} 1162}
1156 1163
1157/*ARGSUSED*/ 1164/*ARGSUSED*/
1158int 1165int
1159p2k_node_write(struct puffs_usermount *pu, puffs_cookie_t opc, 1166p2k_node_write(struct puffs_usermount *pu, puffs_cookie_t opc,
1160 uint8_t *buf, off_t offset, size_t *resid, 1167 uint8_t *buf, off_t offset, size_t *resid,
1161 const struct puffs_cred *pcr, int ioflag) 1168 const struct puffs_cred *pcr, int ioflag)
1162{ 1169{
1163 struct vnode *vp = OPC2VP(opc); 1170 struct vnode *vp = OPC2VP(opc);
1164 struct kauth_cred *cred; 1171 struct kauth_cred *cred;
1165 struct uio *uio; 1172 struct uio *uio;
1166 int rv; 1173 int rv;
1167 1174
1168 /* "deadfs" */ 1175 /* "deadfs" */
1169 if (!vp) 1176 if (!vp)
1170 return 0; 1177 return 0;
1171 1178
1172 cred = cred_create(pcr); 1179 cred = cred_create(pcr);
1173 uio = rump_pub_uio_setup(buf, *resid, offset, RUMPUIO_WRITE); 1180 uio = rump_pub_uio_setup(buf, *resid, offset, RUMPUIO_WRITE);
1174 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE); 1181 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE);
1175 rv = RUMP_VOP_WRITE(vp, uio, ioflag, cred); 1182 rv = RUMP_VOP_WRITE(vp, uio, ioflag, cred);
1176 RUMP_VOP_UNLOCK(vp); 1183 RUMP_VOP_UNLOCK(vp);
1177 *resid = rump_pub_uio_free(uio); 1184 *resid = rump_pub_uio_free(uio);
1178 cred_destroy(cred); 1185 cred_destroy(cred);
1179 1186
1180 return rv; 1187 return rv;
1181} 1188}
1182 1189
1183/*ARGSUSED*/ 1190/*ARGSUSED*/
1184int 1191int
1185p2k_node_pathconf(struct puffs_usermount *pu, puffs_cookie_t opc, 1192p2k_node_pathconf(struct puffs_usermount *pu, puffs_cookie_t opc,
1186 int name, register_t *retval) 1193 int name, register_t *retval)
1187{ 1194{
1188 struct vnode *vp = OPC2VP(opc); 1195 struct vnode *vp = OPC2VP(opc);
1189 int rv; 1196 int rv;
1190 1197
1191 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE); 1198 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE);
1192 rv = RUMP_VOP_PATHCONF(vp, name, retval); 1199 rv = RUMP_VOP_PATHCONF(vp, name, retval);
1193 RUMP_VOP_UNLOCK(vp); 1200 RUMP_VOP_UNLOCK(vp);
1194 1201
1195 return rv; 1202 return rv;
1196} 1203}
1197 1204
1198/*ARGSUSED*/ 1205/*ARGSUSED*/
1199int 1206int
1200p2k_node_getextattr(struct puffs_usermount *pu, puffs_cookie_t opc, 1207p2k_node_getextattr(struct puffs_usermount *pu, puffs_cookie_t opc,
1201 int attrnamespace, const char *attrname, size_t *attrsize, 1208 int attrnamespace, const char *attrname, size_t *attrsize,
1202 uint8_t *attr, size_t *resid, const struct puffs_cred *pcr) 1209 uint8_t *attr, size_t *resid, const struct puffs_cred *pcr)
1203{ 1210{
1204 struct vnode *vp = OPC2VP(opc); 1211 struct vnode *vp = OPC2VP(opc);
1205 struct kauth_cred *cred; 1212 struct kauth_cred *cred;
1206 struct uio *uio; 1213 struct uio *uio;
1207 int rv; 1214 int rv;
1208 1215
1209 if (attr) 1216 if (attr)
1210 uio = rump_pub_uio_setup(attr, *resid, 0, RUMPUIO_READ); 1217 uio = rump_pub_uio_setup(attr, *resid, 0, RUMPUIO_READ);
1211 else 1218 else
1212 uio = NULL; 1219 uio = NULL;
1213 1220
1214 cred = cred_create(pcr); 1221 cred = cred_create(pcr);
1215 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE); 1222 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE);
1216 rv = RUMP_VOP_GETEXTATTR(vp, attrnamespace, attrname, uio, 1223 rv = RUMP_VOP_GETEXTATTR(vp, attrnamespace, attrname, uio,
1217 attrsize, cred); 1224 attrsize, cred);
1218 RUMP_VOP_UNLOCK(vp); 1225 RUMP_VOP_UNLOCK(vp);
1219 cred_destroy(cred); 1226 cred_destroy(cred);
1220 1227
1221 if (uio) 1228 if (uio)
1222 *resid = rump_pub_uio_free(uio); 1229 *resid = rump_pub_uio_free(uio);
1223 1230
1224 return rv; 1231 return rv;
1225} 1232}
1226 1233
1227/*ARGSUSED*/ 1234/*ARGSUSED*/
1228int 1235int
1229p2k_node_setextattr(struct puffs_usermount *pu, puffs_cookie_t opc, 1236p2k_node_setextattr(struct puffs_usermount *pu, puffs_cookie_t opc,
1230 int attrnamespace, const char *attrname, 1237 int attrnamespace, const char *attrname,
1231 uint8_t *attr, size_t *resid, const struct puffs_cred *pcr) 1238 uint8_t *attr, size_t *resid, const struct puffs_cred *pcr)
1232{ 1239{
1233 struct vnode *vp = OPC2VP(opc); 1240 struct vnode *vp = OPC2VP(opc);
1234 struct kauth_cred *cred; 1241 struct kauth_cred *cred;
1235 struct uio *uio; 1242 struct uio *uio;
1236 int rv; 1243 int rv;
1237 1244
1238 if (attr) 1245 if (attr)
1239 uio = rump_pub_uio_setup(attr, *resid, 0, RUMPUIO_READ); 1246 uio = rump_pub_uio_setup(attr, *resid, 0, RUMPUIO_READ);
1240 else 1247 else
1241 uio = NULL; 1248 uio = NULL;
1242 1249
1243 cred = cred_create(pcr); 1250 cred = cred_create(pcr);
1244 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE); 1251 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE);
1245 rv = RUMP_VOP_SETEXTATTR(vp, attrnamespace, attrname, uio, cred); 1252 rv = RUMP_VOP_SETEXTATTR(vp, attrnamespace, attrname, uio, cred);
1246 RUMP_VOP_UNLOCK(vp); 1253 RUMP_VOP_UNLOCK(vp);
1247 cred_destroy(cred); 1254 cred_destroy(cred);
1248 1255
1249 if (uio) 1256 if (uio)
1250 *resid = rump_pub_uio_free(uio); 1257 *resid = rump_pub_uio_free(uio);
1251 1258
1252 return rv; 1259 return rv;
1253} 1260}
1254 1261
1255/*ARGSUSED*/ 1262/*ARGSUSED*/
1256int 1263int
1257p2k_node_listextattr(struct puffs_usermount *pu, puffs_cookie_t opc, 1264p2k_node_listextattr(struct puffs_usermount *pu, puffs_cookie_t opc,
1258 int attrnamespace, size_t *attrsize, 1265 int attrnamespace, size_t *attrsize,
1259 uint8_t *attrs, size_t *resid, const struct puffs_cred *pcr) 1266 uint8_t *attrs, size_t *resid, const struct puffs_cred *pcr)
1260{ 1267{
1261 struct vnode *vp = OPC2VP(opc); 1268 struct vnode *vp = OPC2VP(opc);
1262 struct kauth_cred *cred; 1269 struct kauth_cred *cred;
1263 struct uio *uio; 1270 struct uio *uio;
1264 int rv; 1271 int rv;
1265 1272
1266 if (attrs) 1273 if (attrs)
1267 uio = rump_pub_uio_setup(attrs, *resid, 0, RUMPUIO_READ); 1274 uio = rump_pub_uio_setup(attrs, *resid, 0, RUMPUIO_READ);
1268 else 1275 else
1269 uio = NULL; 1276 uio = NULL;
1270 1277
1271 cred = cred_create(pcr); 1278 cred = cred_create(pcr);
1272 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE); 1279 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE);
1273 rv = RUMP_VOP_LISTEXTATTR(vp, attrnamespace, uio, attrsize, cred); 1280 rv = RUMP_VOP_LISTEXTATTR(vp, attrnamespace, uio, attrsize, cred);
1274 RUMP_VOP_UNLOCK(vp); 1281 RUMP_VOP_UNLOCK(vp);
1275 cred_destroy(cred); 1282 cred_destroy(cred);
1276 1283
1277 if (uio) 1284 if (uio)
1278 *resid = rump_pub_uio_free(uio); 1285 *resid = rump_pub_uio_free(uio);
1279 1286
1280 return rv; 1287 return rv;
1281} 1288}
1282 1289
1283/*ARGSUSED*/ 1290/*ARGSUSED*/
1284int 1291int
1285p2k_node_deleteextattr(struct puffs_usermount *pu, puffs_cookie_t opc, 1292p2k_node_deleteextattr(struct puffs_usermount *pu, puffs_cookie_t opc,
1286 int attrnamespace, const char *attrname, const struct puffs_cred *pcr) 1293 int attrnamespace, const char *attrname, const struct puffs_cred *pcr)
1287{ 1294{
1288 struct vnode *vp = OPC2VP(opc); 1295 struct vnode *vp = OPC2VP(opc);
1289 struct kauth_cred *cred; 1296 struct kauth_cred *cred;
1290 int rv; 1297 int rv;
1291 1298
1292 cred = cred_create(pcr); 1299 cred = cred_create(pcr);
1293 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE); 1300 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE);
1294 rv = RUMP_VOP_DELETEEXTATTR(vp, attrnamespace, attrname, cred); 1301 rv = RUMP_VOP_DELETEEXTATTR(vp, attrnamespace, attrname, cred);
1295 RUMP_VOP_UNLOCK(vp); 1302 RUMP_VOP_UNLOCK(vp);
1296 cred_destroy(cred); 1303 cred_destroy(cred);
1297 1304
1298 return rv; 1305 return rv;
1299} 1306}
1300 1307
1301/* the kernel releases its last reference here */  1308/* the kernel releases its last reference here */
1302int 1309int
1303p2k_node_inactive(struct puffs_usermount *pu, puffs_cookie_t opc) 1310p2k_node_inactive(struct puffs_usermount *pu, puffs_cookie_t opc)
1304{ 1311{
1305 struct p2k_mount *p2m = puffs_getspecific(pu); 1312 struct p2k_mount *p2m = puffs_getspecific(pu);
1306 struct p2k_node *p2n = opc; 1313 struct p2k_node *p2n = opc;
1307 struct vnode *vp = OPC2VP(opc); 1314 struct vnode *vp = OPC2VP(opc);
1308 bool recycle = false; 1315 bool recycle = false;
1309 int rv; 1316 int rv;
1310 1317
1311 /* deadfs */ 1318 /* deadfs */
1312 if (!vp) 1319 if (!vp)
1313 return 0; 1320 return 0;
1314 1321
1315 /* 1322 /*
1316 * Flush all cached vnode pages from the rump kernel -- they 1323 * Flush all cached vnode pages from the rump kernel -- they
1317 * are kept in puffs for all things that matter. However, 1324 * are kept in puffs for all things that matter. However,
1318 * don't do this for tmpfs (vnodes are backed by an aobj), since that 1325 * don't do this for tmpfs (vnodes are backed by an aobj), since that
1319 * would cause us to clear the backing storage leaving us without 1326 * would cause us to clear the backing storage leaving us without
1320 * a way to regain the data from "stable storage". 1327 * a way to regain the data from "stable storage".
1321 */ 1328 */
1322 if (!p2m->p2m_imtmpfsman) { 1329 if (!p2m->p2m_imtmpfsman) {
1323 rump_pub_vp_interlock(vp); 1330 rump_pub_vp_interlock(vp);
1324 RUMP_VOP_PUTPAGES(vp, 0, 0, 1331 RUMP_VOP_PUTPAGES(vp, 0, 0,
1325 PGO_ALLPAGES|PGO_CLEANIT|PGO_FREE); 1332 PGO_ALLPAGES|PGO_CLEANIT|PGO_FREE);
1326 } 1333 }
1327 1334
1328 /* 1335 /*
1329 * Ok, this is where we get nasty. We pretend the vnode is 1336 * Ok, this is where we get nasty. We pretend the vnode is
1330 * inactive and already tell the file system that. However, 1337 * inactive and already tell the file system that. However,
1331 * we are allowed to pretend it also grows a reference immediately 1338 * we are allowed to pretend it also grows a reference immediately
1332 * after per vget(), so this does not do harm. Cheap trick, but ... 1339 * after per vget(), so this does not do harm. Cheap trick, but ...
1333 * 1340 *
1334 * If the file system thinks the inode is done for, we release 1341 * If the file system thinks the inode is done for, we release
1335 * our reference and clear all knowledge of the vnode. If, 1342 * our reference and clear all knowledge of the vnode. If,
1336 * however, the inode is still active, we retain our reference 1343 * however, the inode is still active, we retain our reference
1337 * until reclaim, since puffs might be flushing out some data 1344 * until reclaim, since puffs might be flushing out some data
1338 * later. 1345 * later.
1339 */ 1346 */
1340 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE); 1347 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE);
1341 rv = RUMP_VOP_INACTIVE(vp, &recycle); 1348 rv = RUMP_VOP_INACTIVE(vp, &recycle);
1342 if (recycle) { 1349 if (recycle) {
1343 puffs_setback(puffs_cc_getcc(pu), PUFFS_SETBACK_NOREF_N1); 1350 puffs_setback(puffs_cc_getcc(pu), PUFFS_SETBACK_NOREF_N1);
1344 rump_pub_vp_rele(p2n->p2n_vp); 1351 rump_pub_vp_rele(p2n->p2n_vp);
1345 p2n->p2n_vp = NULL; 1352 p2n->p2n_vp = NULL;
1346 } 1353 }
1347 1354
1348 return rv; 1355 return rv;
1349} 1356}
1350 1357
1351/*ARGSUSED*/ 1358/*ARGSUSED*/
1352int 1359int
1353p2k_node_reclaim(struct puffs_usermount *pu, puffs_croissant_t opc) 1360p2k_node_reclaim(struct puffs_usermount *pu, puffs_croissant_t opc)
1354{ 1361{
1355 struct p2k_node *p2n = opc; 1362 struct p2k_node *p2n = opc;
1356 1363
1357 if (p2n->p2n_vp) { 1364 if (p2n->p2n_vp) {
1358 rump_pub_vp_rele(p2n->p2n_vp); 1365 rump_pub_vp_rele(p2n->p2n_vp);
1359 p2n->p2n_vp = NULL; 1366 p2n->p2n_vp = NULL;
1360 } 1367 }
1361 1368
1362 freep2n(p2n); 1369 freep2n(p2n);
1363 return 0; 1370 return 0;
1364} 1371}