Mon Dec 11 12:42:18 2023 UTC (174d)
pathconf needs to return EINVAL when the variable is invalid
or cannot be associated with a file. This also needs to be true
when the node doesn't implement the pathconf function at all.


(mlelstv)
diff -r1.49 -r1.50 src/lib/libpuffs/dispatcher.c

cvs diff -r1.49 -r1.50 src/lib/libpuffs/dispatcher.c (switch to unified diff)

--- src/lib/libpuffs/dispatcher.c 2021/03/08 17:34:10 1.49
+++ src/lib/libpuffs/dispatcher.c 2023/12/11 12:42:18 1.50
@@ -1,1209 +1,1209 @@ @@ -1,1209 +1,1209 @@
1/* $NetBSD: dispatcher.c,v 1.49 2021/03/08 17:34:10 christos Exp $ */ 1/* $NetBSD: dispatcher.c,v 1.50 2023/12/11 12:42:18 mlelstv Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2006, 2007, 2008 Antti Kantee. All Rights Reserved. 4 * Copyright (c) 2006, 2007, 2008 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 * Ulla Tuominen Foundation, the Finnish Cultural Foundation and 7 * Ulla Tuominen Foundation, the Finnish Cultural Foundation and
8 * Research Foundation of Helsinki University of Technology. 8 * Research Foundation of Helsinki University of Technology.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
20 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33#if !defined(lint) 33#if !defined(lint)
34__RCSID("$NetBSD: dispatcher.c,v 1.49 2021/03/08 17:34:10 christos Exp $"); 34__RCSID("$NetBSD: dispatcher.c,v 1.50 2023/12/11 12:42:18 mlelstv Exp $");
35#endif /* !lint */ 35#endif /* !lint */
36 36
37#include <sys/types.h> 37#include <sys/types.h>
38#include <sys/poll.h> 38#include <sys/poll.h>
39 39
40#include <assert.h> 40#include <assert.h>
41#include <errno.h> 41#include <errno.h>
42#include <pthread.h> 42#include <pthread.h>
43#include <puffs.h> 43#include <puffs.h>
44#include <puffsdump.h> 44#include <puffsdump.h>
45#include <stdio.h> 45#include <stdio.h>
46#include <stdlib.h> 46#include <stdlib.h>
47#include <unistd.h> 47#include <unistd.h>
48 48
49#include "puffs_priv.h" 49#include "puffs_priv.h"
50 50
51#define PUFFS_USE_FS_TTL(pu) (pu->pu_flags & PUFFS_KFLAG_CACHE_FS_TTL)  51#define PUFFS_USE_FS_TTL(pu) (pu->pu_flags & PUFFS_KFLAG_CACHE_FS_TTL)
52 52
53static void dispatch(struct puffs_cc *); 53static void dispatch(struct puffs_cc *);
54 54
55/* for our eyes only */ 55/* for our eyes only */
56void 56void
57puffs__ml_dispatch(struct puffs_usermount *pu, struct puffs_framebuf *pb) 57puffs__ml_dispatch(struct puffs_usermount *pu, struct puffs_framebuf *pb)
58{ 58{
59 struct puffs_cc *pcc = puffs_cc_getcc(pu); 59 struct puffs_cc *pcc = puffs_cc_getcc(pu);
60 struct puffs_req *preq; 60 struct puffs_req *preq;
61 61
62 pcc->pcc_pb = pb; 62 pcc->pcc_pb = pb;
63 pcc->pcc_flags |= PCC_MLCONT; 63 pcc->pcc_flags |= PCC_MLCONT;
64 dispatch(pcc); 64 dispatch(pcc);
65 65
66 /* Put result to kernel sendqueue if necessary */ 66 /* Put result to kernel sendqueue if necessary */
67 preq = puffs__framebuf_getdataptr(pcc->pcc_pb); 67 preq = puffs__framebuf_getdataptr(pcc->pcc_pb);
68 if (PUFFSOP_WANTREPLY(preq->preq_opclass)) { 68 if (PUFFSOP_WANTREPLY(preq->preq_opclass)) {
69 if (pu->pu_flags & PUFFS_FLAG_OPDUMP) 69 if (pu->pu_flags & PUFFS_FLAG_OPDUMP)
70 puffsdump_rv(preq); 70 puffsdump_rv(preq);
71 71
72 puffs_framev_enqueue_justsend(pu, pu->pu_fd, 72 puffs_framev_enqueue_justsend(pu, pu->pu_fd,
73 pcc->pcc_pb, 0, 0); 73 pcc->pcc_pb, 0, 0);
74 } else { 74 } else {
75 puffs_framebuf_destroy(pcc->pcc_pb); 75 puffs_framebuf_destroy(pcc->pcc_pb);
76 } 76 }
77 77
78 /* who needs information when you're living on borrowed time? */ 78 /* who needs information when you're living on borrowed time? */
79 if (pcc->pcc_flags & PCC_BORROWED) { 79 if (pcc->pcc_flags & PCC_BORROWED) {
80 puffs_cc_yield(pcc); /* back to borrow source */ 80 puffs_cc_yield(pcc); /* back to borrow source */
81 } 81 }
82 pcc->pcc_flags = 0; 82 pcc->pcc_flags = 0;
83} 83}
84 84
85/* public, but not really tested and only semi-supported */ 85/* public, but not really tested and only semi-supported */
86int 86int
87puffs_dispatch_create(struct puffs_usermount *pu, struct puffs_framebuf *pb, 87puffs_dispatch_create(struct puffs_usermount *pu, struct puffs_framebuf *pb,
88 struct puffs_cc **pccp) 88 struct puffs_cc **pccp)
89{ 89{
90 struct puffs_cc *pcc; 90 struct puffs_cc *pcc;
91 91
92 if (puffs__cc_create(pu, dispatch, &pcc) == -1) 92 if (puffs__cc_create(pu, dispatch, &pcc) == -1)
93 return -1; 93 return -1;
94 94
95 pcc->pcc_pb = pb; 95 pcc->pcc_pb = pb;
96 *pccp = pcc; 96 *pccp = pcc;
97 97
98 return 0; 98 return 0;
99} 99}
100 100
101int 101int
102puffs_dispatch_exec(struct puffs_cc *pcc, struct puffs_framebuf **pbp) 102puffs_dispatch_exec(struct puffs_cc *pcc, struct puffs_framebuf **pbp)
103{ 103{
104 int rv; 104 int rv;
105 105
106 puffs_cc_continue(pcc); 106 puffs_cc_continue(pcc);
107 107
108 if (pcc->pcc_flags & PCC_DONE) { 108 if (pcc->pcc_flags & PCC_DONE) {
109 rv = 1; 109 rv = 1;
110 *pbp = pcc->pcc_pb; 110 *pbp = pcc->pcc_pb;
111 pcc->pcc_flags = 0; 111 pcc->pcc_flags = 0;
112 puffs__cc_destroy(pcc, 0); 112 puffs__cc_destroy(pcc, 0);
113 } else { 113 } else {
114 rv = 0; 114 rv = 0;
115 } 115 }
116 116
117 return rv; 117 return rv;
118} 118}
119 119
120static void 120static void
121dispatch(struct puffs_cc *pcc) 121dispatch(struct puffs_cc *pcc)
122{ 122{
123 struct puffs_usermount *pu = pcc->pcc_pu; 123 struct puffs_usermount *pu = pcc->pcc_pu;
124 struct puffs_ops *pops = &pu->pu_ops; 124 struct puffs_ops *pops = &pu->pu_ops;
125 struct puffs_req *preq = puffs__framebuf_getdataptr(pcc->pcc_pb); 125 struct puffs_req *preq = puffs__framebuf_getdataptr(pcc->pcc_pb);
126 void *auxbuf; /* help with typecasting */ 126 void *auxbuf; /* help with typecasting */
127 puffs_cookie_t opcookie; 127 puffs_cookie_t opcookie;
128 int error = 0, buildpath, pncookie; 128 int error = 0, buildpath, pncookie;
129 129
130 /* XXX: smaller hammer, please */ 130 /* XXX: smaller hammer, please */
131 if ((PUFFSOP_OPCLASS(preq->preq_opclass == PUFFSOP_VFS && 131 if ((PUFFSOP_OPCLASS(preq->preq_opclass == PUFFSOP_VFS &&
132 preq->preq_optype == PUFFS_VFS_VPTOFH)) || 132 preq->preq_optype == PUFFS_VFS_VPTOFH)) ||
133 (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VN && 133 (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VN &&
134 (preq->preq_optype == PUFFS_VN_READDIR 134 (preq->preq_optype == PUFFS_VN_READDIR
135 || preq->preq_optype == PUFFS_VN_READ))) { 135 || preq->preq_optype == PUFFS_VN_READ))) {
136 if (puffs_framebuf_reserve_space(pcc->pcc_pb, 136 if (puffs_framebuf_reserve_space(pcc->pcc_pb,
137 PUFFS_MSG_MAXSIZE) == -1) 137 PUFFS_MSG_MAXSIZE) == -1)
138 error = errno; 138 error = errno;
139 preq = puffs__framebuf_getdataptr(pcc->pcc_pb); 139 preq = puffs__framebuf_getdataptr(pcc->pcc_pb);
140 } 140 }
141 141
142 auxbuf = preq; 142 auxbuf = preq;
143 opcookie = preq->preq_cookie; 143 opcookie = preq->preq_cookie;
144 144
145 assert((pcc->pcc_flags & PCC_DONE) == 0); 145 assert((pcc->pcc_flags & PCC_DONE) == 0);
146 146
147 buildpath = pu->pu_flags & PUFFS_FLAG_BUILDPATH; 147 buildpath = pu->pu_flags & PUFFS_FLAG_BUILDPATH;
148 pncookie = pu->pu_flags & PUFFS_FLAG_PNCOOKIE; 148 pncookie = pu->pu_flags & PUFFS_FLAG_PNCOOKIE;
149 assert(!buildpath || pncookie); 149 assert(!buildpath || pncookie);
150 150
151 preq->preq_setbacks = 0; 151 preq->preq_setbacks = 0;
152 152
153 if (pu->pu_flags & PUFFS_FLAG_OPDUMP) 153 if (pu->pu_flags & PUFFS_FLAG_OPDUMP)
154 puffsdump_req(preq); 154 puffsdump_req(preq);
155 155
156 puffs__cc_setcaller(pcc, preq->preq_pid, preq->preq_lid); 156 puffs__cc_setcaller(pcc, preq->preq_pid, preq->preq_lid);
157 157
158 /* pre-operation */ 158 /* pre-operation */
159 if (pu->pu_oppre) 159 if (pu->pu_oppre)
160 pu->pu_oppre(pu); 160 pu->pu_oppre(pu);
161 161
162 if (error) 162 if (error)
163 goto out; 163 goto out;
164 164
165 /* Execute actual operation */ 165 /* Execute actual operation */
166 if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VFS) { 166 if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VFS) {
167 switch ((enum puffs_vfs)preq->preq_optype) { 167 switch ((enum puffs_vfs)preq->preq_optype) {
168 case PUFFS_VFS_UNMOUNT: 168 case PUFFS_VFS_UNMOUNT:
169 { 169 {
170 struct puffs_vfsmsg_unmount *auxt = auxbuf; 170 struct puffs_vfsmsg_unmount *auxt = auxbuf;
171 171
172 PU_SETSTATE(pu, PUFFS_STATE_UNMOUNTING); 172 PU_SETSTATE(pu, PUFFS_STATE_UNMOUNTING);
173 error = pops->puffs_fs_unmount(pu, auxt->pvfsr_flags); 173 error = pops->puffs_fs_unmount(pu, auxt->pvfsr_flags);
174 if (!error) 174 if (!error)
175 PU_SETSTATE(pu, PUFFS_STATE_UNMOUNTED); 175 PU_SETSTATE(pu, PUFFS_STATE_UNMOUNTED);
176 else 176 else
177 PU_SETSTATE(pu, PUFFS_STATE_RUNNING); 177 PU_SETSTATE(pu, PUFFS_STATE_RUNNING);
178 break; 178 break;
179 } 179 }
180 180
181 case PUFFS_VFS_STATVFS: 181 case PUFFS_VFS_STATVFS:
182 { 182 {
183 struct puffs_vfsmsg_statvfs *auxt = auxbuf; 183 struct puffs_vfsmsg_statvfs *auxt = auxbuf;
184 184
185 error = pops->puffs_fs_statvfs(pu, &auxt->pvfsr_sb); 185 error = pops->puffs_fs_statvfs(pu, &auxt->pvfsr_sb);
186 break; 186 break;
187 } 187 }
188 188
189 case PUFFS_VFS_SYNC: 189 case PUFFS_VFS_SYNC:
190 { 190 {
191 struct puffs_vfsmsg_sync *auxt = auxbuf; 191 struct puffs_vfsmsg_sync *auxt = auxbuf;
192 PUFFS_MAKECRED(pcr, &auxt->pvfsr_cred); 192 PUFFS_MAKECRED(pcr, &auxt->pvfsr_cred);
193 193
194 error = pops->puffs_fs_sync(pu, 194 error = pops->puffs_fs_sync(pu,
195 auxt->pvfsr_waitfor, pcr); 195 auxt->pvfsr_waitfor, pcr);
196 break; 196 break;
197 } 197 }
198 198
199 case PUFFS_VFS_FHTOVP: 199 case PUFFS_VFS_FHTOVP:
200 { 200 {
201 struct puffs_vfsmsg_fhtonode *auxt = auxbuf; 201 struct puffs_vfsmsg_fhtonode *auxt = auxbuf;
202 struct puffs_newinfo pni; 202 struct puffs_newinfo pni;
203 203
204 pni.pni_cookie = &auxt->pvfsr_fhcookie; 204 pni.pni_cookie = &auxt->pvfsr_fhcookie;
205 pni.pni_vtype = &auxt->pvfsr_vtype; 205 pni.pni_vtype = &auxt->pvfsr_vtype;
206 pni.pni_size = &auxt->pvfsr_size; 206 pni.pni_size = &auxt->pvfsr_size;
207 pni.pni_rdev = &auxt->pvfsr_rdev; 207 pni.pni_rdev = &auxt->pvfsr_rdev;
208 pni.pni_va = NULL; 208 pni.pni_va = NULL;
209 pni.pni_va_ttl = NULL; 209 pni.pni_va_ttl = NULL;
210 pni.pni_cn_ttl = NULL; 210 pni.pni_cn_ttl = NULL;
211 211
212 error = pops->puffs_fs_fhtonode(pu, auxt->pvfsr_data, 212 error = pops->puffs_fs_fhtonode(pu, auxt->pvfsr_data,
213 auxt->pvfsr_dsize, &pni); 213 auxt->pvfsr_dsize, &pni);
214 214
215 break; 215 break;
216 } 216 }
217 217
218 case PUFFS_VFS_VPTOFH: 218 case PUFFS_VFS_VPTOFH:
219 { 219 {
220 struct puffs_vfsmsg_nodetofh *auxt = auxbuf; 220 struct puffs_vfsmsg_nodetofh *auxt = auxbuf;
221 221
222 error = pops->puffs_fs_nodetofh(pu, 222 error = pops->puffs_fs_nodetofh(pu,
223 auxt->pvfsr_fhcookie, auxt->pvfsr_data, 223 auxt->pvfsr_fhcookie, auxt->pvfsr_data,
224 &auxt->pvfsr_dsize); 224 &auxt->pvfsr_dsize);
225 225
226 break; 226 break;
227 } 227 }
228 228
229 case PUFFS_VFS_EXTATTRCTL: 229 case PUFFS_VFS_EXTATTRCTL:
230 { 230 {
231 struct puffs_vfsmsg_extattrctl *auxt = auxbuf; 231 struct puffs_vfsmsg_extattrctl *auxt = auxbuf;
232 const char *attrname; 232 const char *attrname;
233 int flags; 233 int flags;
234 234
235 if (pops->puffs_fs_extattrctl == NULL) { 235 if (pops->puffs_fs_extattrctl == NULL) {
236 error = EOPNOTSUPP; 236 error = EOPNOTSUPP;
237 break; 237 break;
238 } 238 }
239 239
240 if (auxt->pvfsr_flags & PUFFS_EXTATTRCTL_HASATTRNAME) 240 if (auxt->pvfsr_flags & PUFFS_EXTATTRCTL_HASATTRNAME)
241 attrname = auxt->pvfsr_attrname; 241 attrname = auxt->pvfsr_attrname;
242 else 242 else
243 attrname = NULL; 243 attrname = NULL;
244 244
245 flags = auxt->pvfsr_flags & PUFFS_EXTATTRCTL_HASNODE; 245 flags = auxt->pvfsr_flags & PUFFS_EXTATTRCTL_HASNODE;
246 error = pops->puffs_fs_extattrctl(pu, auxt->pvfsr_cmd, 246 error = pops->puffs_fs_extattrctl(pu, auxt->pvfsr_cmd,
247 opcookie, flags, 247 opcookie, flags,
248 auxt->pvfsr_attrnamespace, attrname); 248 auxt->pvfsr_attrnamespace, attrname);
249 break; 249 break;
250 } 250 }
251 251
252 default: 252 default:
253 /* 253 /*
254 * I guess the kernel sees this one coming 254 * I guess the kernel sees this one coming
255 */ 255 */
256 error = EINVAL; 256 error = EINVAL;
257 break; 257 break;
258 } 258 }
259 259
260 /* XXX: audit return values */ 260 /* XXX: audit return values */
261 /* XXX: sync with kernel */ 261 /* XXX: sync with kernel */
262 } else if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VN) { 262 } else if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VN) {
263 switch ((enum puffs_vn)preq->preq_optype) { 263 switch ((enum puffs_vn)preq->preq_optype) {
264 case PUFFS_VN_LOOKUP: 264 case PUFFS_VN_LOOKUP:
265 { 265 {
266 struct puffs_vnmsg_lookup *auxt = auxbuf; 266 struct puffs_vnmsg_lookup *auxt = auxbuf;
267 struct puffs_newinfo pni; 267 struct puffs_newinfo pni;
268 struct puffs_cn pcn; 268 struct puffs_cn pcn;
269 struct puffs_node *pn = NULL; 269 struct puffs_node *pn = NULL;
270 270
271 pcn.pcn_pkcnp = &auxt->pvnr_cn; 271 pcn.pcn_pkcnp = &auxt->pvnr_cn;
272 PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); 272 PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
273 pni.pni_cookie = &auxt->pvnr_newnode; 273 pni.pni_cookie = &auxt->pvnr_newnode;
274 pni.pni_vtype = &auxt->pvnr_vtype; 274 pni.pni_vtype = &auxt->pvnr_vtype;
275 pni.pni_size = &auxt->pvnr_size; 275 pni.pni_size = &auxt->pvnr_size;
276 pni.pni_rdev = &auxt->pvnr_rdev; 276 pni.pni_rdev = &auxt->pvnr_rdev;
277 pni.pni_va = &auxt->pvnr_va; 277 pni.pni_va = &auxt->pvnr_va;
278 pni.pni_va_ttl = &auxt->pvnr_va_ttl; 278 pni.pni_va_ttl = &auxt->pvnr_va_ttl;
279 pni.pni_cn_ttl = &auxt->pvnr_cn_ttl; 279 pni.pni_cn_ttl = &auxt->pvnr_cn_ttl;
280 280
281 if (buildpath) { 281 if (buildpath) {
282 error = puffs_path_pcnbuild(pu, &pcn, opcookie); 282 error = puffs_path_pcnbuild(pu, &pcn, opcookie);
283 if (error) 283 if (error)
284 break; 284 break;
285 } 285 }
286 286
287 /* lookup *must* be present */ 287 /* lookup *must* be present */
288 error = pops->puffs_node_lookup(pu, opcookie, 288 error = pops->puffs_node_lookup(pu, opcookie,
289 &pni, &pcn); 289 &pni, &pcn);
290 290
291 if (buildpath) { 291 if (buildpath) {
292 if (error) { 292 if (error) {
293 pu->pu_pathfree(pu, &pcn.pcn_po_full); 293 pu->pu_pathfree(pu, &pcn.pcn_po_full);
294 } else { 294 } else {
295 /* 295 /*
296 * did we get a new node or a 296 * did we get a new node or a
297 * recycled node? 297 * recycled node?
298 */ 298 */
299 pn = PU_CMAP(pu, auxt->pvnr_newnode); 299 pn = PU_CMAP(pu, auxt->pvnr_newnode);
300 if (pn->pn_po.po_path == NULL) 300 if (pn->pn_po.po_path == NULL)
301 pn->pn_po = pcn.pcn_po_full; 301 pn->pn_po = pcn.pcn_po_full;
302 else 302 else
303 pu->pu_pathfree(pu, 303 pu->pu_pathfree(pu,
304 &pcn.pcn_po_full); 304 &pcn.pcn_po_full);
305 } 305 }
306 } 306 }
307 307
308 if (pncookie && !error) { 308 if (pncookie && !error) {
309 if (pn == NULL) 309 if (pn == NULL)
310 pn = PU_CMAP(pu, auxt->pvnr_newnode); 310 pn = PU_CMAP(pu, auxt->pvnr_newnode);
311 pn->pn_nlookup++; 311 pn->pn_nlookup++;
312 } 312 }
313 break; 313 break;
314 } 314 }
315 315
316 case PUFFS_VN_CREATE: 316 case PUFFS_VN_CREATE:
317 { 317 {
318 struct puffs_vnmsg_create *auxt = auxbuf; 318 struct puffs_vnmsg_create *auxt = auxbuf;
319 struct puffs_newinfo pni; 319 struct puffs_newinfo pni;
320 struct puffs_cn pcn; 320 struct puffs_cn pcn;
321 struct puffs_node *pn = NULL; 321 struct puffs_node *pn = NULL;
322 322
323 if (pops->puffs_node_create == NULL) { 323 if (pops->puffs_node_create == NULL) {
324 error = 0; 324 error = 0;
325 break; 325 break;
326 } 326 }
327 327
328 pcn.pcn_pkcnp = &auxt->pvnr_cn; 328 pcn.pcn_pkcnp = &auxt->pvnr_cn;
329 PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); 329 PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
330 330
331 memset(&pni, 0, sizeof(pni)); 331 memset(&pni, 0, sizeof(pni));
332 pni.pni_cookie = &auxt->pvnr_newnode; 332 pni.pni_cookie = &auxt->pvnr_newnode;
333 pni.pni_va = &auxt->pvnr_va; 333 pni.pni_va = &auxt->pvnr_va;
334 pni.pni_va_ttl = &auxt->pvnr_va_ttl; 334 pni.pni_va_ttl = &auxt->pvnr_va_ttl;
335 pni.pni_cn_ttl = &auxt->pvnr_cn_ttl; 335 pni.pni_cn_ttl = &auxt->pvnr_cn_ttl;
336 336
337 if (buildpath) { 337 if (buildpath) {
338 error = puffs_path_pcnbuild(pu, &pcn, opcookie); 338 error = puffs_path_pcnbuild(pu, &pcn, opcookie);
339 if (error) 339 if (error)
340 break; 340 break;
341 } 341 }
342 342
343 error = pops->puffs_node_create(pu, 343 error = pops->puffs_node_create(pu,
344 opcookie, &pni, &pcn, &auxt->pvnr_va); 344 opcookie, &pni, &pcn, &auxt->pvnr_va);
345 345
346 if (buildpath) { 346 if (buildpath) {
347 if (error) { 347 if (error) {
348 pu->pu_pathfree(pu, &pcn.pcn_po_full); 348 pu->pu_pathfree(pu, &pcn.pcn_po_full);
349 } else { 349 } else {
350 pn = PU_CMAP(pu, auxt->pvnr_newnode); 350 pn = PU_CMAP(pu, auxt->pvnr_newnode);
351 pn->pn_po = pcn.pcn_po_full; 351 pn->pn_po = pcn.pcn_po_full;
352 } 352 }
353 } 353 }
354 354
355 if (pncookie && !error) { 355 if (pncookie && !error) {
356 if (pn == NULL) 356 if (pn == NULL)
357 pn = PU_CMAP(pu, auxt->pvnr_newnode); 357 pn = PU_CMAP(pu, auxt->pvnr_newnode);
358 pn->pn_nlookup++; 358 pn->pn_nlookup++;
359 } 359 }
360 break; 360 break;
361 } 361 }
362 362
363 case PUFFS_VN_MKNOD: 363 case PUFFS_VN_MKNOD:
364 { 364 {
365 struct puffs_vnmsg_mknod *auxt = auxbuf; 365 struct puffs_vnmsg_mknod *auxt = auxbuf;
366 struct puffs_newinfo pni; 366 struct puffs_newinfo pni;
367 struct puffs_cn pcn; 367 struct puffs_cn pcn;
368 struct puffs_node *pn = NULL; 368 struct puffs_node *pn = NULL;
369 369
370 if (pops->puffs_node_mknod == NULL) { 370 if (pops->puffs_node_mknod == NULL) {
371 error = 0; 371 error = 0;
372 break; 372 break;
373 } 373 }
374 374
375 pcn.pcn_pkcnp = &auxt->pvnr_cn; 375 pcn.pcn_pkcnp = &auxt->pvnr_cn;
376 PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); 376 PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
377 377
378 memset(&pni, 0, sizeof(pni)); 378 memset(&pni, 0, sizeof(pni));
379 pni.pni_cookie = &auxt->pvnr_newnode; 379 pni.pni_cookie = &auxt->pvnr_newnode;
380 pni.pni_va = &auxt->pvnr_va; 380 pni.pni_va = &auxt->pvnr_va;
381 pni.pni_va_ttl = &auxt->pvnr_va_ttl; 381 pni.pni_va_ttl = &auxt->pvnr_va_ttl;
382 pni.pni_cn_ttl = &auxt->pvnr_cn_ttl; 382 pni.pni_cn_ttl = &auxt->pvnr_cn_ttl;
383 383
384 if (buildpath) { 384 if (buildpath) {
385 error = puffs_path_pcnbuild(pu, &pcn, opcookie); 385 error = puffs_path_pcnbuild(pu, &pcn, opcookie);
386 if (error) 386 if (error)
387 break; 387 break;
388 } 388 }
389 389
390 error = pops->puffs_node_mknod(pu, 390 error = pops->puffs_node_mknod(pu,
391 opcookie, &pni, &pcn, &auxt->pvnr_va); 391 opcookie, &pni, &pcn, &auxt->pvnr_va);
392 392
393 if (buildpath) { 393 if (buildpath) {
394 if (error) { 394 if (error) {
395 pu->pu_pathfree(pu, &pcn.pcn_po_full); 395 pu->pu_pathfree(pu, &pcn.pcn_po_full);
396 } else { 396 } else {
397 pn = PU_CMAP(pu, auxt->pvnr_newnode); 397 pn = PU_CMAP(pu, auxt->pvnr_newnode);
398 pn->pn_po = pcn.pcn_po_full; 398 pn->pn_po = pcn.pcn_po_full;
399 } 399 }
400 } 400 }
401 401
402 if (pncookie && !error) { 402 if (pncookie && !error) {
403 if (pn == NULL) 403 if (pn == NULL)
404 pn = PU_CMAP(pu, auxt->pvnr_newnode); 404 pn = PU_CMAP(pu, auxt->pvnr_newnode);
405 pn->pn_nlookup++; 405 pn->pn_nlookup++;
406 } 406 }
407 break; 407 break;
408 } 408 }
409 409
410 case PUFFS_VN_OPEN: 410 case PUFFS_VN_OPEN:
411 { 411 {
412 struct puffs_vnmsg_open *auxt = auxbuf; 412 struct puffs_vnmsg_open *auxt = auxbuf;
413 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 413 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
414 414
415 if (pops->puffs_node_open2 != NULL) { 415 if (pops->puffs_node_open2 != NULL) {
416 error = pops->puffs_node_open2(pu, 416 error = pops->puffs_node_open2(pu,
417 opcookie, auxt->pvnr_mode, pcr,  417 opcookie, auxt->pvnr_mode, pcr,
418 &auxt->pvnr_oflags); 418 &auxt->pvnr_oflags);
419 419
420 break; 420 break;
421 } 421 }
422 422
423 if (pops->puffs_node_open == NULL) { 423 if (pops->puffs_node_open == NULL) {
424 error = 0; 424 error = 0;
425 break; 425 break;
426 } 426 }
427 427
428 error = pops->puffs_node_open(pu, 428 error = pops->puffs_node_open(pu,
429 opcookie, auxt->pvnr_mode, pcr); 429 opcookie, auxt->pvnr_mode, pcr);
430 break; 430 break;
431 } 431 }
432 432
433 case PUFFS_VN_CLOSE: 433 case PUFFS_VN_CLOSE:
434 { 434 {
435 struct puffs_vnmsg_close *auxt = auxbuf; 435 struct puffs_vnmsg_close *auxt = auxbuf;
436 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 436 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
437 437
438 if (pops->puffs_node_close == NULL) { 438 if (pops->puffs_node_close == NULL) {
439 error = 0; 439 error = 0;
440 break; 440 break;
441 } 441 }
442 442
443 error = pops->puffs_node_close(pu, 443 error = pops->puffs_node_close(pu,
444 opcookie, auxt->pvnr_fflag, pcr); 444 opcookie, auxt->pvnr_fflag, pcr);
445 break; 445 break;
446 } 446 }
447 447
448 case PUFFS_VN_ACCESS: 448 case PUFFS_VN_ACCESS:
449 { 449 {
450 struct puffs_vnmsg_access *auxt = auxbuf; 450 struct puffs_vnmsg_access *auxt = auxbuf;
451 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 451 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
452 452
453 if (pops->puffs_node_access == NULL) { 453 if (pops->puffs_node_access == NULL) {
454 error = 0; 454 error = 0;
455 break; 455 break;
456 } 456 }
457 457
458 error = pops->puffs_node_access(pu, 458 error = pops->puffs_node_access(pu,
459 opcookie, auxt->pvnr_mode, pcr); 459 opcookie, auxt->pvnr_mode, pcr);
460 break; 460 break;
461 } 461 }
462 462
463 case PUFFS_VN_GETATTR: 463 case PUFFS_VN_GETATTR:
464 { 464 {
465 struct puffs_vnmsg_getattr *auxt = auxbuf; 465 struct puffs_vnmsg_getattr *auxt = auxbuf;
466 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 466 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
467 467
468 if (PUFFS_USE_FS_TTL(pu)) { 468 if (PUFFS_USE_FS_TTL(pu)) {
469 if (pops->puffs_node_getattr_ttl == NULL) { 469 if (pops->puffs_node_getattr_ttl == NULL) {
470 error = EOPNOTSUPP; 470 error = EOPNOTSUPP;
471 break; 471 break;
472 } 472 }
473 473
474 error = pops->puffs_node_getattr_ttl(pu, 474 error = pops->puffs_node_getattr_ttl(pu,
475 opcookie, &auxt->pvnr_va, pcr, 475 opcookie, &auxt->pvnr_va, pcr,
476 &auxt->pvnr_va_ttl); 476 &auxt->pvnr_va_ttl);
477 } else { 477 } else {
478 if (pops->puffs_node_getattr == NULL) { 478 if (pops->puffs_node_getattr == NULL) {
479 error = EOPNOTSUPP; 479 error = EOPNOTSUPP;
480 break; 480 break;
481 } 481 }
482 482
483 error = pops->puffs_node_getattr(pu, 483 error = pops->puffs_node_getattr(pu,
484 opcookie, &auxt->pvnr_va, pcr); 484 opcookie, &auxt->pvnr_va, pcr);
485 } 485 }
486 break; 486 break;
487 } 487 }
488 488
489 case PUFFS_VN_SETATTR: 489 case PUFFS_VN_SETATTR:
490 { 490 {
491 struct puffs_vnmsg_setattr *auxt = auxbuf; 491 struct puffs_vnmsg_setattr *auxt = auxbuf;
492 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 492 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
493 493
494 if (PUFFS_USE_FS_TTL(pu)) { 494 if (PUFFS_USE_FS_TTL(pu)) {
495 int xflag = 0; 495 int xflag = 0;
496 496
497 if (pops->puffs_node_setattr_ttl == NULL) { 497 if (pops->puffs_node_setattr_ttl == NULL) {
498 error = EOPNOTSUPP; 498 error = EOPNOTSUPP;
499 break; 499 break;
500 } 500 }
501 501
502 if (!PUFFSOP_WANTREPLY(preq->preq_opclass)) 502 if (!PUFFSOP_WANTREPLY(preq->preq_opclass))
503 xflag |= PUFFS_SETATTR_FAF; 503 xflag |= PUFFS_SETATTR_FAF;
504 504
505 error = pops->puffs_node_setattr_ttl(pu, 505 error = pops->puffs_node_setattr_ttl(pu,
506 opcookie, &auxt->pvnr_va, pcr, 506 opcookie, &auxt->pvnr_va, pcr,
507 &auxt->pvnr_va_ttl, xflag); 507 &auxt->pvnr_va_ttl, xflag);
508 } else { 508 } else {
509 if (pops->puffs_node_setattr == NULL) { 509 if (pops->puffs_node_setattr == NULL) {
510 error = EOPNOTSUPP; 510 error = EOPNOTSUPP;
511 break; 511 break;
512 } 512 }
513 513
514 error = pops->puffs_node_setattr(pu, 514 error = pops->puffs_node_setattr(pu,
515 opcookie, &auxt->pvnr_va, pcr); 515 opcookie, &auxt->pvnr_va, pcr);
516 } 516 }
517 break; 517 break;
518 } 518 }
519 519
520 case PUFFS_VN_MMAP: 520 case PUFFS_VN_MMAP:
521 { 521 {
522 struct puffs_vnmsg_mmap *auxt = auxbuf; 522 struct puffs_vnmsg_mmap *auxt = auxbuf;
523 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 523 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
524 524
525 if (pops->puffs_node_mmap == NULL) { 525 if (pops->puffs_node_mmap == NULL) {
526 error = 0; 526 error = 0;
527 break; 527 break;
528 } 528 }
529 529
530 error = pops->puffs_node_mmap(pu, 530 error = pops->puffs_node_mmap(pu,
531 opcookie, auxt->pvnr_prot, pcr); 531 opcookie, auxt->pvnr_prot, pcr);
532 break; 532 break;
533 } 533 }
534 534
535 case PUFFS_VN_FSYNC: 535 case PUFFS_VN_FSYNC:
536 { 536 {
537 struct puffs_vnmsg_fsync *auxt = auxbuf; 537 struct puffs_vnmsg_fsync *auxt = auxbuf;
538 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 538 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
539 539
540 if (pops->puffs_node_fsync == NULL) { 540 if (pops->puffs_node_fsync == NULL) {
541 error = 0; 541 error = 0;
542 break; 542 break;
543 } 543 }
544 544
545 error = pops->puffs_node_fsync(pu, opcookie, pcr, 545 error = pops->puffs_node_fsync(pu, opcookie, pcr,
546 auxt->pvnr_flags, auxt->pvnr_offlo, 546 auxt->pvnr_flags, auxt->pvnr_offlo,
547 auxt->pvnr_offhi); 547 auxt->pvnr_offhi);
548 break; 548 break;
549 } 549 }
550 550
551 case PUFFS_VN_SEEK: 551 case PUFFS_VN_SEEK:
552 { 552 {
553 struct puffs_vnmsg_seek *auxt = auxbuf; 553 struct puffs_vnmsg_seek *auxt = auxbuf;
554 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 554 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
555 555
556 if (pops->puffs_node_seek == NULL) { 556 if (pops->puffs_node_seek == NULL) {
557 error = 0; 557 error = 0;
558 break; 558 break;
559 } 559 }
560 560
561 error = pops->puffs_node_seek(pu, 561 error = pops->puffs_node_seek(pu,
562 opcookie, auxt->pvnr_oldoff, 562 opcookie, auxt->pvnr_oldoff,
563 auxt->pvnr_newoff, pcr); 563 auxt->pvnr_newoff, pcr);
564 break; 564 break;
565 } 565 }
566 566
567 case PUFFS_VN_REMOVE: 567 case PUFFS_VN_REMOVE:
568 { 568 {
569 struct puffs_vnmsg_remove *auxt = auxbuf; 569 struct puffs_vnmsg_remove *auxt = auxbuf;
570 struct puffs_cn pcn; 570 struct puffs_cn pcn;
571 if (pops->puffs_node_remove == NULL) { 571 if (pops->puffs_node_remove == NULL) {
572 error = 0; 572 error = 0;
573 break; 573 break;
574 } 574 }
575 575
576 pcn.pcn_pkcnp = &auxt->pvnr_cn; 576 pcn.pcn_pkcnp = &auxt->pvnr_cn;
577 PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); 577 PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
578 578
579 error = pops->puffs_node_remove(pu, 579 error = pops->puffs_node_remove(pu,
580 opcookie, auxt->pvnr_cookie_targ, &pcn); 580 opcookie, auxt->pvnr_cookie_targ, &pcn);
581 break; 581 break;
582 } 582 }
583 583
584 case PUFFS_VN_LINK: 584 case PUFFS_VN_LINK:
585 { 585 {
586 struct puffs_vnmsg_link *auxt = auxbuf; 586 struct puffs_vnmsg_link *auxt = auxbuf;
587 struct puffs_cn pcn; 587 struct puffs_cn pcn;
588 if (pops->puffs_node_link == NULL) { 588 if (pops->puffs_node_link == NULL) {
589 error = 0; 589 error = 0;
590 break; 590 break;
591 } 591 }
592 592
593 pcn.pcn_pkcnp = &auxt->pvnr_cn; 593 pcn.pcn_pkcnp = &auxt->pvnr_cn;
594 PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); 594 PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
595 595
596 if (buildpath) { 596 if (buildpath) {
597 error = puffs_path_pcnbuild(pu, &pcn, opcookie); 597 error = puffs_path_pcnbuild(pu, &pcn, opcookie);
598 if (error) 598 if (error)
599 break; 599 break;
600 } 600 }
601 601
602 error = pops->puffs_node_link(pu, 602 error = pops->puffs_node_link(pu,
603 opcookie, auxt->pvnr_cookie_targ, &pcn); 603 opcookie, auxt->pvnr_cookie_targ, &pcn);
604 if (buildpath) 604 if (buildpath)
605 pu->pu_pathfree(pu, &pcn.pcn_po_full); 605 pu->pu_pathfree(pu, &pcn.pcn_po_full);
606 606
607 break; 607 break;
608 } 608 }
609 609
610 case PUFFS_VN_RENAME: 610 case PUFFS_VN_RENAME:
611 { 611 {
612 struct puffs_vnmsg_rename *auxt = auxbuf; 612 struct puffs_vnmsg_rename *auxt = auxbuf;
613 struct puffs_cn pcn_src, pcn_targ; 613 struct puffs_cn pcn_src, pcn_targ;
614 struct puffs_node *pn_src; 614 struct puffs_node *pn_src;
615 615
616 if (pops->puffs_node_rename == NULL) { 616 if (pops->puffs_node_rename == NULL) {
617 error = 0; 617 error = 0;
618 break; 618 break;
619 } 619 }
620 620
621 pcn_src.pcn_pkcnp = &auxt->pvnr_cn_src; 621 pcn_src.pcn_pkcnp = &auxt->pvnr_cn_src;
622 PUFFS_KCREDTOCRED(pcn_src.pcn_cred, 622 PUFFS_KCREDTOCRED(pcn_src.pcn_cred,
623 &auxt->pvnr_cn_src_cred); 623 &auxt->pvnr_cn_src_cred);
624 624
625 pcn_targ.pcn_pkcnp = &auxt->pvnr_cn_targ; 625 pcn_targ.pcn_pkcnp = &auxt->pvnr_cn_targ;
626 PUFFS_KCREDTOCRED(pcn_targ.pcn_cred, 626 PUFFS_KCREDTOCRED(pcn_targ.pcn_cred,
627 &auxt->pvnr_cn_targ_cred); 627 &auxt->pvnr_cn_targ_cred);
628 628
629 if (buildpath) { 629 if (buildpath) {
630 pn_src = auxt->pvnr_cookie_src; 630 pn_src = auxt->pvnr_cookie_src;
631 pcn_src.pcn_po_full = pn_src->pn_po; 631 pcn_src.pcn_po_full = pn_src->pn_po;
632 632
633 error = puffs_path_pcnbuild(pu, &pcn_targ, 633 error = puffs_path_pcnbuild(pu, &pcn_targ,
634 auxt->pvnr_cookie_targdir); 634 auxt->pvnr_cookie_targdir);
635 if (error) 635 if (error)
636 break; 636 break;
637 } 637 }
638 638
639 error = pops->puffs_node_rename(pu, 639 error = pops->puffs_node_rename(pu,
640 opcookie, auxt->pvnr_cookie_src, 640 opcookie, auxt->pvnr_cookie_src,
641 &pcn_src, auxt->pvnr_cookie_targdir, 641 &pcn_src, auxt->pvnr_cookie_targdir,
642 auxt->pvnr_cookie_targ, &pcn_targ); 642 auxt->pvnr_cookie_targ, &pcn_targ);
643 643
644 if (buildpath) { 644 if (buildpath) {
645 if (error) { 645 if (error) {
646 pu->pu_pathfree(pu, 646 pu->pu_pathfree(pu,
647 &pcn_targ.pcn_po_full); 647 &pcn_targ.pcn_po_full);
648 } else { 648 } else {
649 struct puffs_pathinfo pi; 649 struct puffs_pathinfo pi;
650 struct puffs_pathobj po_old; 650 struct puffs_pathobj po_old;
651 651
652 /* handle this node */ 652 /* handle this node */
653 po_old = pn_src->pn_po; 653 po_old = pn_src->pn_po;
654 pn_src->pn_po = pcn_targ.pcn_po_full; 654 pn_src->pn_po = pcn_targ.pcn_po_full;
655 655
656 if (pn_src->pn_va.va_type != VDIR) { 656 if (pn_src->pn_va.va_type != VDIR) {
657 pu->pu_pathfree(pu, &po_old); 657 pu->pu_pathfree(pu, &po_old);
658 break; 658 break;
659 } 659 }
660 660
661 /* handle all child nodes for DIRs */ 661 /* handle all child nodes for DIRs */
662 pi.pi_old = &pcn_src.pcn_po_full; 662 pi.pi_old = &pcn_src.pcn_po_full;
663 pi.pi_new = &pcn_targ.pcn_po_full; 663 pi.pi_new = &pcn_targ.pcn_po_full;
664 664
665 PU_LOCK(); 665 PU_LOCK();
666 if (puffs_pn_nodewalk(pu, 666 if (puffs_pn_nodewalk(pu,
667 puffs_path_prefixadj, &pi) != NULL) 667 puffs_path_prefixadj, &pi) != NULL)
668 error = ENOMEM; 668 error = ENOMEM;
669 PU_UNLOCK(); 669 PU_UNLOCK();
670 pu->pu_pathfree(pu, &po_old); 670 pu->pu_pathfree(pu, &po_old);
671 } 671 }
672 } 672 }
673 break; 673 break;
674 } 674 }
675 675
676 case PUFFS_VN_MKDIR: 676 case PUFFS_VN_MKDIR:
677 { 677 {
678 struct puffs_vnmsg_mkdir *auxt = auxbuf; 678 struct puffs_vnmsg_mkdir *auxt = auxbuf;
679 struct puffs_newinfo pni; 679 struct puffs_newinfo pni;
680 struct puffs_cn pcn; 680 struct puffs_cn pcn;
681 struct puffs_node *pn = NULL; 681 struct puffs_node *pn = NULL;
682 682
683 if (pops->puffs_node_mkdir == NULL) { 683 if (pops->puffs_node_mkdir == NULL) {
684 error = 0; 684 error = 0;
685 break; 685 break;
686 } 686 }
687 687
688 pcn.pcn_pkcnp = &auxt->pvnr_cn; 688 pcn.pcn_pkcnp = &auxt->pvnr_cn;
689 PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); 689 PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
690 690
691 memset(&pni, 0, sizeof(pni)); 691 memset(&pni, 0, sizeof(pni));
692 pni.pni_cookie = &auxt->pvnr_newnode; 692 pni.pni_cookie = &auxt->pvnr_newnode;
693 pni.pni_va = &auxt->pvnr_va; 693 pni.pni_va = &auxt->pvnr_va;
694 pni.pni_va_ttl = &auxt->pvnr_va_ttl; 694 pni.pni_va_ttl = &auxt->pvnr_va_ttl;
695 pni.pni_cn_ttl = &auxt->pvnr_cn_ttl; 695 pni.pni_cn_ttl = &auxt->pvnr_cn_ttl;
696 696
697 if (buildpath) { 697 if (buildpath) {
698 error = puffs_path_pcnbuild(pu, &pcn, opcookie); 698 error = puffs_path_pcnbuild(pu, &pcn, opcookie);
699 if (error) 699 if (error)
700 break; 700 break;
701 } 701 }
702 702
703 error = pops->puffs_node_mkdir(pu, 703 error = pops->puffs_node_mkdir(pu,
704 opcookie, &pni, &pcn, &auxt->pvnr_va); 704 opcookie, &pni, &pcn, &auxt->pvnr_va);
705 705
706 if (buildpath) { 706 if (buildpath) {
707 if (error) { 707 if (error) {
708 pu->pu_pathfree(pu, &pcn.pcn_po_full); 708 pu->pu_pathfree(pu, &pcn.pcn_po_full);
709 } else { 709 } else {
710 pn = PU_CMAP(pu, auxt->pvnr_newnode); 710 pn = PU_CMAP(pu, auxt->pvnr_newnode);
711 pn->pn_po = pcn.pcn_po_full; 711 pn->pn_po = pcn.pcn_po_full;
712 } 712 }
713 } 713 }
714 714
715 if (pncookie && !error) { 715 if (pncookie && !error) {
716 if (pn == NULL) 716 if (pn == NULL)
717 pn = PU_CMAP(pu, auxt->pvnr_newnode); 717 pn = PU_CMAP(pu, auxt->pvnr_newnode);
718 pn->pn_nlookup++; 718 pn->pn_nlookup++;
719 } 719 }
720 break; 720 break;
721 } 721 }
722 722
723 case PUFFS_VN_RMDIR: 723 case PUFFS_VN_RMDIR:
724 { 724 {
725 struct puffs_vnmsg_rmdir *auxt = auxbuf; 725 struct puffs_vnmsg_rmdir *auxt = auxbuf;
726 struct puffs_cn pcn; 726 struct puffs_cn pcn;
727 if (pops->puffs_node_rmdir == NULL) { 727 if (pops->puffs_node_rmdir == NULL) {
728 error = 0; 728 error = 0;
729 break; 729 break;
730 } 730 }
731 731
732 pcn.pcn_pkcnp = &auxt->pvnr_cn; 732 pcn.pcn_pkcnp = &auxt->pvnr_cn;
733 PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); 733 PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
734 734
735 error = pops->puffs_node_rmdir(pu, 735 error = pops->puffs_node_rmdir(pu,
736 opcookie, auxt->pvnr_cookie_targ, &pcn); 736 opcookie, auxt->pvnr_cookie_targ, &pcn);
737 break; 737 break;
738 } 738 }
739 739
740 case PUFFS_VN_SYMLINK: 740 case PUFFS_VN_SYMLINK:
741 { 741 {
742 struct puffs_vnmsg_symlink *auxt = auxbuf; 742 struct puffs_vnmsg_symlink *auxt = auxbuf;
743 struct puffs_newinfo pni; 743 struct puffs_newinfo pni;
744 struct puffs_cn pcn; 744 struct puffs_cn pcn;
745 struct puffs_node *pn = NULL; 745 struct puffs_node *pn = NULL;
746 746
747 if (pops->puffs_node_symlink == NULL) { 747 if (pops->puffs_node_symlink == NULL) {
748 error = 0; 748 error = 0;
749 break; 749 break;
750 } 750 }
751 751
752 pcn.pcn_pkcnp = &auxt->pvnr_cn; 752 pcn.pcn_pkcnp = &auxt->pvnr_cn;
753 PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); 753 PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
754 754
755 memset(&pni, 0, sizeof(pni)); 755 memset(&pni, 0, sizeof(pni));
756 pni.pni_cookie = &auxt->pvnr_newnode; 756 pni.pni_cookie = &auxt->pvnr_newnode;
757 pni.pni_va = &auxt->pvnr_va; 757 pni.pni_va = &auxt->pvnr_va;
758 pni.pni_va_ttl = &auxt->pvnr_va_ttl; 758 pni.pni_va_ttl = &auxt->pvnr_va_ttl;
759 pni.pni_cn_ttl = &auxt->pvnr_cn_ttl; 759 pni.pni_cn_ttl = &auxt->pvnr_cn_ttl;
760 760
761 if (buildpath) { 761 if (buildpath) {
762 error = puffs_path_pcnbuild(pu, &pcn, opcookie); 762 error = puffs_path_pcnbuild(pu, &pcn, opcookie);
763 if (error) 763 if (error)
764 break; 764 break;
765 } 765 }
766 766
767 error = pops->puffs_node_symlink(pu, 767 error = pops->puffs_node_symlink(pu,
768 opcookie, &pni, &pcn, 768 opcookie, &pni, &pcn,
769 &auxt->pvnr_va, auxt->pvnr_link); 769 &auxt->pvnr_va, auxt->pvnr_link);
770 770
771 if (buildpath) { 771 if (buildpath) {
772 if (error) { 772 if (error) {
773 pu->pu_pathfree(pu, &pcn.pcn_po_full); 773 pu->pu_pathfree(pu, &pcn.pcn_po_full);
774 } else { 774 } else {
775 pn = PU_CMAP(pu, auxt->pvnr_newnode); 775 pn = PU_CMAP(pu, auxt->pvnr_newnode);
776 pn->pn_po = pcn.pcn_po_full; 776 pn->pn_po = pcn.pcn_po_full;
777 } 777 }
778 } 778 }
779 779
780 if (pncookie && !error) { 780 if (pncookie && !error) {
781 if (pn == NULL) 781 if (pn == NULL)
782 pn = PU_CMAP(pu, auxt->pvnr_newnode); 782 pn = PU_CMAP(pu, auxt->pvnr_newnode);
783 pn->pn_nlookup++; 783 pn->pn_nlookup++;
784 } 784 }
785 break; 785 break;
786 } 786 }
787 787
788 case PUFFS_VN_READDIR: 788 case PUFFS_VN_READDIR:
789 { 789 {
790 struct puffs_vnmsg_readdir *auxt = auxbuf; 790 struct puffs_vnmsg_readdir *auxt = auxbuf;
791 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 791 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
792 struct dirent *dent; 792 struct dirent *dent;
793 off_t *cookies; 793 off_t *cookies;
794 size_t res, origcookies; 794 size_t res, origcookies;
795 795
796 if (pops->puffs_node_readdir == NULL) { 796 if (pops->puffs_node_readdir == NULL) {
797 error = 0; 797 error = 0;
798 break; 798 break;
799 } 799 }
800 800
801 if (auxt->pvnr_ncookies) { 801 if (auxt->pvnr_ncookies) {
802 /* LINTED: pvnr_data is __aligned() */ 802 /* LINTED: pvnr_data is __aligned() */
803 cookies = (off_t *)auxt->pvnr_data; 803 cookies = (off_t *)auxt->pvnr_data;
804 origcookies = auxt->pvnr_ncookies; 804 origcookies = auxt->pvnr_ncookies;
805 } else { 805 } else {
806 cookies = NULL; 806 cookies = NULL;
807 origcookies = 0; 807 origcookies = 0;
808 } 808 }
809 /* LINTED: dentoff is aligned in the kernel */ 809 /* LINTED: dentoff is aligned in the kernel */
810 dent = (struct dirent *) 810 dent = (struct dirent *)
811 (auxt->pvnr_data + auxt->pvnr_dentoff); 811 (auxt->pvnr_data + auxt->pvnr_dentoff);
812 812
813 res = auxt->pvnr_resid; 813 res = auxt->pvnr_resid;
814 error = pops->puffs_node_readdir(pu, 814 error = pops->puffs_node_readdir(pu,
815 opcookie, dent, &auxt->pvnr_offset, 815 opcookie, dent, &auxt->pvnr_offset,
816 &auxt->pvnr_resid, pcr, &auxt->pvnr_eofflag, 816 &auxt->pvnr_resid, pcr, &auxt->pvnr_eofflag,
817 cookies, &auxt->pvnr_ncookies); 817 cookies, &auxt->pvnr_ncookies);
818 818
819 /* much easier to track non-working NFS */ 819 /* much easier to track non-working NFS */
820 assert(auxt->pvnr_ncookies <= origcookies); 820 assert(auxt->pvnr_ncookies <= origcookies);
821 821
822 /* need to move a bit more */ 822 /* need to move a bit more */
823 preq->preq_buflen = sizeof(struct puffs_vnmsg_readdir)  823 preq->preq_buflen = sizeof(struct puffs_vnmsg_readdir)
824 + auxt->pvnr_dentoff + (res - auxt->pvnr_resid); 824 + auxt->pvnr_dentoff + (res - auxt->pvnr_resid);
825 break; 825 break;
826 } 826 }
827 827
828 case PUFFS_VN_READLINK: 828 case PUFFS_VN_READLINK:
829 { 829 {
830 struct puffs_vnmsg_readlink *auxt = auxbuf; 830 struct puffs_vnmsg_readlink *auxt = auxbuf;
831 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 831 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
832 832
833 if (pops->puffs_node_readlink == NULL) { 833 if (pops->puffs_node_readlink == NULL) {
834 error = EOPNOTSUPP; 834 error = EOPNOTSUPP;
835 break; 835 break;
836 } 836 }
837 837
838 /*LINTED*/ 838 /*LINTED*/
839 error = pops->puffs_node_readlink(pu, opcookie, pcr, 839 error = pops->puffs_node_readlink(pu, opcookie, pcr,
840 auxt->pvnr_link, &auxt->pvnr_linklen); 840 auxt->pvnr_link, &auxt->pvnr_linklen);
841 break; 841 break;
842 } 842 }
843 843
844 case PUFFS_VN_RECLAIM: 844 case PUFFS_VN_RECLAIM:
845 { 845 {
846 struct puffs_vnmsg_reclaim *auxt = auxbuf; 846 struct puffs_vnmsg_reclaim *auxt = auxbuf;
847 struct puffs_node *pn; 847 struct puffs_node *pn;
848  848
849 if (pops->puffs_node_reclaim2 != NULL) { 849 if (pops->puffs_node_reclaim2 != NULL) {
850 error = pops->puffs_node_reclaim2(pu, opcookie, 850 error = pops->puffs_node_reclaim2(pu, opcookie,
851 auxt->pvnr_nlookup); 851 auxt->pvnr_nlookup);
852 break; 852 break;
853 } 853 }
854 854
855 if (pops->puffs_node_reclaim == NULL) { 855 if (pops->puffs_node_reclaim == NULL) {
856 error = 0; 856 error = 0;
857 break; 857 break;
858 } 858 }
859 859
860 /* 860 /*
861 * This fixes a race condition,  861 * This fixes a race condition,
862 * where a node in reclaimed by kernel  862 * where a node in reclaimed by kernel
863 * after a lookup request is sent,  863 * after a lookup request is sent,
864 * but before the reply, leaving the kernel 864 * but before the reply, leaving the kernel
865 * with a invalid vnode/cookie reference. 865 * with a invalid vnode/cookie reference.
866 */ 866 */
867 if (pncookie) { 867 if (pncookie) {
868 pn = PU_CMAP(pu, opcookie); 868 pn = PU_CMAP(pu, opcookie);
869 pn->pn_nlookup -= auxt->pvnr_nlookup; 869 pn->pn_nlookup -= auxt->pvnr_nlookup;
870 if (pn->pn_nlookup >= 1) { 870 if (pn->pn_nlookup >= 1) {
871 error = 0; 871 error = 0;
872 break; 872 break;
873 } 873 }
874 } 874 }
875 875
876 error = pops->puffs_node_reclaim(pu, opcookie); 876 error = pops->puffs_node_reclaim(pu, opcookie);
877 break; 877 break;
878 } 878 }
879 879
880 case PUFFS_VN_INACTIVE: 880 case PUFFS_VN_INACTIVE:
881 { 881 {
882 882
883 if (pops->puffs_node_inactive == NULL) { 883 if (pops->puffs_node_inactive == NULL) {
884 error = EOPNOTSUPP; 884 error = EOPNOTSUPP;
885 break; 885 break;
886 } 886 }
887 887
888 error = pops->puffs_node_inactive(pu, opcookie); 888 error = pops->puffs_node_inactive(pu, opcookie);
889 break; 889 break;
890 } 890 }
891 891
892 case PUFFS_VN_PATHCONF: 892 case PUFFS_VN_PATHCONF:
893 { 893 {
894 struct puffs_vnmsg_pathconf *auxt = auxbuf; 894 struct puffs_vnmsg_pathconf *auxt = auxbuf;
895 if (pops->puffs_node_pathconf == NULL) { 895 if (pops->puffs_node_pathconf == NULL) {
896 error = 0; 896 error = EINVAL;
897 break; 897 break;
898 } 898 }
899 899
900 error = pops->puffs_node_pathconf(pu, 900 error = pops->puffs_node_pathconf(pu,
901 opcookie, auxt->pvnr_name, 901 opcookie, auxt->pvnr_name,
902 &auxt->pvnr_retval); 902 &auxt->pvnr_retval);
903 break; 903 break;
904 } 904 }
905 905
906 case PUFFS_VN_ADVLOCK: 906 case PUFFS_VN_ADVLOCK:
907 { 907 {
908 struct puffs_vnmsg_advlock *auxt = auxbuf; 908 struct puffs_vnmsg_advlock *auxt = auxbuf;
909 if (pops->puffs_node_advlock == NULL) { 909 if (pops->puffs_node_advlock == NULL) {
910 error = 0; 910 error = 0;
911 break; 911 break;
912 } 912 }
913 913
914 error = pops->puffs_node_advlock(pu, 914 error = pops->puffs_node_advlock(pu,
915 opcookie, auxt->pvnr_id, auxt->pvnr_op, 915 opcookie, auxt->pvnr_id, auxt->pvnr_op,
916 &auxt->pvnr_fl, auxt->pvnr_flags); 916 &auxt->pvnr_fl, auxt->pvnr_flags);
917 break; 917 break;
918 } 918 }
919 919
920 case PUFFS_VN_PRINT: 920 case PUFFS_VN_PRINT:
921 { 921 {
922 if (pops->puffs_node_print == NULL) { 922 if (pops->puffs_node_print == NULL) {
923 error = 0; 923 error = 0;
924 break; 924 break;
925 } 925 }
926 926
927 error = pops->puffs_node_print(pu, 927 error = pops->puffs_node_print(pu,
928 opcookie); 928 opcookie);
929 break; 929 break;
930 } 930 }
931 931
932 case PUFFS_VN_ABORTOP: 932 case PUFFS_VN_ABORTOP:
933 { 933 {
934 struct puffs_vnmsg_abortop *auxt = auxbuf; 934 struct puffs_vnmsg_abortop *auxt = auxbuf;
935 struct puffs_cn pcn; 935 struct puffs_cn pcn;
936 936
937 if (pops->puffs_node_abortop == NULL) { 937 if (pops->puffs_node_abortop == NULL) {
938 error = 0; 938 error = 0;
939 break; 939 break;
940 } 940 }
941 941
942 pcn.pcn_pkcnp = &auxt->pvnr_cn; 942 pcn.pcn_pkcnp = &auxt->pvnr_cn;
943 PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred); 943 PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
944 944
945 error = pops->puffs_node_abortop(pu, opcookie, &pcn); 945 error = pops->puffs_node_abortop(pu, opcookie, &pcn);
946  946
947 break; 947 break;
948 } 948 }
949 949
950 case PUFFS_VN_READ: 950 case PUFFS_VN_READ:
951 { 951 {
952 struct puffs_vnmsg_read *auxt = auxbuf; 952 struct puffs_vnmsg_read *auxt = auxbuf;
953 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 953 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
954 size_t res; 954 size_t res;
955 955
956 if (pops->puffs_node_read == NULL) { 956 if (pops->puffs_node_read == NULL) {
957 error = EIO; 957 error = EIO;
958 break; 958 break;
959 } 959 }
960 960
961 res = auxt->pvnr_resid; 961 res = auxt->pvnr_resid;
962 error = pops->puffs_node_read(pu, 962 error = pops->puffs_node_read(pu,
963 opcookie, auxt->pvnr_data, 963 opcookie, auxt->pvnr_data,
964 auxt->pvnr_offset, &auxt->pvnr_resid, 964 auxt->pvnr_offset, &auxt->pvnr_resid,
965 pcr, auxt->pvnr_ioflag); 965 pcr, auxt->pvnr_ioflag);
966 966
967 /* need to move a bit more */ 967 /* need to move a bit more */
968 preq->preq_buflen = sizeof(struct puffs_vnmsg_read) 968 preq->preq_buflen = sizeof(struct puffs_vnmsg_read)
969 + (res - auxt->pvnr_resid); 969 + (res - auxt->pvnr_resid);
970 break; 970 break;
971 } 971 }
972 972
973 case PUFFS_VN_WRITE: 973 case PUFFS_VN_WRITE:
974 { 974 {
975 struct puffs_vnmsg_write *auxt = auxbuf; 975 struct puffs_vnmsg_write *auxt = auxbuf;
976 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 976 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
977 977
978 if (pops->puffs_node_write2 != NULL) { 978 if (pops->puffs_node_write2 != NULL) {
979 int xflag = 0; 979 int xflag = 0;
980 980
981 if (!PUFFSOP_WANTREPLY(preq->preq_opclass)) 981 if (!PUFFSOP_WANTREPLY(preq->preq_opclass))
982 xflag |= PUFFS_SETATTR_FAF; 982 xflag |= PUFFS_SETATTR_FAF;
983 983
984 error = pops->puffs_node_write2(pu, 984 error = pops->puffs_node_write2(pu,
985 opcookie, auxt->pvnr_data, 985 opcookie, auxt->pvnr_data,
986 auxt->pvnr_offset, &auxt->pvnr_resid, 986 auxt->pvnr_offset, &auxt->pvnr_resid,
987 pcr, auxt->pvnr_ioflag, xflag); 987 pcr, auxt->pvnr_ioflag, xflag);
988 988
989 } else if (pops->puffs_node_write != NULL) { 989 } else if (pops->puffs_node_write != NULL) {
990 error = pops->puffs_node_write(pu, 990 error = pops->puffs_node_write(pu,
991 opcookie, auxt->pvnr_data, 991 opcookie, auxt->pvnr_data,
992 auxt->pvnr_offset, &auxt->pvnr_resid, 992 auxt->pvnr_offset, &auxt->pvnr_resid,
993 pcr, auxt->pvnr_ioflag); 993 pcr, auxt->pvnr_ioflag);
994 } else { 994 } else {
995 error = EIO; 995 error = EIO;
996 break; 996 break;
997 } 997 }
998 998
999 999
1000 /* don't need to move data back to the kernel */ 1000 /* don't need to move data back to the kernel */
1001 preq->preq_buflen = sizeof(struct puffs_vnmsg_write); 1001 preq->preq_buflen = sizeof(struct puffs_vnmsg_write);
1002 break; 1002 break;
1003 } 1003 }
1004 1004
1005 case PUFFS_VN_POLL: 1005 case PUFFS_VN_POLL:
1006 { 1006 {
1007 struct puffs_vnmsg_poll *auxt = auxbuf; 1007 struct puffs_vnmsg_poll *auxt = auxbuf;
1008 1008
1009 if (pops->puffs_node_poll == NULL) { 1009 if (pops->puffs_node_poll == NULL) {
1010 error = 0; 1010 error = 0;
1011 1011
1012 /* emulate genfs_poll() */ 1012 /* emulate genfs_poll() */
1013 auxt->pvnr_events &= (POLLIN | POLLOUT 1013 auxt->pvnr_events &= (POLLIN | POLLOUT
1014 | POLLRDNORM | POLLWRNORM); 1014 | POLLRDNORM | POLLWRNORM);
1015 1015
1016 break; 1016 break;
1017 } 1017 }
1018 1018
1019 error = pops->puffs_node_poll(pu, 1019 error = pops->puffs_node_poll(pu,
1020 opcookie, &auxt->pvnr_events); 1020 opcookie, &auxt->pvnr_events);
1021 break; 1021 break;
1022 } 1022 }
1023 1023
1024 case PUFFS_VN_GETEXTATTR: 1024 case PUFFS_VN_GETEXTATTR:
1025 { 1025 {
1026 struct puffs_vnmsg_getextattr *auxt = auxbuf; 1026 struct puffs_vnmsg_getextattr *auxt = auxbuf;
1027 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 1027 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
1028 size_t res, *resp, *sizep; 1028 size_t res, *resp, *sizep;
1029 uint8_t *data; 1029 uint8_t *data;
1030 1030
1031 if (pops->puffs_node_getextattr == NULL) { 1031 if (pops->puffs_node_getextattr == NULL) {
1032 error = EOPNOTSUPP; 1032 error = EOPNOTSUPP;
1033 break; 1033 break;
1034 } 1034 }
1035 1035
1036 if (auxt->pvnr_datasize) 1036 if (auxt->pvnr_datasize)
1037 sizep = &auxt->pvnr_datasize; 1037 sizep = &auxt->pvnr_datasize;
1038 else 1038 else
1039 sizep = NULL; 1039 sizep = NULL;
1040 1040
1041 res = auxt->pvnr_resid; 1041 res = auxt->pvnr_resid;
1042 if (res > 0) { 1042 if (res > 0) {
1043 data = auxt->pvnr_data; 1043 data = auxt->pvnr_data;
1044 resp = &auxt->pvnr_resid; 1044 resp = &auxt->pvnr_resid;
1045 } else { 1045 } else {
1046 data = NULL; 1046 data = NULL;
1047 resp = NULL; 1047 resp = NULL;
1048 } 1048 }
1049 1049
1050 error = pops->puffs_node_getextattr(pu, 1050 error = pops->puffs_node_getextattr(pu,
1051 opcookie, auxt->pvnr_attrnamespace, 1051 opcookie, auxt->pvnr_attrnamespace,
1052 auxt->pvnr_attrname, sizep, data, resp, pcr); 1052 auxt->pvnr_attrname, sizep, data, resp, pcr);
1053 1053
1054 /* need to move a bit more? */ 1054 /* need to move a bit more? */
1055 preq->preq_buflen = 1055 preq->preq_buflen =
1056 sizeof(struct puffs_vnmsg_getextattr) 1056 sizeof(struct puffs_vnmsg_getextattr)
1057 + (res - auxt->pvnr_resid); 1057 + (res - auxt->pvnr_resid);
1058 break; 1058 break;
1059 } 1059 }
1060 1060
1061 case PUFFS_VN_SETEXTATTR: 1061 case PUFFS_VN_SETEXTATTR:
1062 { 1062 {
1063 struct puffs_vnmsg_setextattr *auxt = auxbuf; 1063 struct puffs_vnmsg_setextattr *auxt = auxbuf;
1064 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 1064 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
1065 size_t *resp; 1065 size_t *resp;
1066 uint8_t *data; 1066 uint8_t *data;
1067 1067
1068 if (pops->puffs_node_setextattr == NULL) { 1068 if (pops->puffs_node_setextattr == NULL) {
1069 error = EOPNOTSUPP; 1069 error = EOPNOTSUPP;
1070 break; 1070 break;
1071 } 1071 }
1072 1072
1073 if (auxt->pvnr_resid > 0) { 1073 if (auxt->pvnr_resid > 0) {
1074 data = auxt->pvnr_data; 1074 data = auxt->pvnr_data;
1075 resp = &auxt->pvnr_resid; 1075 resp = &auxt->pvnr_resid;
1076 } else { 1076 } else {
1077 data = NULL; 1077 data = NULL;
1078 resp = NULL; 1078 resp = NULL;
1079 } 1079 }
1080 1080
1081 error = pops->puffs_node_setextattr(pu, 1081 error = pops->puffs_node_setextattr(pu,
1082 opcookie, auxt->pvnr_attrnamespace, 1082 opcookie, auxt->pvnr_attrnamespace,
1083 auxt->pvnr_attrname, data, resp, pcr); 1083 auxt->pvnr_attrname, data, resp, pcr);
1084 break; 1084 break;
1085 } 1085 }
1086 1086
1087 case PUFFS_VN_LISTEXTATTR: 1087 case PUFFS_VN_LISTEXTATTR:
1088 { 1088 {
1089 struct puffs_vnmsg_listextattr *auxt = auxbuf; 1089 struct puffs_vnmsg_listextattr *auxt = auxbuf;
1090 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 1090 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
1091 size_t res, *resp, *sizep; 1091 size_t res, *resp, *sizep;
1092 int flag; 1092 int flag;
1093 uint8_t *data; 1093 uint8_t *data;
1094 1094
1095 if (pops->puffs_node_listextattr == NULL) { 1095 if (pops->puffs_node_listextattr == NULL) {
1096 error = EOPNOTSUPP; 1096 error = EOPNOTSUPP;
1097 break; 1097 break;
1098 } 1098 }
1099 1099
1100 if (auxt->pvnr_datasize) 1100 if (auxt->pvnr_datasize)
1101 sizep = &auxt->pvnr_datasize; 1101 sizep = &auxt->pvnr_datasize;
1102 else 1102 else
1103 sizep = NULL; 1103 sizep = NULL;
1104 1104
1105 res = auxt->pvnr_resid; 1105 res = auxt->pvnr_resid;
1106 if (res > 0) { 1106 if (res > 0) {
1107 data = auxt->pvnr_data; 1107 data = auxt->pvnr_data;
1108 resp = &auxt->pvnr_resid; 1108 resp = &auxt->pvnr_resid;
1109 } else { 1109 } else {
1110 data = NULL; 1110 data = NULL;
1111 resp = NULL; 1111 resp = NULL;
1112 } 1112 }
1113 1113
1114 res = auxt->pvnr_resid; 1114 res = auxt->pvnr_resid;
1115 flag = auxt->pvnr_flag; 1115 flag = auxt->pvnr_flag;
1116 error = pops->puffs_node_listextattr(pu, 1116 error = pops->puffs_node_listextattr(pu,
1117 opcookie, auxt->pvnr_attrnamespace, 1117 opcookie, auxt->pvnr_attrnamespace,
1118 sizep, data, resp, flag, pcr); 1118 sizep, data, resp, flag, pcr);
1119 1119
1120 /* need to move a bit more? */ 1120 /* need to move a bit more? */
1121 preq->preq_buflen = 1121 preq->preq_buflen =
1122 sizeof(struct puffs_vnmsg_listextattr) 1122 sizeof(struct puffs_vnmsg_listextattr)
1123 + (res - auxt->pvnr_resid); 1123 + (res - auxt->pvnr_resid);
1124 break; 1124 break;
1125 } 1125 }
1126 1126
1127 case PUFFS_VN_DELETEEXTATTR: 1127 case PUFFS_VN_DELETEEXTATTR:
1128 { 1128 {
1129 struct puffs_vnmsg_deleteextattr *auxt = auxbuf; 1129 struct puffs_vnmsg_deleteextattr *auxt = auxbuf;
1130 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred); 1130 PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
1131 1131
1132 if (pops->puffs_node_deleteextattr == NULL) { 1132 if (pops->puffs_node_deleteextattr == NULL) {
1133 error = EOPNOTSUPP; 1133 error = EOPNOTSUPP;
1134 break; 1134 break;
1135 } 1135 }
1136 1136
1137 error = pops->puffs_node_deleteextattr(pu, 1137 error = pops->puffs_node_deleteextattr(pu,
1138 opcookie, auxt->pvnr_attrnamespace, 1138 opcookie, auxt->pvnr_attrnamespace,
1139 auxt->pvnr_attrname, pcr); 1139 auxt->pvnr_attrname, pcr);
1140 break; 1140 break;
1141 } 1141 }
1142 1142
1143 case PUFFS_VN_FALLOCATE: 1143 case PUFFS_VN_FALLOCATE:
1144 { 1144 {
1145 struct puffs_vnmsg_fallocate *auxt = auxbuf; 1145 struct puffs_vnmsg_fallocate *auxt = auxbuf;
1146 1146
1147 if (pops->puffs_node_fallocate == NULL) { 1147 if (pops->puffs_node_fallocate == NULL) {
1148 error = EOPNOTSUPP; 1148 error = EOPNOTSUPP;
1149 break; 1149 break;
1150 } 1150 }
1151 1151
1152 error = pops->puffs_node_fallocate(pu, 1152 error = pops->puffs_node_fallocate(pu,
1153 opcookie, auxt->pvnr_off, auxt->pvnr_len); 1153 opcookie, auxt->pvnr_off, auxt->pvnr_len);
1154 break; 1154 break;
1155 } 1155 }
1156 1156
1157 case PUFFS_VN_FDISCARD: 1157 case PUFFS_VN_FDISCARD:
1158 { 1158 {
1159 struct puffs_vnmsg_fdiscard *auxt = auxbuf; 1159 struct puffs_vnmsg_fdiscard *auxt = auxbuf;
1160 1160
1161 if (pops->puffs_node_fdiscard == NULL) { 1161 if (pops->puffs_node_fdiscard == NULL) {
1162 error = EOPNOTSUPP; 1162 error = EOPNOTSUPP;
1163 break; 1163 break;
1164 } 1164 }
1165 1165
1166 error = pops->puffs_node_fdiscard(pu, 1166 error = pops->puffs_node_fdiscard(pu,
1167 opcookie, auxt->pvnr_off, auxt->pvnr_len); 1167 opcookie, auxt->pvnr_off, auxt->pvnr_len);
1168 break; 1168 break;
1169 } 1169 }
1170 1170
1171 default: 1171 default:
1172 printf("inval op %d\n", preq->preq_optype); 1172 printf("inval op %d\n", preq->preq_optype);
1173 error = EINVAL; 1173 error = EINVAL;
1174 break; 1174 break;
1175 } 1175 }
1176 1176
1177#if 0 1177#if 0
1178 /* not issued by kernel currently */ 1178 /* not issued by kernel currently */
1179 } else if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_CACHE) { 1179 } else if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_CACHE) {
1180 struct puffs_cacheinfo *pci = (void *)preq; 1180 struct puffs_cacheinfo *pci = (void *)preq;
1181 1181
1182 if (pu->pu_ops.puffs_cache_write) { 1182 if (pu->pu_ops.puffs_cache_write) {
1183 pu->pu_ops.puffs_cache_write(pu, preq->preq_cookie, 1183 pu->pu_ops.puffs_cache_write(pu, preq->preq_cookie,
1184 pci->pcache_nruns, pci->pcache_runs); 1184 pci->pcache_nruns, pci->pcache_runs);
1185 } 1185 }
1186 error = 0; 1186 error = 0;
1187#endif 1187#endif
1188 1188
1189 } else if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_ERROR) { 1189 } else if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_ERROR) {
1190 struct puffs_error *perr = (void *)preq; 1190 struct puffs_error *perr = (void *)preq;
1191 1191
1192 pu->pu_errnotify(pu, preq->preq_optype, 1192 pu->pu_errnotify(pu, preq->preq_optype,
1193 perr->perr_error, perr->perr_str, preq->preq_cookie); 1193 perr->perr_error, perr->perr_str, preq->preq_cookie);
1194 error = 0; 1194 error = 0;
1195 } else { 1195 } else {
1196 /* 1196 /*
1197 * I guess the kernel sees this one coming also 1197 * I guess the kernel sees this one coming also
1198 */ 1198 */
1199 error = EINVAL; 1199 error = EINVAL;
1200 } 1200 }
1201 1201
1202 out: 1202 out:
1203 preq->preq_rv = error; 1203 preq->preq_rv = error;
1204 1204
1205 if (pu->pu_oppost) 1205 if (pu->pu_oppost)
1206 pu->pu_oppost(pu); 1206 pu->pu_oppost(pu);
1207 1207
1208 pcc->pcc_flags |= PCC_DONE; 1208 pcc->pcc_flags |= PCC_DONE;
1209} 1209}