Sat Jan 23 16:39:31 2016 UTC ()
Don't include <sys/vnode.h> to get the pager constants.


(christos)
diff -r1.66 -r1.67 src/lib/libp2k/p2k.c

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

--- src/lib/libp2k/p2k.c 2015/04/20 23:03:07 1.66
+++ src/lib/libp2k/p2k.c 2016/01/23 16:39:31 1.67
@@ -1,1063 +1,1064 @@ @@ -1,1063 +1,1064 @@
1/* $NetBSD: p2k.c,v 1.66 2015/04/20 23:03:07 riastradh Exp $ */ 1/* $NetBSD: p2k.c,v 1.67 2016/01/23 16:39:31 christos 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> 
50#include <sys/lock.h> 49#include <sys/lock.h>
51#include <sys/namei.h> 50#include <sys/namei.h>
52#include <sys/dirent.h> 51#include <sys/dirent.h>
53#include <sys/hash.h> 52#include <sys/hash.h>
54 53
55#include <assert.h> 54#include <assert.h>
56#include <errno.h> 55#include <errno.h>
57#include <puffs.h> 56#include <puffs.h>
58#include <stdlib.h> 57#include <stdlib.h>
59#include <stdio.h> 58#include <stdio.h>
60 59
61#include <rump/rump.h> 60#include <rump/rump.h>
62#include <rump/p2k.h> 61#include <rump/p2k.h>
63#include <rump/ukfs.h> 62#include <rump/ukfs.h>
64 63
 64#include <uvm/uvm_pager.h>
 65
65/* NetBSD-5 compat */ 66/* NetBSD-5 compat */
66#ifndef MOUNT_RUMPFS 67#ifndef MOUNT_RUMPFS
67#define MOUNT_RUMPFS "rumpfs" 68#define MOUNT_RUMPFS "rumpfs"
68#endif 69#endif
69 70
70PUFFSOP_PROTOS(p2k) 71PUFFSOP_PROTOS(p2k)
71 72
72LIST_HEAD(p2k_vp_hash, p2k_node); 73LIST_HEAD(p2k_vp_hash, p2k_node);
73#define NHASHBUCK (1<<16) 74#define NHASHBUCK (1<<16)
74struct p2k_mount { 75struct p2k_mount {
75 struct vnode *p2m_rvp; 76 struct vnode *p2m_rvp;
76 struct puffs_usermount *p2m_pu; 77 struct puffs_usermount *p2m_pu;
77 struct ukfs *p2m_ukfs; 78 struct ukfs *p2m_ukfs;
78 struct p2k_vp_hash p2m_vphash[NHASHBUCK]; 79 struct p2k_vp_hash p2m_vphash[NHASHBUCK];
79 struct mount *p2m_mp; 80 struct mount *p2m_mp;
80 int p2m_nvnodes; 81 int p2m_nvnodes;
81 int p2m_imtmpfsman; 82 int p2m_imtmpfsman;
82 bool p2m_hasdebug; 83 bool p2m_hasdebug;
83}; 84};
84 85
85struct p2k_node { 86struct p2k_node {
86 struct puffs_node p2n_pn; 87 struct puffs_node p2n_pn;
87 struct vnode *p2n_vp; 88 struct vnode *p2n_vp;
88 89
89 LIST_ENTRY(p2k_node) p2n_entries; 90 LIST_ENTRY(p2k_node) p2n_entries;
90}; 91};
91 92
92#define OPC2VP(opc) (((struct p2k_node *)opc)->p2n_vp) 93#define OPC2VP(opc) (((struct p2k_node *)opc)->p2n_vp)
93 94
94static int haswizard; 95static int haswizard;
95static uid_t wizarduid; 96static uid_t wizarduid;
96 97
97static struct kauth_cred * 98static struct kauth_cred *
98cred_create(const struct puffs_cred *pcr) 99cred_create(const struct puffs_cred *pcr)
99{ 100{
100 gid_t groups[NGROUPS]; 101 gid_t groups[NGROUPS];
101 uid_t uid; 102 uid_t uid;
102 gid_t gid; 103 gid_t gid;
103 short ngroups = __arraycount(groups); 104 short ngroups = __arraycount(groups);
104 105
105 if (haswizard) { 106 if (haswizard) {
106 uid = wizarduid; 107 uid = wizarduid;
107 } else { 108 } else {
108 if (puffs_cred_getuid(pcr, &uid) == -1) 109 if (puffs_cred_getuid(pcr, &uid) == -1)
109 uid = 0; 110 uid = 0;
110 } 111 }
111 if (puffs_cred_getgid(pcr, &gid) == -1) 112 if (puffs_cred_getgid(pcr, &gid) == -1)
112 gid = 0; 113 gid = 0;
113 puffs_cred_getgroups(pcr, groups, &ngroups); 114 puffs_cred_getgroups(pcr, groups, &ngroups);
114 115
115 /* LINTED: ngroups is ok */ 116 /* LINTED: ngroups is ok */
116 return rump_pub_cred_create(uid, gid, ngroups, groups); 117 return rump_pub_cred_create(uid, gid, ngroups, groups);
117} 118}
118 119
119static __inline void 120static __inline void
120cred_destroy(struct kauth_cred *cred) 121cred_destroy(struct kauth_cred *cred)
121{ 122{
122 123
123 rump_pub_cred_put(cred); 124 rump_pub_cred_put(cred);
124} 125}
125 126
126static struct componentname * 127static struct componentname *
127makecn(const struct puffs_cn *pcn) 128makecn(const struct puffs_cn *pcn)
128{ 129{
129 struct kauth_cred *cred; 130 struct kauth_cred *cred;
130 131
131 cred = cred_create(pcn->pcn_cred); 132 cred = cred_create(pcn->pcn_cred);
132 /* LINTED: prehistoric types in first two args */ 133 /* LINTED: prehistoric types in first two args */
133 return rump_pub_makecn(pcn->pcn_nameiop, pcn->pcn_flags, 134 return rump_pub_makecn(pcn->pcn_nameiop, pcn->pcn_flags,
134 pcn->pcn_name, pcn->pcn_namelen, cred, rump_pub_lwproc_curlwp()); 135 pcn->pcn_name, pcn->pcn_namelen, cred, rump_pub_lwproc_curlwp());
135} 136}
136 137
137static __inline void 138static __inline void
138freecn(struct componentname *cnp) 139freecn(struct componentname *cnp)
139{ 140{
140 141
141 rump_pub_freecn(cnp, RUMPCN_FREECRED); 142 rump_pub_freecn(cnp, RUMPCN_FREECRED);
142} 143}
143 144
144static void 145static void
145makelwp(struct puffs_usermount *pu) 146makelwp(struct puffs_usermount *pu)
146{ 147{
147 pid_t pid; 148 pid_t pid;
148 lwpid_t lid; 149 lwpid_t lid;
149 150
150 puffs_cc_getcaller(puffs_cc_getcc(pu), &pid, &lid); 151 puffs_cc_getcaller(puffs_cc_getcc(pu), &pid, &lid);
151 rump_pub_allbetsareoff_setid(pid, lid); 152 rump_pub_allbetsareoff_setid(pid, lid);
152} 153}
153 154
154static volatile sig_atomic_t dodump; 155static volatile sig_atomic_t dodump;
155static void 156static void
156dumpmp(struct puffs_usermount *pu) 157dumpmp(struct puffs_usermount *pu)
157{ 158{
158 struct statvfs svfsb; 159 struct statvfs svfsb;
159 160
160 if (dodump && p2k_fs_statvfs(pu, &svfsb) == 0) { 161 if (dodump && p2k_fs_statvfs(pu, &svfsb) == 0) {
161 rump_pub_vfs_mount_print(svfsb.f_mntonname, dodump-1); 162 rump_pub_vfs_mount_print(svfsb.f_mntonname, dodump-1);
162 } 163 }
163 164
164 dodump = 0; 165 dodump = 0;
165} 166}
166 167
167static void 168static void
168sighand(int sig) 169sighand(int sig)
169{ 170{
170 171
171 if (sig == SIGINFO) 172 if (sig == SIGINFO)
172 dodump = 1; 173 dodump = 1;
173 else if (sig == SIGUSR1) 174 else if (sig == SIGUSR1)
174 dodump = 2; 175 dodump = 2;
175} 176}
176 177
177static __inline struct p2k_vp_hash * 178static __inline struct p2k_vp_hash *
178gethash(struct p2k_mount *p2m, struct vnode *vp) 179gethash(struct p2k_mount *p2m, struct vnode *vp)
179{ 180{
180 uint32_t hash; 181 uint32_t hash;
181 182
182 hash = hash32_buf(&vp, sizeof(vp), HASH32_BUF_INIT); 183 hash = hash32_buf(&vp, sizeof(vp), HASH32_BUF_INIT);
183 return &p2m->p2m_vphash[hash % NHASHBUCK]; 184 return &p2m->p2m_vphash[hash % NHASHBUCK];
184} 185}
185 186
186/* 187/*
187 * Find node based on hash of vnode pointer. If vnode is found, 188 * Find node based on hash of vnode pointer. If vnode is found,
188 * releases one reference to vnode based on the fact that we just 189 * releases one reference to vnode based on the fact that we just
189 * performed a lookup for it. 190 * performed a lookup for it.
190 * 191 *
191 * If the optinal p2n_storage parameter is passed, it is used instead 192 * If the optinal p2n_storage parameter is passed, it is used instead
192 * of allocating more memory. This allows for easier error recovery. 193 * of allocating more memory. This allows for easier error recovery.
193 */ 194 */
194static struct p2k_node * 195static struct p2k_node *
195getp2n(struct p2k_mount *p2m, struct vnode *vp, bool initial, 196getp2n(struct p2k_mount *p2m, struct vnode *vp, bool initial,
196 struct p2k_node *p2n_storage) 197 struct p2k_node *p2n_storage)
197{ 198{
198 struct p2k_vp_hash *hl; 199 struct p2k_vp_hash *hl;
199 struct p2k_node *p2n = NULL; 200 struct p2k_node *p2n = NULL;
200 201
201 /* p2n_storage => initial */ 202 /* p2n_storage => initial */
202 assert(!p2n_storage || initial); 203 assert(!p2n_storage || initial);
203 204
204 hl = gethash(p2m, vp); 205 hl = gethash(p2m, vp);
205 if (!initial) 206 if (!initial)
206 LIST_FOREACH(p2n, hl, p2n_entries) 207 LIST_FOREACH(p2n, hl, p2n_entries)
207 if (p2n->p2n_vp == vp) 208 if (p2n->p2n_vp == vp)
208 break; 209 break;
209 210
210 hl = gethash(p2m, vp); 211 hl = gethash(p2m, vp);
211 if (p2n) { 212 if (p2n) {
212 rump_pub_vp_rele(vp); 213 rump_pub_vp_rele(vp);
213 } else { 214 } else {
214 if (p2n_storage) 215 if (p2n_storage)
215 p2n = p2n_storage; 216 p2n = p2n_storage;
216 else 217 else
217 p2n = malloc(sizeof(*p2n)); 218 p2n = malloc(sizeof(*p2n));
218 if (!p2n) { 219 if (!p2n) {
219 rump_pub_vp_rele(vp); 220 rump_pub_vp_rele(vp);
220 return NULL; 221 return NULL;
221 } 222 }
222 memset(p2n, 0, sizeof(*p2n)); 223 memset(p2n, 0, sizeof(*p2n));
223 LIST_INSERT_HEAD(hl, p2n, p2n_entries); 224 LIST_INSERT_HEAD(hl, p2n, p2n_entries);
224 p2n->p2n_vp = vp; 225 p2n->p2n_vp = vp;
225 } 226 }
226 return p2n; 227 return p2n;
227} 228}
228 229
229static void 230static void
230freep2n(struct p2k_node *p2n) 231freep2n(struct p2k_node *p2n)
231{ 232{
232 233
233 assert(p2n->p2n_vp == NULL); 234 assert(p2n->p2n_vp == NULL);
234 LIST_REMOVE(p2n, p2n_entries); 235 LIST_REMOVE(p2n, p2n_entries);
235 free(p2n); 236 free(p2n);
236} 237}
237 238
238/*ARGSUSED*/ 239/*ARGSUSED*/
239static void 240static void
240p2k_errcatcher(struct puffs_usermount *pu, uint8_t type, int error, 241p2k_errcatcher(struct puffs_usermount *pu, uint8_t type, int error,
241 const char *str, puffs_cookie_t cook) 242 const char *str, puffs_cookie_t cook)
242{ 243{
243 244
244 fprintf(stderr, "type %d, error %d, cookie %p (%s)\n", 245 fprintf(stderr, "type %d, error %d, cookie %p (%s)\n",
245 type, error, cook, str); 246 type, error, cook, str);
246 247
247 /* 248 /*
248 * Trap all EINVAL responses to lookup. It most likely means 249 * Trap all EINVAL responses to lookup. It most likely means
249 * that we supplied VNON/VBAD as the type. The real kernel 250 * that we supplied VNON/VBAD as the type. The real kernel
250 * doesn't panic from this either, but just handles it. 251 * doesn't panic from this either, but just handles it.
251 */ 252 */
252 if (type != PUFFS_VN_LOOKUP && error == EINVAL) 253 if (type != PUFFS_VN_LOOKUP && error == EINVAL)
253 abort(); 254 abort();
254} 255}
255 256
256/* just to avoid annoying loop when singlestepping */ 257/* just to avoid annoying loop when singlestepping */
257static struct p2k_mount * 258static struct p2k_mount *
258allocp2m(void) 259allocp2m(void)
259{ 260{
260 struct p2k_mount *p2m; 261 struct p2k_mount *p2m;
261 int i; 262 int i;
262 263
263 p2m = malloc(sizeof(*p2m)); 264 p2m = malloc(sizeof(*p2m));
264 if (p2m == NULL) 265 if (p2m == NULL)
265 return NULL; 266 return NULL;
266 memset(p2m, 0, sizeof(*p2m)); 267 memset(p2m, 0, sizeof(*p2m));
267 268
268 for (i = 0; i < NHASHBUCK; i++) 269 for (i = 0; i < NHASHBUCK; i++)
269 LIST_INIT(&p2m->p2m_vphash[i]); 270 LIST_INIT(&p2m->p2m_vphash[i]);
270 271
271 return p2m; 272 return p2m;
272} 273}
273 274
274struct p2k_mount * 275struct p2k_mount *
275p2k_init(uint32_t puffs_flags) 276p2k_init(uint32_t puffs_flags)
276{ 277{
277 struct puffs_ops *pops; 278 struct puffs_ops *pops;
278 struct p2k_mount *p2m; 279 struct p2k_mount *p2m;
279 char *envbuf; 280 char *envbuf;
280 bool dodaemon; 281 bool dodaemon;
281 bool hasdebug; 282 bool hasdebug;
282 283
283 PUFFSOP_INIT(pops); 284 PUFFSOP_INIT(pops);
284 285
285 PUFFSOP_SET(pops, p2k, fs, statvfs); 286 PUFFSOP_SET(pops, p2k, fs, statvfs);
286 PUFFSOP_SET(pops, p2k, fs, unmount); 287 PUFFSOP_SET(pops, p2k, fs, unmount);
287 PUFFSOP_SET(pops, p2k, fs, sync); 288 PUFFSOP_SET(pops, p2k, fs, sync);
288 PUFFSOP_SET(pops, p2k, fs, fhtonode); 289 PUFFSOP_SET(pops, p2k, fs, fhtonode);
289 PUFFSOP_SET(pops, p2k, fs, nodetofh); 290 PUFFSOP_SET(pops, p2k, fs, nodetofh);
290 PUFFSOP_SET(pops, p2k, fs, extattrctl); 291 PUFFSOP_SET(pops, p2k, fs, extattrctl);
291 292
292 PUFFSOP_SET(pops, p2k, node, lookup); 293 PUFFSOP_SET(pops, p2k, node, lookup);
293 PUFFSOP_SET(pops, p2k, node, create); 294 PUFFSOP_SET(pops, p2k, node, create);
294 PUFFSOP_SET(pops, p2k, node, mknod); 295 PUFFSOP_SET(pops, p2k, node, mknod);
295 PUFFSOP_SET(pops, p2k, node, open); 296 PUFFSOP_SET(pops, p2k, node, open);
296 PUFFSOP_SET(pops, p2k, node, close); 297 PUFFSOP_SET(pops, p2k, node, close);
297 PUFFSOP_SET(pops, p2k, node, access); 298 PUFFSOP_SET(pops, p2k, node, access);
298 PUFFSOP_SET(pops, p2k, node, getattr); 299 PUFFSOP_SET(pops, p2k, node, getattr);
299 PUFFSOP_SET(pops, p2k, node, setattr); 300 PUFFSOP_SET(pops, p2k, node, setattr);
300#if 0 301#if 0
301 PUFFSOP_SET(pops, p2k, node, poll); 302 PUFFSOP_SET(pops, p2k, node, poll);
302#endif 303#endif
303 PUFFSOP_SET(pops, p2k, node, mmap); 304 PUFFSOP_SET(pops, p2k, node, mmap);
304 PUFFSOP_SET(pops, p2k, node, fsync); 305 PUFFSOP_SET(pops, p2k, node, fsync);
305 PUFFSOP_SET(pops, p2k, node, seek); 306 PUFFSOP_SET(pops, p2k, node, seek);
306 PUFFSOP_SET(pops, p2k, node, remove); 307 PUFFSOP_SET(pops, p2k, node, remove);
307 PUFFSOP_SET(pops, p2k, node, link); 308 PUFFSOP_SET(pops, p2k, node, link);
308 PUFFSOP_SET(pops, p2k, node, rename); 309 PUFFSOP_SET(pops, p2k, node, rename);
309 PUFFSOP_SET(pops, p2k, node, mkdir); 310 PUFFSOP_SET(pops, p2k, node, mkdir);
310 PUFFSOP_SET(pops, p2k, node, rmdir); 311 PUFFSOP_SET(pops, p2k, node, rmdir);
311 PUFFSOP_SET(pops, p2k, node, symlink); 312 PUFFSOP_SET(pops, p2k, node, symlink);
312 PUFFSOP_SET(pops, p2k, node, readdir); 313 PUFFSOP_SET(pops, p2k, node, readdir);
313 PUFFSOP_SET(pops, p2k, node, readlink); 314 PUFFSOP_SET(pops, p2k, node, readlink);
314 PUFFSOP_SET(pops, p2k, node, read); 315 PUFFSOP_SET(pops, p2k, node, read);
315 PUFFSOP_SET(pops, p2k, node, write); 316 PUFFSOP_SET(pops, p2k, node, write);
316 317
317 PUFFSOP_SET(pops, p2k, node, pathconf); 318 PUFFSOP_SET(pops, p2k, node, pathconf);
318 319
319 PUFFSOP_SET(pops, p2k, node, inactive); 320 PUFFSOP_SET(pops, p2k, node, inactive);
320 PUFFSOP_SET(pops, p2k, node, reclaim); 321 PUFFSOP_SET(pops, p2k, node, reclaim);
321 322
322 PUFFSOP_SET(pops, p2k, node, getextattr); 323 PUFFSOP_SET(pops, p2k, node, getextattr);
323 PUFFSOP_SET(pops, p2k, node, setextattr); 324 PUFFSOP_SET(pops, p2k, node, setextattr);
324 PUFFSOP_SET(pops, p2k, node, listextattr); 325 PUFFSOP_SET(pops, p2k, node, listextattr);
325 PUFFSOP_SET(pops, p2k, node, deleteextattr); 326 PUFFSOP_SET(pops, p2k, node, deleteextattr);
326 327
327 dodaemon = true; 328 dodaemon = true;
328 hasdebug = false; 329 hasdebug = false;
329 330
330 if (getenv("P2K_DEBUG") != NULL) { 331 if (getenv("P2K_DEBUG") != NULL) {
331 puffs_flags |= PUFFS_FLAG_OPDUMP; 332 puffs_flags |= PUFFS_FLAG_OPDUMP;
332 dodaemon = false; 333 dodaemon = false;
333 hasdebug = true; 334 hasdebug = true;
334 } 335 }
335 if (getenv("P2K_NODETACH") != NULL) { 336 if (getenv("P2K_NODETACH") != NULL) {
336 dodaemon = false; 337 dodaemon = false;
337 } 338 }
338 if (getenv("P2K_NOCACHE_PAGE") != NULL) { 339 if (getenv("P2K_NOCACHE_PAGE") != NULL) {
339 puffs_flags |= PUFFS_KFLAG_NOCACHE_PAGE; 340 puffs_flags |= PUFFS_KFLAG_NOCACHE_PAGE;
340 } 341 }
341 if (getenv("P2K_NOCACHE_NAME") != NULL) { 342 if (getenv("P2K_NOCACHE_NAME") != NULL) {
342 puffs_flags |= PUFFS_KFLAG_NOCACHE_NAME; 343 puffs_flags |= PUFFS_KFLAG_NOCACHE_NAME;
343 } 344 }
344 if (getenv("P2K_NOCACHE") != NULL) { 345 if (getenv("P2K_NOCACHE") != NULL) {
345 puffs_flags |= PUFFS_KFLAG_NOCACHE; 346 puffs_flags |= PUFFS_KFLAG_NOCACHE;
346 } 347 }
347 if ((envbuf = getenv("P2K_WIZARDUID")) != NULL) { 348 if ((envbuf = getenv("P2K_WIZARDUID")) != NULL) {
348 char *ep; 349 char *ep;
349 350
350 wizarduid = strtoul(envbuf, &ep, 10); 351 wizarduid = strtoul(envbuf, &ep, 10);
351 if (envbuf[0] == '\0' || *ep != '\0') { 352 if (envbuf[0] == '\0' || *ep != '\0') {
352 printf("P2K_WIZARDUID: invalid uid %s\n", envbuf); 353 printf("P2K_WIZARDUID: invalid uid %s\n", envbuf);
353 } else if (wizarduid > UID_MAX) { 354 } else if (wizarduid > UID_MAX) {
354 printf("P2K_WIZARDUID: uid %s out-of-range\n", envbuf); 355 printf("P2K_WIZARDUID: uid %s out-of-range\n", envbuf);
355 } else { 356 } else {
356 haswizard = 1; 357 haswizard = 1;
357 printf("P2K WIZARD MODE: using uid %d\n", wizarduid); 358 printf("P2K WIZARD MODE: using uid %d\n", wizarduid);
358 } 359 }
359 } 360 }
360 361
361 /* 362 /*
362 * Explicitely tell that our cookies can be treated as 363 * Explicitely tell that our cookies can be treated as
363 * puffs_node, since we never let libpuffs know by  364 * puffs_node, since we never let libpuffs know by
364 * calling call puffs_pn_new() 365 * calling call puffs_pn_new()
365 */ 366 */
366 puffs_flags |= PUFFS_FLAG_PNCOOKIE; 367 puffs_flags |= PUFFS_FLAG_PNCOOKIE;
367 368
368 p2m = allocp2m(); 369 p2m = allocp2m();
369 if (p2m == NULL) 370 if (p2m == NULL)
370 return NULL; 371 return NULL;
371 p2m->p2m_pu = puffs_init(pops, PUFFS_DEFER, PUFFS_DEFER, 372 p2m->p2m_pu = puffs_init(pops, PUFFS_DEFER, PUFFS_DEFER,
372 PUFFS_DEFER, puffs_flags); 373 PUFFS_DEFER, puffs_flags);
373 if (p2m->p2m_pu == NULL) { 374 if (p2m->p2m_pu == NULL) {
374 int sverrno = errno; 375 int sverrno = errno;
375 free(p2m); 376 free(p2m);
376 errno = sverrno; 377 errno = sverrno;
377 return NULL; 378 return NULL;
378 } 379 }
379 p2m->p2m_hasdebug = hasdebug; 380 p2m->p2m_hasdebug = hasdebug;
380 381
381 if (dodaemon) { 382 if (dodaemon) {
382 if (puffs_daemon(p2m->p2m_pu, 1, 1) == -1) { 383 if (puffs_daemon(p2m->p2m_pu, 1, 1) == -1) {
383 int sverrno = errno; 384 int sverrno = errno;
384 p2k_cancel(p2m, sverrno); 385 p2k_cancel(p2m, sverrno);
385 errno = sverrno; 386 errno = sverrno;
386 p2m = NULL; 387 p2m = NULL;
387 } 388 }
388 } 389 }
389 if (p2m) 390 if (p2m)
390 rump_init(); 391 rump_init();
391 392
392 rump_pub_lwproc_rfork(RUMP_RFCFDG); 393 rump_pub_lwproc_rfork(RUMP_RFCFDG);
393 394
394 return p2m; 395 return p2m;
395} 396}
396 397
397void 398void
398p2k_cancel(struct p2k_mount *p2m, int error) 399p2k_cancel(struct p2k_mount *p2m, int error)
399{ 400{
400 401
401 puffs_cancel(p2m->p2m_pu, error); 402 puffs_cancel(p2m->p2m_pu, error);
402 free(p2m); 403 free(p2m);
403} 404}
404 405
405static int 406static int
406setupfs(struct p2k_mount *p2m, const char *vfsname, const char *devpath, 407setupfs(struct p2k_mount *p2m, const char *vfsname, const char *devpath,
407 struct ukfs_part *part, const char *mountpath, int mntflags, 408 struct ukfs_part *part, const char *mountpath, int mntflags,
408 void *arg, size_t alen) 409 void *arg, size_t alen)
409{ 410{
410 char partpath[UKFS_DEVICE_MAXPATHLEN]; 411 char partpath[UKFS_DEVICE_MAXPATHLEN];
411 char partbuf[UKFS_DEVICE_MAXSTR]; 412 char partbuf[UKFS_DEVICE_MAXSTR];
412 char typebuf[PUFFS_TYPELEN]; 413 char typebuf[PUFFS_TYPELEN];
413 struct puffs_usermount *pu = p2m->p2m_pu; 414 struct puffs_usermount *pu = p2m->p2m_pu;
414 struct p2k_node *p2n_root; 415 struct p2k_node *p2n_root;
415 struct ukfs *ukfs = NULL; 416 struct ukfs *ukfs = NULL;
416 extern int puffs_fakecc; 417 extern int puffs_fakecc;
417 int rv = -1, sverrno; 418 int rv = -1, sverrno;
418 419
419 strcpy(typebuf, "p2k|"); 420 strcpy(typebuf, "p2k|");
420 if (strcmp(vfsname, "puffs") == 0) { /* XXX */ 421 if (strcmp(vfsname, "puffs") == 0) { /* XXX */
421 struct puffs_kargs *args = arg; 422 struct puffs_kargs *args = arg;
422 strlcat(typebuf, args->pa_typename, sizeof(typebuf)); 423 strlcat(typebuf, args->pa_typename, sizeof(typebuf));
423 } else { 424 } else {
424 strlcat(typebuf, vfsname, sizeof(typebuf)); 425 strlcat(typebuf, vfsname, sizeof(typebuf));
425 } 426 }
426 427
427 strlcpy(partpath, devpath, sizeof(partpath)); 428 strlcpy(partpath, devpath, sizeof(partpath));
428 if (ukfs_part_tostring(part, partbuf, sizeof(partbuf))) { 429 if (ukfs_part_tostring(part, partbuf, sizeof(partbuf))) {
429 strlcat(partpath, partbuf, sizeof(partpath)); 430 strlcat(partpath, partbuf, sizeof(partpath));
430 } 431 }
431 puffs_setmntinfo(pu, partpath, typebuf); 432 puffs_setmntinfo(pu, partpath, typebuf);
432 433
433 if (ukfs_init() == -1) 434 if (ukfs_init() == -1)
434 goto out; 435 goto out;
435 436
436 /*  437 /*
437 * If we're mounting rumpfs, actually do no mount and redirect 438 * If we're mounting rumpfs, actually do no mount and redirect
438 * requests to rump fs namespace root. Strictly speaking, this 439 * requests to rump fs namespace root. Strictly speaking, this
439 * is not correct, but I don't think anyone will notice. 440 * is not correct, but I don't think anyone will notice.
440 * After all, we're mostly interested in things which reside 441 * After all, we're mostly interested in things which reside
441 * specifically on the rootfs, namely the contents of /dev 442 * specifically on the rootfs, namely the contents of /dev
442 */ 443 */
443 if (strcmp(vfsname, MOUNT_RUMPFS) == 0) { 444 if (strcmp(vfsname, MOUNT_RUMPFS) == 0) {
444 if ((rv = rump_pub_vfs_getmp("/", &p2m->p2m_mp)) != 0) { 445 if ((rv = rump_pub_vfs_getmp("/", &p2m->p2m_mp)) != 0) {
445 errno = rv; 446 errno = rv;
446 rv = -1; 447 rv = -1;
447 goto out; 448 goto out;
448 } 449 }
449 } else { 450 } else {
450 if (part != ukfs_part_na) 451 if (part != ukfs_part_na)
451 ukfs = ukfs_mount_disk(vfsname, devpath, part, 452 ukfs = ukfs_mount_disk(vfsname, devpath, part,
452 mountpath, mntflags, arg, alen); 453 mountpath, mntflags, arg, alen);
453 else 454 else
454 ukfs = ukfs_mount(vfsname, devpath, mountpath, mntflags, 455 ukfs = ukfs_mount(vfsname, devpath, mountpath, mntflags,
455 arg, alen); 456 arg, alen);
456 if (ukfs == NULL) 457 if (ukfs == NULL)
457 goto out; 458 goto out;
458 ukfs_setspecific(ukfs, p2m); 459 ukfs_setspecific(ukfs, p2m);
459 p2m->p2m_ukfs = ukfs; 460 p2m->p2m_ukfs = ukfs;
460 p2m->p2m_mp = ukfs_getmp(ukfs); 461 p2m->p2m_mp = ukfs_getmp(ukfs);
461 } 462 }
462 if ((rv = rump_pub_vfs_root(p2m->p2m_mp, &p2m->p2m_rvp, 0)) != 0) { 463 if ((rv = rump_pub_vfs_root(p2m->p2m_mp, &p2m->p2m_rvp, 0)) != 0) {
463 errno = rv; 464 errno = rv;
464 rv = -1; 465 rv = -1;
465 goto out; 466 goto out;
466 } 467 }
467 468
468 p2m->p2m_pu = pu; 469 p2m->p2m_pu = pu;
469 470
470 /* 471 /*
471 * Detect tmpfs. XXX: this is a kludge. See inactive(). 472 * Detect tmpfs. XXX: this is a kludge. See inactive().
472 * 473 *
473 * In reality we'd want "does file system use anon objects 474 * In reality we'd want "does file system use anon objects
474 * for storage?". But since tmpfs hides the anon object from 475 * for storage?". But since tmpfs hides the anon object from
475 * the public interface, we can't actually detect it sanely. 476 * the public interface, we can't actually detect it sanely.
476 * Therefore, use this kludge. 477 * Therefore, use this kludge.
477 */ 478 */
478 p2m->p2m_imtmpfsman = strcmp(vfsname, MOUNT_TMPFS) == 0; 479 p2m->p2m_imtmpfsman = strcmp(vfsname, MOUNT_TMPFS) == 0;
479 480
480 p2n_root = getp2n(p2m, p2m->p2m_rvp, true, NULL); 481 p2n_root = getp2n(p2m, p2m->p2m_rvp, true, NULL);
481 puffs_setfhsize(pu, 0, PUFFS_FHFLAG_PASSTHROUGH); 482 puffs_setfhsize(pu, 0, PUFFS_FHFLAG_PASSTHROUGH);
482 puffs_setstacksize(pu, PUFFS_STACKSIZE_MIN); 483 puffs_setstacksize(pu, PUFFS_STACKSIZE_MIN);
483 puffs_fakecc = 1; 484 puffs_fakecc = 1;
484 puffs_set_prepost(pu, makelwp, NULL); 485 puffs_set_prepost(pu, makelwp, NULL);
485 486
486 if (p2m->p2m_hasdebug) { 487 if (p2m->p2m_hasdebug) {
487 struct timespec ts; 488 struct timespec ts;
488 489
489 signal(SIGINFO, sighand); 490 signal(SIGINFO, sighand);
490 signal(SIGUSR1, sighand); 491 signal(SIGUSR1, sighand);
491 492
492 ts.tv_sec = 0; 493 ts.tv_sec = 0;
493 ts.tv_nsec = 1000*1000*10; /* 10ms */ 494 ts.tv_nsec = 1000*1000*10; /* 10ms */
494 puffs_ml_setloopfn(pu, dumpmp); 495 puffs_ml_setloopfn(pu, dumpmp);
495 puffs_ml_settimeout(pu, &ts); 496 puffs_ml_settimeout(pu, &ts);
496 } 497 }
497 puffs_set_errnotify(pu, p2k_errcatcher); 498 puffs_set_errnotify(pu, p2k_errcatcher);
498 499
499 puffs_setspecific(pu, p2m); 500 puffs_setspecific(pu, p2m);
500 rv = puffs_mount(pu, mountpath, mntflags, p2n_root); 501 rv = puffs_mount(pu, mountpath, mntflags, p2n_root);
501 502
502 out: 503 out:
503 if (rv == -1) { 504 if (rv == -1) {
504 sverrno = errno; 505 sverrno = errno;
505 puffs_cancel(pu, sverrno); 506 puffs_cancel(pu, sverrno);
506 if (ukfs) 507 if (ukfs)
507 ukfs_release(p2m->p2m_ukfs, UKFS_RELFLAG_FORCE); 508 ukfs_release(p2m->p2m_ukfs, UKFS_RELFLAG_FORCE);
508 free(p2m); 509 free(p2m);
509 errno = sverrno; 510 errno = sverrno;
510 } 511 }
511 512
512 return rv; 513 return rv;
513} 514}
514 515
515int 516int
516p2k_mainloop(struct p2k_mount *p2m) 517p2k_mainloop(struct p2k_mount *p2m)
517{ 518{
518 int rv, sverrno; 519 int rv, sverrno;
519 520
520 rv = puffs_mainloop(p2m->p2m_pu); 521 rv = puffs_mainloop(p2m->p2m_pu);
521 sverrno = errno; 522 sverrno = errno;
522 puffs_exit(p2m->p2m_pu, 1); 523 puffs_exit(p2m->p2m_pu, 1);
523 if (p2m->p2m_ukfs) 524 if (p2m->p2m_ukfs)
524 ukfs_release(p2m->p2m_ukfs, UKFS_RELFLAG_FORCE); 525 ukfs_release(p2m->p2m_ukfs, UKFS_RELFLAG_FORCE);
525 free(p2m); 526 free(p2m);
526 527
527 if (rv == -1) 528 if (rv == -1)
528 errno = sverrno; 529 errno = sverrno;
529 return rv; 530 return rv;
530} 531}
531 532
532int 533int
533p2k_run_fs(const char *vfsname, const char *devpath, const char *mountpath, 534p2k_run_fs(const char *vfsname, const char *devpath, const char *mountpath,
534 int mntflags, void *arg, size_t alen, uint32_t puffs_flags) 535 int mntflags, void *arg, size_t alen, uint32_t puffs_flags)
535{ 536{
536 struct p2k_mount *p2m; 537 struct p2k_mount *p2m;
537 int rv; 538 int rv;
538 539
539 p2m = p2k_init(puffs_flags); 540 p2m = p2k_init(puffs_flags);
540 if (p2m == NULL) 541 if (p2m == NULL)
541 return -1; 542 return -1;
542 rv = setupfs(p2m, vfsname, devpath, ukfs_part_na, mountpath, 543 rv = setupfs(p2m, vfsname, devpath, ukfs_part_na, mountpath,
543 mntflags, arg, alen); 544 mntflags, arg, alen);
544 if (rv == -1) 545 if (rv == -1)
545 return rv; 546 return rv;
546 return p2k_mainloop(p2m); 547 return p2k_mainloop(p2m);
547} 548}
548 549
549int 550int
550p2k_run_diskfs(const char *vfsname, const char *devpath, struct ukfs_part *part, 551p2k_run_diskfs(const char *vfsname, const char *devpath, struct ukfs_part *part,
551 const char *mountpath, int mntflags, void *arg, size_t alen, 552 const char *mountpath, int mntflags, void *arg, size_t alen,
552 uint32_t puffs_flags) 553 uint32_t puffs_flags)
553{ 554{
554 struct p2k_mount *p2m; 555 struct p2k_mount *p2m;
555 int rv; 556 int rv;
556 557
557 p2m = p2k_init(puffs_flags); 558 p2m = p2k_init(puffs_flags);
558 if (p2m == NULL) 559 if (p2m == NULL)
559 return -1; 560 return -1;
560 rv = setupfs(p2m, vfsname, devpath, part, mountpath, mntflags, 561 rv = setupfs(p2m, vfsname, devpath, part, mountpath, mntflags,
561 arg, alen); 562 arg, alen);
562 if (rv == -1) 563 if (rv == -1)
563 return rv; 564 return rv;
564 return p2k_mainloop(p2m); 565 return p2k_mainloop(p2m);
565} 566}
566 567
567int 568int
568p2k_setup_fs(struct p2k_mount *p2m, const char *vfsname, const char *devpath, 569p2k_setup_fs(struct p2k_mount *p2m, const char *vfsname, const char *devpath,
569 const char *mountpath, int mntflags, void *arg, size_t alen) 570 const char *mountpath, int mntflags, void *arg, size_t alen)
570{ 571{
571 572
572 return setupfs(p2m, vfsname, devpath, ukfs_part_na, mountpath, 573 return setupfs(p2m, vfsname, devpath, ukfs_part_na, mountpath,
573 mntflags, arg, alen); 574 mntflags, arg, alen);
574} 575}
575 576
576int 577int
577p2k_setup_diskfs(struct p2k_mount *p2m, const char *vfsname, 578p2k_setup_diskfs(struct p2k_mount *p2m, const char *vfsname,
578 const char *devpath, struct ukfs_part *part, const char *mountpath, 579 const char *devpath, struct ukfs_part *part, const char *mountpath,
579 int mntflags, void *arg, size_t alen) 580 int mntflags, void *arg, size_t alen)
580{ 581{
581 582
582 return setupfs(p2m, vfsname, devpath, part, mountpath, mntflags, 583 return setupfs(p2m, vfsname, devpath, part, mountpath, mntflags,
583 arg, alen); 584 arg, alen);
584} 585}
585 586
586int 587int
587p2k_fs_statvfs(struct puffs_usermount *pu, struct statvfs *sbp) 588p2k_fs_statvfs(struct puffs_usermount *pu, struct statvfs *sbp)
588{ 589{
589 struct p2k_mount *p2m = puffs_getspecific(pu); 590 struct p2k_mount *p2m = puffs_getspecific(pu);
590 struct mount *mp = p2m->p2m_mp; 591 struct mount *mp = p2m->p2m_mp;
591 592
592 return rump_pub_vfs_statvfs(mp, sbp); 593 return rump_pub_vfs_statvfs(mp, sbp);
593} 594}
594 595
595/*ARGSUSED*/ 596/*ARGSUSED*/
596int 597int
597p2k_fs_unmount(struct puffs_usermount *pu, int flags) 598p2k_fs_unmount(struct puffs_usermount *pu, int flags)
598{ 599{
599 struct p2k_mount *p2m = puffs_getspecific(pu); 600 struct p2k_mount *p2m = puffs_getspecific(pu);
600 struct ukfs *fs = p2m->p2m_ukfs; 601 struct ukfs *fs = p2m->p2m_ukfs;
601 int error = 0; 602 int error = 0;
602 603
603 rump_pub_vp_rele(p2m->p2m_rvp); 604 rump_pub_vp_rele(p2m->p2m_rvp);
604 605
605 if (fs) { 606 if (fs) {
606 if (ukfs_release(fs, 0) != 0) { 607 if (ukfs_release(fs, 0) != 0) {
607 struct statvfs svfsb; 608 struct statvfs svfsb;
608 609
609 if (p2m->p2m_hasdebug 610 if (p2m->p2m_hasdebug
610 && p2k_fs_statvfs(pu, &svfsb) == 0) { 611 && p2k_fs_statvfs(pu, &svfsb) == 0) {
611 printf("\nSOFT UNMOUNT FAILED, MP INFO DUMP\n"); 612 printf("\nSOFT UNMOUNT FAILED, MP INFO DUMP\n");
612 rump_pub_vfs_mount_print(svfsb.f_mntonname, 1); 613 rump_pub_vfs_mount_print(svfsb.f_mntonname, 1);
613 } 614 }
614 ukfs_release(fs, UKFS_RELFLAG_FORCE); 615 ukfs_release(fs, UKFS_RELFLAG_FORCE);
615 error = 0; 616 error = 0;
616 } 617 }
617 } 618 }
618 p2m->p2m_ukfs = NULL; 619 p2m->p2m_ukfs = NULL;
619 620
620 if (p2m->p2m_hasdebug) { 621 if (p2m->p2m_hasdebug) {
621 printf("-- rump kernel event counters --\n"); 622 printf("-- rump kernel event counters --\n");
622 rump_printevcnts(); 623 rump_printevcnts();
623 printf("-- end of event counters --\n"); 624 printf("-- end of event counters --\n");
624 } 625 }
625 626
626 return error; 627 return error;
627} 628}
628 629
629int 630int
630p2k_fs_sync(struct puffs_usermount *pu, int waitfor, 631p2k_fs_sync(struct puffs_usermount *pu, int waitfor,
631 const struct puffs_cred *pcr) 632 const struct puffs_cred *pcr)
632{ 633{
633 struct p2k_mount *p2m = puffs_getspecific(pu); 634 struct p2k_mount *p2m = puffs_getspecific(pu);
634 struct mount *mp = p2m->p2m_mp; 635 struct mount *mp = p2m->p2m_mp;
635 struct kauth_cred *cred; 636 struct kauth_cred *cred;
636 int rv; 637 int rv;
637 638
638 cred = cred_create(pcr); 639 cred = cred_create(pcr);
639 rv = rump_pub_vfs_sync(mp, waitfor, cred); 640 rv = rump_pub_vfs_sync(mp, waitfor, cred);
640 cred_destroy(cred); 641 cred_destroy(cred);
641 642
642 return rv; 643 return rv;
643} 644}
644 645
645/*ARGSUSED*/ 646/*ARGSUSED*/
646int 647int
647p2k_fs_fhtonode(struct puffs_usermount *pu, void *fid, size_t fidsize, 648p2k_fs_fhtonode(struct puffs_usermount *pu, void *fid, size_t fidsize,
648 struct puffs_newinfo *pni) 649 struct puffs_newinfo *pni)
649{ 650{
650 struct p2k_mount *p2m = puffs_getspecific(pu); 651 struct p2k_mount *p2m = puffs_getspecific(pu);
651 struct mount *mp = p2m->p2m_mp; 652 struct mount *mp = p2m->p2m_mp;
652 struct p2k_node *p2n; 653 struct p2k_node *p2n;
653 struct vnode *vp; 654 struct vnode *vp;
654 enum rump_vtype vtype; 655 enum rump_vtype vtype;
655 voff_t vsize; 656 voff_t vsize;
656 uint64_t rdev; /* XXX: allows running this on NetBSD 5.0 */ 657 uint64_t rdev; /* XXX: allows running this on NetBSD 5.0 */
657 int rv; 658 int rv;
658 659
659 rv = rump_pub_vfs_fhtovp(mp, fid, &vp); 660 rv = rump_pub_vfs_fhtovp(mp, fid, &vp);
660 if (rv) 661 if (rv)
661 return rv; 662 return rv;
662 RUMP_VOP_UNLOCK(vp); 663 RUMP_VOP_UNLOCK(vp);
663 664
664 p2n = getp2n(p2m, vp, false, NULL); 665 p2n = getp2n(p2m, vp, false, NULL);
665 if (p2n == NULL) 666 if (p2n == NULL)
666 return ENOMEM; 667 return ENOMEM;
667 668
668 puffs_newinfo_setcookie(pni, p2n); 669 puffs_newinfo_setcookie(pni, p2n);
669 rump_pub_getvninfo(vp, &vtype, &vsize, (void *)&rdev); 670 rump_pub_getvninfo(vp, &vtype, &vsize, (void *)&rdev);
670 puffs_newinfo_setvtype(pni, (enum vtype)vtype); 671 puffs_newinfo_setvtype(pni, (enum vtype)vtype);
671 puffs_newinfo_setsize(pni, vsize); 672 puffs_newinfo_setsize(pni, vsize);
672 /* LINTED: yea, it'll lose accuracy, but that's life */ 673 /* LINTED: yea, it'll lose accuracy, but that's life */
673 puffs_newinfo_setrdev(pni, rdev); 674 puffs_newinfo_setrdev(pni, rdev);
674 675
675 return 0; 676 return 0;
676} 677}
677 678
678/*ARGSUSED*/ 679/*ARGSUSED*/
679int 680int
680p2k_fs_nodetofh(struct puffs_usermount *pu, puffs_cookie_t cookie, void *fid, 681p2k_fs_nodetofh(struct puffs_usermount *pu, puffs_cookie_t cookie, void *fid,
681 size_t *fidsize) 682 size_t *fidsize)
682{ 683{
683 struct vnode *vp = OPC2VP(cookie); 684 struct vnode *vp = OPC2VP(cookie);
684 685
685 return rump_pub_vfs_vptofh(vp, fid, fidsize); 686 return rump_pub_vfs_vptofh(vp, fid, fidsize);
686} 687}
687 688
688int 689int
689p2k_fs_extattrctl(struct puffs_usermount *pu, int cmd, 690p2k_fs_extattrctl(struct puffs_usermount *pu, int cmd,
690 puffs_cookie_t cookie, int flags, 691 puffs_cookie_t cookie, int flags,
691 int attrnamespace, const char *attrname) 692 int attrnamespace, const char *attrname)
692{ 693{
693 struct p2k_mount *p2m = puffs_getspecific(pu); 694 struct p2k_mount *p2m = puffs_getspecific(pu);
694 struct mount *mp = p2m->p2m_mp; 695 struct mount *mp = p2m->p2m_mp;
695 struct vnode *vp; 696 struct vnode *vp;
696 697
697 if (flags & PUFFS_EXTATTRCTL_HASNODE) { 698 if (flags & PUFFS_EXTATTRCTL_HASNODE) {
698 vp = OPC2VP(cookie); 699 vp = OPC2VP(cookie);
699 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE | LK_RETRY); 700 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE | LK_RETRY);
700 } else { 701 } else {
701 vp = NULL; 702 vp = NULL;
702 } 703 }
703 704
704 /* vfsop unlocks (but doesn't release) vnode, so we're done here */ 705 /* vfsop unlocks (but doesn't release) vnode, so we're done here */
705 return rump_pub_vfs_extattrctl(mp, cmd, vp, attrnamespace, attrname); 706 return rump_pub_vfs_extattrctl(mp, cmd, vp, attrnamespace, attrname);
706} 707}
707 708
708/*ARGSUSED*/ 709/*ARGSUSED*/
709int 710int
710p2k_node_lookup(struct puffs_usermount *pu, puffs_cookie_t opc, 711p2k_node_lookup(struct puffs_usermount *pu, puffs_cookie_t opc,
711 struct puffs_newinfo *pni, const struct puffs_cn *pcn) 712 struct puffs_newinfo *pni, const struct puffs_cn *pcn)
712{ 713{
713 struct p2k_mount *p2m = puffs_getspecific(pu); 714 struct p2k_mount *p2m = puffs_getspecific(pu);
714 struct p2k_node *p2n_dir = opc, *p2n; 715 struct p2k_node *p2n_dir = opc, *p2n;
715 struct componentname *cn; 716 struct componentname *cn;
716 struct vnode *dvp = p2n_dir->p2n_vp, *vp; 717 struct vnode *dvp = p2n_dir->p2n_vp, *vp;
717 enum rump_vtype vtype; 718 enum rump_vtype vtype;
718 voff_t vsize; 719 voff_t vsize;
719 uint64_t rdev; /* XXX: uint64_t because of stack overwrite in compat */ 720 uint64_t rdev; /* XXX: uint64_t because of stack overwrite in compat */
720 int rv; 721 int rv;
721 722
722 cn = makecn(pcn); 723 cn = makecn(pcn);
723 RUMP_VOP_LOCK(dvp, LK_EXCLUSIVE); 724 RUMP_VOP_LOCK(dvp, LK_EXCLUSIVE);
724 rv = RUMP_VOP_LOOKUP(dvp, &vp, cn); 725 rv = RUMP_VOP_LOOKUP(dvp, &vp, cn);
725 RUMP_VOP_UNLOCK(dvp); 726 RUMP_VOP_UNLOCK(dvp);
726 freecn(cn); 727 freecn(cn);
727 728
728 if (rv) { 729 if (rv) {
729 if (rv == RUMP_EJUSTRETURN) { 730 if (rv == RUMP_EJUSTRETURN) {
730 rv = ENOENT; 731 rv = ENOENT;
731 } 732 }
732 return rv; 733 return rv;
733 } 734 }
734 735
735 p2n = getp2n(p2m, vp, false, NULL); 736 p2n = getp2n(p2m, vp, false, NULL);
736 if (p2n == NULL) { 737 if (p2n == NULL) {
737 return ENOMEM; 738 return ENOMEM;
738 } 739 }
739 740
740 puffs_newinfo_setcookie(pni, p2n); 741 puffs_newinfo_setcookie(pni, p2n);
741 rump_pub_getvninfo(vp, &vtype, &vsize, (void *)&rdev); 742 rump_pub_getvninfo(vp, &vtype, &vsize, (void *)&rdev);
742 puffs_newinfo_setvtype(pni, (enum vtype)vtype); 743 puffs_newinfo_setvtype(pni, (enum vtype)vtype);
743 puffs_newinfo_setsize(pni, vsize); 744 puffs_newinfo_setsize(pni, vsize);
744 /* LINTED: yea, it'll lose accuracy, but that's life */ 745 /* LINTED: yea, it'll lose accuracy, but that's life */
745 puffs_newinfo_setrdev(pni, rdev); 746 puffs_newinfo_setrdev(pni, rdev);
746 747
747 return 0; 748 return 0;
748} 749}
749 750
750#define VERS_TIMECHANGE 599000700 751#define VERS_TIMECHANGE 599000700
751static int 752static int
752needcompat(void) 753needcompat(void)
753{ 754{
754 755
755 /*LINTED*/ 756 /*LINTED*/
756 return __NetBSD_Version__ < VERS_TIMECHANGE 757 return __NetBSD_Version__ < VERS_TIMECHANGE
757 && rump_getversion() >= VERS_TIMECHANGE; 758 && rump_getversion() >= VERS_TIMECHANGE;
758} 759}
759 760
760#define DOCOMPAT(va, va_compat) \ 761#define DOCOMPAT(va, va_compat) \
761do { \ 762do { \
762 if (needcompat()) { \ 763 if (needcompat()) { \
763 va_compat = rump_pub_vattr_init(); \ 764 va_compat = rump_pub_vattr_init(); \
764 rump_pub_vattr50_to_vattr(va, va_compat); \ 765 rump_pub_vattr50_to_vattr(va, va_compat); \
765 } else { \ 766 } else { \
766 va_compat = __UNCONST(va); \ 767 va_compat = __UNCONST(va); \
767 } \ 768 } \
768} while (/*CONSTCOND*/0) 769} while (/*CONSTCOND*/0)
769 770
770#define UNDOCOMPAT(va_compat) \ 771#define UNDOCOMPAT(va_compat) \
771do { \ 772do { \
772 if (needcompat()) \ 773 if (needcompat()) \
773 rump_pub_vattr_free(va_compat); \ 774 rump_pub_vattr_free(va_compat); \
774} while (/*CONSTCOND*/0) 775} while (/*CONSTCOND*/0)
775 776
776static int 777static int
777do_makenode(struct puffs_usermount *pu, struct p2k_node *p2n_dir, 778do_makenode(struct puffs_usermount *pu, struct p2k_node *p2n_dir,
778 struct puffs_newinfo *pni, const struct puffs_cn *pcn, 779 struct puffs_newinfo *pni, const struct puffs_cn *pcn,
779 const struct vattr *vap, char *link_target, 780 const struct vattr *vap, char *link_target,
780 int (*makefn)(struct vnode *, struct vnode **, struct componentname *, 781 int (*makefn)(struct vnode *, struct vnode **, struct componentname *,
781 struct vattr *), 782 struct vattr *),
782 int (*symfn)(struct vnode *, struct vnode **, struct componentname *, 783 int (*symfn)(struct vnode *, struct vnode **, struct componentname *,
783 struct vattr *, char *)) 784 struct vattr *, char *))
784{ 785{
785 struct p2k_mount *p2m = puffs_getspecific(pu); 786 struct p2k_mount *p2m = puffs_getspecific(pu);
786 struct vnode *dvp = p2n_dir->p2n_vp; 787 struct vnode *dvp = p2n_dir->p2n_vp;
787 struct p2k_node *p2n; 788 struct p2k_node *p2n;
788 struct componentname *cn; 789 struct componentname *cn;
789 struct vattr *va_x; 790 struct vattr *va_x;
790 struct vnode *vp; 791 struct vnode *vp;
791 int rv; 792 int rv;
792 793
793 p2n = malloc(sizeof(*p2n)); 794 p2n = malloc(sizeof(*p2n));
794 if (p2n == NULL) 795 if (p2n == NULL)
795 return ENOMEM; 796 return ENOMEM;
796 DOCOMPAT(vap, va_x); 797 DOCOMPAT(vap, va_x);
797 798
798 cn = makecn(pcn); 799 cn = makecn(pcn);
799 RUMP_VOP_LOCK(dvp, LK_EXCLUSIVE); 800 RUMP_VOP_LOCK(dvp, LK_EXCLUSIVE);
800 rump_pub_vp_incref(dvp); 801 rump_pub_vp_incref(dvp);
801 if (makefn) { 802 if (makefn) {
802 rv = makefn(dvp, &vp, cn, va_x); 803 rv = makefn(dvp, &vp, cn, va_x);
803 } else { 804 } else {
804 rv = symfn(dvp, &vp, cn, va_x, link_target); 805 rv = symfn(dvp, &vp, cn, va_x, link_target);
805 } 806 }
806 rump_pub_vp_rele(dvp); 807 rump_pub_vp_rele(dvp);
807 RUMP_VOP_UNLOCK(dvp); 808 RUMP_VOP_UNLOCK(dvp);
808 freecn(cn); 809 freecn(cn);
809 810
810 if (rv == 0) { 811 if (rv == 0) {
811 p2n = getp2n(p2m, vp, true, p2n); 812 p2n = getp2n(p2m, vp, true, p2n);
812 puffs_newinfo_setcookie(pni, p2n); 813 puffs_newinfo_setcookie(pni, p2n);
813 } else { 814 } else {
814 free(p2n); 815 free(p2n);
815 } 816 }
816 817
817 UNDOCOMPAT(va_x); 818 UNDOCOMPAT(va_x);
818 819
819 return rv; 820 return rv;
820 821
821} 822}
822 823
823/*ARGSUSED*/ 824/*ARGSUSED*/
824int 825int
825p2k_node_create(struct puffs_usermount *pu, puffs_cookie_t opc, 826p2k_node_create(struct puffs_usermount *pu, puffs_cookie_t opc,
826 struct puffs_newinfo *pni, const struct puffs_cn *pcn, 827 struct puffs_newinfo *pni, const struct puffs_cn *pcn,
827 const struct vattr *vap) 828 const struct vattr *vap)
828{ 829{
829 830
830 return do_makenode(pu, opc, pni, pcn, vap, NULL, RUMP_VOP_CREATE, NULL); 831 return do_makenode(pu, opc, pni, pcn, vap, NULL, RUMP_VOP_CREATE, NULL);
831} 832}
832 833
833/*ARGSUSED*/ 834/*ARGSUSED*/
834int 835int
835p2k_node_mknod(struct puffs_usermount *pu, puffs_cookie_t opc, 836p2k_node_mknod(struct puffs_usermount *pu, puffs_cookie_t opc,
836 struct puffs_newinfo *pni, const struct puffs_cn *pcn, 837 struct puffs_newinfo *pni, const struct puffs_cn *pcn,
837 const struct vattr *vap) 838 const struct vattr *vap)
838{ 839{
839 840
840 return do_makenode(pu, opc, pni, pcn, vap, NULL, RUMP_VOP_MKNOD, NULL); 841 return do_makenode(pu, opc, pni, pcn, vap, NULL, RUMP_VOP_MKNOD, NULL);
841} 842}
842 843
843/*ARGSUSED*/ 844/*ARGSUSED*/
844int 845int
845p2k_node_open(struct puffs_usermount *pu, puffs_cookie_t opc, int mode, 846p2k_node_open(struct puffs_usermount *pu, puffs_cookie_t opc, int mode,
846 const struct puffs_cred *pcr) 847 const struct puffs_cred *pcr)
847{ 848{
848 struct vnode *vp = OPC2VP(opc); 849 struct vnode *vp = OPC2VP(opc);
849 struct kauth_cred *cred; 850 struct kauth_cred *cred;
850 int rv; 851 int rv;
851 852
852 cred = cred_create(pcr); 853 cred = cred_create(pcr);
853 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE); 854 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE);
854 rv = RUMP_VOP_OPEN(vp, mode, cred); 855 rv = RUMP_VOP_OPEN(vp, mode, cred);
855 RUMP_VOP_UNLOCK(vp); 856 RUMP_VOP_UNLOCK(vp);
856 cred_destroy(cred); 857 cred_destroy(cred);
857 858
858 return rv; 859 return rv;
859} 860}
860 861
861/*ARGSUSED*/ 862/*ARGSUSED*/
862int 863int
863p2k_node_close(struct puffs_usermount *pu, puffs_cookie_t opc, int flags, 864p2k_node_close(struct puffs_usermount *pu, puffs_cookie_t opc, int flags,
864 const struct puffs_cred *pcr) 865 const struct puffs_cred *pcr)
865{ 866{
866 struct vnode *vp = OPC2VP(opc); 867 struct vnode *vp = OPC2VP(opc);
867 struct kauth_cred *cred; 868 struct kauth_cred *cred;
868 869
869 cred = cred_create(pcr); 870 cred = cred_create(pcr);
870 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE); 871 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE);
871 RUMP_VOP_CLOSE(vp, flags, cred); 872 RUMP_VOP_CLOSE(vp, flags, cred);
872 RUMP_VOP_UNLOCK(vp); 873 RUMP_VOP_UNLOCK(vp);
873 cred_destroy(cred); 874 cred_destroy(cred);
874 875
875 return 0; 876 return 0;
876} 877}
877 878
878/*ARGSUSED*/ 879/*ARGSUSED*/
879int 880int
880p2k_node_access(struct puffs_usermount *pu, puffs_cookie_t opc, int mode, 881p2k_node_access(struct puffs_usermount *pu, puffs_cookie_t opc, int mode,
881 const struct puffs_cred *pcr) 882 const struct puffs_cred *pcr)
882{ 883{
883 struct vnode *vp = OPC2VP(opc); 884 struct vnode *vp = OPC2VP(opc);
884 struct kauth_cred *cred; 885 struct kauth_cred *cred;
885 int rv; 886 int rv;
886 887
887 cred = cred_create(pcr); 888 cred = cred_create(pcr);
888 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE); 889 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE);
889 rv = RUMP_VOP_ACCESS(vp, mode, cred); 890 rv = RUMP_VOP_ACCESS(vp, mode, cred);
890 RUMP_VOP_UNLOCK(vp); 891 RUMP_VOP_UNLOCK(vp);
891 cred_destroy(cred); 892 cred_destroy(cred);
892 893
893 return rv; 894 return rv;
894} 895}
895 896
896/*ARGSUSED*/ 897/*ARGSUSED*/
897int 898int
898p2k_node_getattr(struct puffs_usermount *pu, puffs_cookie_t opc, 899p2k_node_getattr(struct puffs_usermount *pu, puffs_cookie_t opc,
899 struct vattr *vap, const struct puffs_cred *pcr) 900 struct vattr *vap, const struct puffs_cred *pcr)
900{ 901{
901 struct vnode *vp = OPC2VP(opc); 902 struct vnode *vp = OPC2VP(opc);
902 struct kauth_cred *cred; 903 struct kauth_cred *cred;
903 struct vattr *va_x; 904 struct vattr *va_x;
904 int rv; 905 int rv;
905 906
906 /* "deadfs" */ 907 /* "deadfs" */
907 if (!vp) 908 if (!vp)
908 return 0; 909 return 0;
909 910
910 if (needcompat()) { 911 if (needcompat()) {
911 va_x = rump_pub_vattr_init(); 912 va_x = rump_pub_vattr_init();
912 } else { 913 } else {
913 va_x = vap; 914 va_x = vap;
914 } 915 }
915 916
916 cred = cred_create(pcr); 917 cred = cred_create(pcr);
917 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE); 918 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE);
918 rv = RUMP_VOP_GETATTR(vp, va_x, cred); 919 rv = RUMP_VOP_GETATTR(vp, va_x, cred);
919 RUMP_VOP_UNLOCK(vp); 920 RUMP_VOP_UNLOCK(vp);
920 cred_destroy(cred); 921 cred_destroy(cred);
921 922
922 if (needcompat()) { 923 if (needcompat()) {
923 rump_pub_vattr_to_vattr50(va_x, vap); 924 rump_pub_vattr_to_vattr50(va_x, vap);
924 rump_pub_vattr_free(va_x); 925 rump_pub_vattr_free(va_x);
925 } 926 }
926 927
927 return rv; 928 return rv;
928} 929}
929 930
930/*ARGSUSED*/ 931/*ARGSUSED*/
931int 932int
932p2k_node_setattr(struct puffs_usermount *pu, puffs_cookie_t opc, 933p2k_node_setattr(struct puffs_usermount *pu, puffs_cookie_t opc,
933 const struct vattr *vap, const struct puffs_cred *pcr) 934 const struct vattr *vap, const struct puffs_cred *pcr)
934{ 935{
935 struct vnode *vp = OPC2VP(opc); 936 struct vnode *vp = OPC2VP(opc);
936 struct kauth_cred *cred; 937 struct kauth_cred *cred;
937 struct vattr *va_x; 938 struct vattr *va_x;
938 int rv; 939 int rv;
939 940
940 /* "deadfs" */ 941 /* "deadfs" */
941 if (!vp) 942 if (!vp)
942 return 0; 943 return 0;
943 944
944 DOCOMPAT(vap, va_x); 945 DOCOMPAT(vap, va_x);
945 946
946 cred = cred_create(pcr); 947 cred = cred_create(pcr);
947 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE); 948 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE);
948 rv = RUMP_VOP_SETATTR(vp, va_x, cred); 949 rv = RUMP_VOP_SETATTR(vp, va_x, cred);
949 RUMP_VOP_UNLOCK(vp); 950 RUMP_VOP_UNLOCK(vp);
950 cred_destroy(cred); 951 cred_destroy(cred);
951 952
952 UNDOCOMPAT(va_x); 953 UNDOCOMPAT(va_x);
953 954
954 return rv; 955 return rv;
955} 956}
956 957
957/*ARGSUSED*/ 958/*ARGSUSED*/
958int 959int
959p2k_node_fsync(struct puffs_usermount *pu, puffs_cookie_t opc, 960p2k_node_fsync(struct puffs_usermount *pu, puffs_cookie_t opc,
960 const struct puffs_cred *pcr, int flags, off_t offlo, off_t offhi) 961 const struct puffs_cred *pcr, int flags, off_t offlo, off_t offhi)
961{ 962{
962 struct vnode *vp = OPC2VP(opc); 963 struct vnode *vp = OPC2VP(opc);
963 struct kauth_cred *cred; 964 struct kauth_cred *cred;
964 int rv; 965 int rv;
965 966
966 /* "deadfs" */ 967 /* "deadfs" */
967 if (!vp) 968 if (!vp)
968 return 0; 969 return 0;
969 970
970 cred = cred_create(pcr); 971 cred = cred_create(pcr);
971 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE); 972 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE);
972 rv = RUMP_VOP_FSYNC(vp, cred, flags, offlo, offhi); 973 rv = RUMP_VOP_FSYNC(vp, cred, flags, offlo, offhi);
973 RUMP_VOP_UNLOCK(vp); 974 RUMP_VOP_UNLOCK(vp);
974 cred_destroy(cred); 975 cred_destroy(cred);
975 976
976 return rv; 977 return rv;
977} 978}
978 979
979/*ARGSUSED*/ 980/*ARGSUSED*/
980int 981int
981p2k_node_mmap(struct puffs_usermount *pu, puffs_cookie_t opc, vm_prot_t flags, 982p2k_node_mmap(struct puffs_usermount *pu, puffs_cookie_t opc, vm_prot_t flags,
982 const struct puffs_cred *pcr) 983 const struct puffs_cred *pcr)
983{ 984{
984 struct kauth_cred *cred; 985 struct kauth_cred *cred;
985 int rv; 986 int rv;
986 987
987 cred = cred_create(pcr); 988 cred = cred_create(pcr);
988 rv = RUMP_VOP_MMAP(OPC2VP(opc), flags, cred); 989 rv = RUMP_VOP_MMAP(OPC2VP(opc), flags, cred);
989 cred_destroy(cred); 990 cred_destroy(cred);
990 991
991 return rv; 992 return rv;
992} 993}
993 994
994/*ARGSUSED*/ 995/*ARGSUSED*/
995int 996int
996p2k_node_seek(struct puffs_usermount *pu, puffs_cookie_t opc, 997p2k_node_seek(struct puffs_usermount *pu, puffs_cookie_t opc,
997 off_t oldoff, off_t newoff, const struct puffs_cred *pcr) 998 off_t oldoff, off_t newoff, const struct puffs_cred *pcr)
998{ 999{
999 struct vnode *vp = OPC2VP(opc); 1000 struct vnode *vp = OPC2VP(opc);
1000 struct kauth_cred *cred; 1001 struct kauth_cred *cred;
1001 int rv; 1002 int rv;
1002 1003
1003 cred = cred_create(pcr); 1004 cred = cred_create(pcr);
1004 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE); 1005 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE);
1005 rv = RUMP_VOP_SEEK(vp, oldoff, newoff, cred); 1006 rv = RUMP_VOP_SEEK(vp, oldoff, newoff, cred);
1006 RUMP_VOP_UNLOCK(vp); 1007 RUMP_VOP_UNLOCK(vp);
1007 cred_destroy(cred); 1008 cred_destroy(cred);
1008 1009
1009 return rv; 1010 return rv;
1010} 1011}
1011 1012
1012static int 1013static int
1013do_nukenode(struct p2k_node *p2n_dir, struct p2k_node *p2n, 1014do_nukenode(struct p2k_node *p2n_dir, struct p2k_node *p2n,
1014 const struct puffs_cn *pcn, 1015 const struct puffs_cn *pcn,
1015 int (*nukefn)(struct vnode *, struct vnode *, struct componentname *)) 1016 int (*nukefn)(struct vnode *, struct vnode *, struct componentname *))
1016{ 1017{
1017 struct vnode *dvp = p2n_dir->p2n_vp, *vp = p2n->p2n_vp; 1018 struct vnode *dvp = p2n_dir->p2n_vp, *vp = p2n->p2n_vp;
1018 struct componentname *cn; 1019 struct componentname *cn;
1019 int rv; 1020 int rv;
1020 1021
1021 cn = makecn(pcn); 1022 cn = makecn(pcn);
1022 RUMP_VOP_LOCK(dvp, LK_EXCLUSIVE); 1023 RUMP_VOP_LOCK(dvp, LK_EXCLUSIVE);
1023 rump_pub_vp_incref(dvp); 1024 rump_pub_vp_incref(dvp);
1024 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE); 1025 RUMP_VOP_LOCK(vp, LK_EXCLUSIVE);
1025 rump_pub_vp_incref(vp); 1026 rump_pub_vp_incref(vp);
1026 rv = nukefn(dvp, vp, cn); 1027 rv = nukefn(dvp, vp, cn);
1027 assert(RUMP_VOP_ISLOCKED(dvp) == 0); 1028 assert(RUMP_VOP_ISLOCKED(dvp) == 0);
1028 assert(RUMP_VOP_ISLOCKED(vp) == 0); 1029 assert(RUMP_VOP_ISLOCKED(vp) == 0);
1029 freecn(cn); 1030 freecn(cn);
1030 1031
1031 return rv; 1032 return rv;
1032 1033
1033} 1034}
1034 1035
1035/*ARGSUSED*/ 1036/*ARGSUSED*/
1036int 1037int
1037p2k_node_remove(struct puffs_usermount *pu, puffs_cookie_t opc, 1038p2k_node_remove(struct puffs_usermount *pu, puffs_cookie_t opc,
1038 puffs_cookie_t targ, const struct puffs_cn *pcn) 1039 puffs_cookie_t targ, const struct puffs_cn *pcn)
1039{ 1040{
1040 1041
1041 return do_nukenode(opc, targ, pcn, RUMP_VOP_REMOVE); 1042 return do_nukenode(opc, targ, pcn, RUMP_VOP_REMOVE);
1042} 1043}
1043 1044
1044/*ARGSUSED*/ 1045/*ARGSUSED*/
1045int 1046int
1046p2k_node_link(struct puffs_usermount *pu, puffs_cookie_t opc, 1047p2k_node_link(struct puffs_usermount *pu, puffs_cookie_t opc,
1047 puffs_cookie_t targ, const struct puffs_cn *pcn) 1048 puffs_cookie_t targ, const struct puffs_cn *pcn)
1048{ 1049{
1049 struct vnode *dvp = OPC2VP(opc); 1050 struct vnode *dvp = OPC2VP(opc);
1050 struct componentname *cn; 1051 struct componentname *cn;
1051 int rv; 1052 int rv;
1052 1053
1053 cn = makecn(pcn); 1054 cn = makecn(pcn);
1054 RUMP_VOP_LOCK(dvp, LK_EXCLUSIVE); 1055 RUMP_VOP_LOCK(dvp, LK_EXCLUSIVE);
1055 rump_pub_vp_incref(dvp); 1056 rump_pub_vp_incref(dvp);
1056 rv = RUMP_VOP_LINK(dvp, OPC2VP(targ), cn); 1057 rv = RUMP_VOP_LINK(dvp, OPC2VP(targ), cn);
1057 rump_pub_vp_rele(dvp); 1058 rump_pub_vp_rele(dvp);
1058 RUMP_VOP_UNLOCK(dvp); 1059 RUMP_VOP_UNLOCK(dvp);
1059 freecn(cn); 1060 freecn(cn);
1060 1061
1061 return rv; 1062 return rv;
1062} 1063}
1063 1064