puffs.c revision 1.3 1 /* $NetBSD: puffs.c,v 1.3 2006/10/25 18:15:50 pooka Exp $ */
2
3 /*
4 * Copyright (c) 2005, 2006 Antti Kantee. All Rights Reserved.
5 *
6 * Development of this software was supported by the
7 * Google Summer of Code program and the Ulla Tuominen Foundation.
8 * The Google SoC project was mentored by Bill Studenmund.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. The name of the company nor the name of the author may be used to
19 * endorse or promote products derived from this software without specific
20 * prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
23 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35 #include <sys/cdefs.h>
36 #if !defined(lint)
37 __RCSID("$NetBSD: puffs.c,v 1.3 2006/10/25 18:15:50 pooka Exp $");
38 #endif /* !lint */
39
40 #include <sys/param.h>
41 #include <sys/mount.h>
42
43 #include <errno.h>
44 #include <fcntl.h>
45 #include <puffs.h>
46 #include <puffsdump.h>
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <string.h>
50 #include <syslog.h>
51 #include <unistd.h>
52
53 static int puffcall(struct puffs_usermount *, struct puffs_req *);
54
55 #define eret(a) do {errno=(a);goto failfree;}while/*NOTREACHED*/(/*CONSTCOND*/0)
56
57 struct puffs_usermount *
58 puffs_mount(struct puffs_vfsops *pvfs, struct puffs_vnops *pvn,
59 const char *dir, int mntflags, const char *puffsname,
60 uint32_t pflags, size_t maxreqlen)
61 {
62 struct puffs_args pargs;
63 struct puffs_vfsreq_start sreq;
64 struct puffs_usermount *pu;
65 int fd;
66
67 pu = NULL;
68
69 if (pvfs->puffs_start == NULL)
70 eret(EINVAL);
71
72 fd = open("/dev/puffs", O_RDONLY);
73 if (fd == -1)
74 return NULL;
75
76 pargs.pa_vers = 0; /* XXX: for now */
77 pargs.pa_flags = pflags;
78 pargs.pa_fd = fd;
79 pargs.pa_maxreqlen = maxreqlen;
80 (void)strlcpy(pargs.pa_name, puffsname, sizeof(pargs.pa_name));
81
82 pu = malloc(sizeof(struct puffs_usermount));
83 if (!pu)
84 eret(ENOMEM);
85
86 pu->pu_flags = pflags;
87 pu->pu_pvfs = *pvfs;
88 pu->pu_pvn = *pvn;
89 pu->pu_fd = fd;
90 if ((pu->pu_rootpath = strdup(dir)) == NULL)
91 eret(ENOMEM);
92 LIST_INIT(&pu->pu_pnodelst);
93
94 if (mount(MOUNT_PUFFS, dir, mntflags, &pargs) == -1)
95 return NULL;
96 pu->pu_maxreqlen = pargs.pa_maxreqlen;
97
98 if (pu->pu_pvfs.puffs_start(pu, &sreq) != 0)
99 return NULL;
100
101 /* tell kernel we're flying */
102 if (ioctl(pu->pu_fd, PUFFSMOUNTOP, &sreq) == -1)
103 return NULL;
104
105 return pu;
106 failfree:
107 free(pu);
108 return NULL;
109 }
110
111 int
112 puffs_mainloop(struct puffs_usermount *pu)
113 {
114 uint8_t *buf;
115 int rv;
116
117 buf = malloc(pu->pu_maxreqlen);
118 if (!buf)
119 return -1;
120
121 for (;;)
122 if ((rv = puffs_oneop(pu, buf, pu->pu_maxreqlen)) != 0)
123 return rv;
124 }
125
126 int
127 puffs_oneop(struct puffs_usermount *pu, uint8_t *buf, size_t buflen)
128 {
129 struct puffs_req preq;
130 int rv;
131
132 preq.preq_aux = buf;
133 preq.preq_auxlen = buflen;
134
135 /* get op from kernel */
136 if (ioctl(pu->pu_fd, PUFFSGETOP, &preq) == -1)
137 return -1;
138
139 /* deal with it */
140 rv = puffcall(pu, &preq);
141
142 /* stuff result back to the kernel */
143 if (ioctl(pu->pu_fd, PUFFSPUTOP, &preq) == -1)
144 return -1;
145
146 return rv;
147 }
148
149 int
150 puffs_getselectable(struct puffs_usermount *pu)
151 {
152
153 return pu->pu_fd;
154 }
155
156 int
157 puffs_setblockingmode(struct puffs_usermount *pu, int block)
158 {
159 int x;
160
161 x = !block;
162 return ioctl(pu->pu_fd, FIONBIO, &x);
163 }
164
165 static int
166 puffcall(struct puffs_usermount *pu, struct puffs_req *preq)
167 {
168 struct puffs_sizeop pop;
169 int error, rv;
170
171 rv = 0;
172
173 if (pu->pu_flags & PUFFSFLAG_OPDUMP)
174 puffsdump_req(preq);
175
176 if (preq->preq_opclass == PUFFSOP_VFS) {
177 switch (preq->preq_optype) {
178 case PUFFS_VFS_UNMOUNT:
179 {
180 struct puffs_vfsreq_unmount *auxt = preq->preq_aux;
181
182 error = pu->pu_pvfs.puffs_unmount(pu,
183 auxt->pvfsr_flags, auxt->pvfsr_pid);
184 rv = 1;
185 break;
186 }
187 case PUFFS_VFS_STATVFS:
188 {
189 struct puffs_vfsreq_statvfs *auxt = preq->preq_aux;
190
191 error = pu->pu_pvfs.puffs_statvfs(pu,
192 &auxt->pvfsr_sb, auxt->pvfsr_pid);
193 break;
194 }
195 case PUFFS_VFS_SYNC:
196 {
197 struct puffs_vfsreq_sync *auxt = preq->preq_aux;
198
199 error = pu->pu_pvfs.puffs_sync(pu,
200 auxt->pvfsr_waitfor, &auxt->pvfsr_cred,
201 auxt->pvfsr_pid);
202 break;
203 }
204 default:
205 /*
206 * I guess the kernel sees this one coming
207 */
208 error = EINVAL;
209 break;
210 }
211
212 /* XXX: audit return values */
213 } else if (preq->preq_opclass == PUFFSOP_VN) {
214 switch (preq->preq_optype) {
215 case PUFFS_VN_LOOKUP:
216 {
217 struct puffs_vnreq_lookup *auxt = preq->preq_aux;
218
219 /* lookup *must* be present */
220 error = pu->pu_pvn.puffs_lookup(pu, preq->preq_cookie,
221 &auxt->pvnr_newnode, &auxt->pvnr_vtype,
222 &auxt->pvnr_cn);
223 break;
224 }
225
226 case PUFFS_VN_CREATE:
227 {
228 struct puffs_vnreq_create *auxt = preq->preq_aux;
229 if (pu->pu_pvn.puffs_create == NULL) {
230 error = 0;
231 break;
232 }
233
234 error = pu->pu_pvn.puffs_create(pu,
235 preq->preq_cookie, &auxt->pvnr_newnode,
236 &auxt->pvnr_cn, &auxt->pvnr_va);
237 break;
238 }
239
240 case PUFFS_VN_MKNOD:
241 {
242 struct puffs_vnreq_mknod *auxt = preq->preq_aux;
243 if (pu->pu_pvn.puffs_mknod == NULL) {
244 error = 0;
245 break;
246 }
247
248 error = pu->pu_pvn.puffs_mknod(pu,
249 preq->preq_cookie, &auxt->pvnr_newnode,
250 &auxt->pvnr_cn, &auxt->pvnr_va);
251 break;
252 }
253
254 case PUFFS_VN_OPEN:
255 {
256 struct puffs_vnreq_open *auxt = preq->preq_aux;
257 if (pu->pu_pvn.puffs_open == NULL) {
258 error = 0;
259 break;
260 }
261
262 error = pu->pu_pvn.puffs_open(pu,
263 preq->preq_cookie, auxt->pvnr_mode,
264 &auxt->pvnr_cred, auxt->pvnr_pid);
265 break;
266 }
267
268 case PUFFS_VN_CLOSE:
269 {
270 struct puffs_vnreq_close *auxt = preq->preq_aux;
271 if (pu->pu_pvn.puffs_close == NULL) {
272 error = 0;
273 break;
274 }
275
276 error = pu->pu_pvn.puffs_close(pu,
277 preq->preq_cookie, auxt->pvnr_fflag,
278 &auxt->pvnr_cred, auxt->pvnr_pid);
279 break;
280 }
281
282 case PUFFS_VN_ACCESS:
283 {
284 struct puffs_vnreq_access *auxt = preq->preq_aux;
285 if (pu->pu_pvn.puffs_access == NULL) {
286 error = 0;
287 break;
288 }
289
290 error = pu->pu_pvn.puffs_access(pu,
291 preq->preq_cookie, auxt->pvnr_mode,
292 &auxt->pvnr_cred, auxt->pvnr_pid);
293 break;
294 }
295
296 case PUFFS_VN_GETATTR:
297 {
298 struct puffs_vnreq_getattr *auxt = preq->preq_aux;
299 if (pu->pu_pvn.puffs_getattr == NULL) {
300 error = 0;
301 break;
302 }
303
304 error = pu->pu_pvn.puffs_getattr(pu,
305 preq->preq_cookie, &auxt->pvnr_va,
306 &auxt->pvnr_cred, auxt->pvnr_pid);
307 break;
308 }
309
310 case PUFFS_VN_SETATTR:
311 {
312 struct puffs_vnreq_setattr *auxt = preq->preq_aux;
313 if (pu->pu_pvn.puffs_setattr == NULL) {
314 error = 0;
315 break;
316 }
317
318 error = pu->pu_pvn.puffs_setattr(pu,
319 preq->preq_cookie, &auxt->pvnr_va,
320 &auxt->pvnr_cred, auxt->pvnr_pid);
321 break;
322 }
323
324 /* notyet */
325 #if 0
326 case PUFFS_VN_POLL:
327 {
328 struct puffs_vnreq_poll *auxt = preq->preq_aux;
329 if (pu->pu_pvn.puffs_poll == NULL) {
330 error = 0;
331 break;
332 }
333
334 error = pu->pu_pvn.puffs_poll(pu,
335 preq->preq_cookie, preq-);
336 break;
337 }
338
339 case PUFFS_VN_KQFILTER:
340 {
341 struct puffs_vnreq_kqfilter *auxt = preq->preq_aux;
342 if (pu->pu_pvn.puffs_kqfilter == NULL) {
343 error = 0;
344 break;
345 }
346
347 error = pu->pu_pvn.puffs_kqfilter(pu,
348 preq->preq_cookie, );
349 break;
350 }
351
352 case PUFFS_VN_MMAP:
353 {
354 struct puffs_vnreq_mmap *auxt = preq->preq_aux;
355 if (pu->pu_pvn.puffs_mmap == NULL) {
356 error = 0;
357 break;
358 }
359
360 error = pu->pu_pvn.puffs_mmap(pu,
361 preq->preq_cookie, );
362 break;
363 }
364 #endif
365
366 case PUFFS_VN_REVOKE:
367 {
368 struct puffs_vnreq_revoke *auxt = preq->preq_aux;
369 if (pu->pu_pvn.puffs_revoke == NULL) {
370 error = 0;
371 break;
372 }
373
374 error = pu->pu_pvn.puffs_revoke(pu,
375 preq->preq_cookie, auxt->pvnr_flags);
376 break;
377 }
378
379 case PUFFS_VN_FSYNC:
380 {
381 struct puffs_vnreq_fsync *auxt = preq->preq_aux;
382 if (pu->pu_pvn.puffs_fsync == NULL) {
383 error = 0;
384 break;
385 }
386
387 error = pu->pu_pvn.puffs_fsync(pu,
388 preq->preq_cookie, &auxt->pvnr_cred,
389 auxt->pvnr_flags, auxt->pvnr_offlo,
390 auxt->pvnr_offhi, auxt->pvnr_pid);
391 break;
392 }
393
394 case PUFFS_VN_SEEK:
395 {
396 struct puffs_vnreq_seek *auxt = preq->preq_aux;
397 if (pu->pu_pvn.puffs_seek == NULL) {
398 error = 0;
399 break;
400 }
401
402 error = pu->pu_pvn.puffs_seek(pu,
403 preq->preq_cookie, auxt->pvnr_oldoff,
404 auxt->pvnr_newoff, &auxt->pvnr_cred);
405 break;
406 }
407
408 case PUFFS_VN_REMOVE:
409 {
410 struct puffs_vnreq_remove *auxt = preq->preq_aux;
411 if (pu->pu_pvn.puffs_remove == NULL) {
412 error = 0;
413 break;
414 }
415
416 error = pu->pu_pvn.puffs_remove(pu,
417 preq->preq_cookie, auxt->pvnr_cookie_targ,
418 &auxt->pvnr_cn);
419 break;
420 }
421
422 case PUFFS_VN_LINK:
423 {
424 struct puffs_vnreq_link *auxt = preq->preq_aux;
425 if (pu->pu_pvn.puffs_link == NULL) {
426 error = 0;
427 break;
428 }
429
430 error = pu->pu_pvn.puffs_link(pu,
431 preq->preq_cookie, auxt->pvnr_cookie_targ,
432 &auxt->pvnr_cn);
433 break;
434 }
435
436 case PUFFS_VN_RENAME:
437 {
438 struct puffs_vnreq_rename *auxt = preq->preq_aux;
439 if (pu->pu_pvn.puffs_rename == NULL) {
440 error = 0;
441 break;
442 }
443
444 error = pu->pu_pvn.puffs_rename(pu,
445 preq->preq_cookie, auxt->pvnr_cookie_src,
446 &auxt->pvnr_cn_src, auxt->pvnr_cookie_targdir,
447 auxt->pvnr_cookie_targ, &auxt->pvnr_cn_targ);
448 break;
449 }
450
451 case PUFFS_VN_MKDIR:
452 {
453 struct puffs_vnreq_mkdir *auxt = preq->preq_aux;
454 if (pu->pu_pvn.puffs_mkdir == NULL) {
455 error = 0;
456 break;
457 }
458
459 error = pu->pu_pvn.puffs_mkdir(pu,
460 preq->preq_cookie, &auxt->pvnr_newnode,
461 &auxt->pvnr_cn, &auxt->pvnr_va);
462 break;
463 }
464
465 case PUFFS_VN_RMDIR:
466 {
467 struct puffs_vnreq_rmdir *auxt = preq->preq_aux;
468 if (pu->pu_pvn.puffs_rmdir == NULL) {
469 error = 0;
470 break;
471 }
472
473 error = pu->pu_pvn.puffs_rmdir(pu,
474 preq->preq_cookie, auxt->pvnr_cookie_targ,
475 &auxt->pvnr_cn);
476 break;
477 }
478
479 case PUFFS_VN_SYMLINK:
480 {
481 struct puffs_vnreq_symlink *auxt = preq->preq_aux;
482 if (pu->pu_pvn.puffs_symlink == NULL) {
483 error = 0;
484 break;
485 }
486
487 error = pu->pu_pvn.puffs_symlink(pu,
488 preq->preq_cookie, &auxt->pvnr_newnode,
489 &auxt->pvnr_cn, &auxt->pvnr_va, auxt->pvnr_link);
490 break;
491 }
492
493 case PUFFS_VN_READDIR:
494 {
495 struct puffs_vnreq_readdir *auxt = preq->preq_aux;
496 size_t res;
497
498 if (pu->pu_pvn.puffs_readdir == NULL) {
499 error = 0;
500 break;
501 }
502
503 res = auxt->pvnr_resid;
504 error = pu->pu_pvn.puffs_readdir(pu,
505 preq->preq_cookie, auxt->pvnr_dent,
506 &auxt->pvnr_cred, &auxt->pvnr_offset,
507 &auxt->pvnr_resid);
508
509 /* need to move a bit more */
510 preq->preq_auxlen += res - auxt->pvnr_resid;
511 break;
512 }
513
514 case PUFFS_VN_READLINK:
515 {
516 struct puffs_vnreq_readlink *auxt = preq->preq_aux;
517 if (pu->pu_pvn.puffs_readlink == NULL) {
518 error = EOPNOTSUPP;
519 break;
520 }
521
522 error = pu->pu_pvn.puffs_readlink(pu,
523 preq->preq_cookie, &auxt->pvnr_cred,
524 auxt->pvnr_link, &auxt->pvnr_linklen);
525 break;
526 }
527
528 case PUFFS_VN_RECLAIM:
529 {
530 struct puffs_vnreq_reclaim *auxt = preq->preq_aux;
531 if (pu->pu_pvn.puffs_reclaim == NULL) {
532 error = 0;
533 break;
534 }
535
536 error = pu->pu_pvn.puffs_reclaim(pu,
537 preq->preq_cookie, auxt->pvnr_pid);
538 break;
539 }
540
541 case PUFFS_VN_INACTIVE:
542 {
543 struct puffs_vnreq_inactive *auxt = preq->preq_aux;
544 if (pu->pu_pvn.puffs_inactive == NULL) {
545 error = EOPNOTSUPP;
546 break;
547 }
548
549 error = pu->pu_pvn.puffs_inactive(pu,
550 preq->preq_cookie, auxt->pvnr_pid,
551 &auxt->pvnr_backendrefs);
552 break;
553 }
554
555 case PUFFS_VN_PATHCONF:
556 {
557 struct puffs_vnreq_pathconf *auxt = preq->preq_aux;
558 if (pu->pu_pvn.puffs_pathconf == NULL) {
559 error = 0;
560 break;
561 }
562
563 error = pu->pu_pvn.puffs_pathconf(pu,
564 preq->preq_cookie, auxt->pvnr_name,
565 &auxt->pvnr_retval);
566 break;
567 }
568
569 case PUFFS_VN_ADVLOCK:
570 {
571 struct puffs_vnreq_advlock *auxt = preq->preq_aux;
572 if (pu->pu_pvn.puffs_advlock == NULL) {
573 error = 0;
574 break;
575 }
576
577 error = pu->pu_pvn.puffs_advlock(pu,
578 preq->preq_cookie, auxt->pvnr_id, auxt->pvnr_op,
579 &auxt->pvnr_fl, auxt->pvnr_flags);
580 break;
581 }
582
583 case PUFFS_VN_PRINT:
584 {
585 if (pu->pu_pvn.puffs_print == NULL) {
586 error = 0;
587 break;
588 }
589
590 error = pu->pu_pvn.puffs_print(pu,
591 preq->preq_cookie);
592 break;
593 }
594
595 case PUFFS_VN_READ:
596 {
597 struct puffs_vnreq_read *auxt = preq->preq_aux;
598 size_t res;
599
600 if (pu->pu_pvn.puffs_read == NULL) {
601 error = EIO;
602 break;
603 }
604
605 res = auxt->pvnr_resid;
606 error = pu->pu_pvn.puffs_read(pu,
607 preq->preq_cookie, auxt->pvnr_data,
608 auxt->pvnr_offset, &auxt->pvnr_resid,
609 &auxt->pvnr_cred, auxt->pvnr_ioflag);
610
611 /* need to move a bit more */
612 preq->preq_auxlen += res - auxt->pvnr_resid;
613 break;
614 }
615
616 case PUFFS_VN_WRITE:
617 {
618 struct puffs_vnreq_write *auxt = preq->preq_aux;
619
620 if (pu->pu_pvn.puffs_write == NULL) {
621 error = EIO;
622 break;
623 }
624
625 error = pu->pu_pvn.puffs_write(pu,
626 preq->preq_cookie, auxt->pvnr_data,
627 auxt->pvnr_offset, &auxt->pvnr_resid,
628 &auxt->pvnr_cred, auxt->pvnr_ioflag);
629
630 /* don't need to move data back to the kernel */
631 preq->preq_auxlen = sizeof(struct puffs_vnreq_write);
632 break;
633 }
634
635 case PUFFS_VN_IOCTL:
636 error = pu->pu_pvn.puffs_ioctl1(pu, preq->preq_cookie,
637 (struct puffs_vnreq_ioctl *)preq->preq_aux, &pop);
638 if (error != 0)
639 break;
640 pop.pso_reqid = preq->preq_id;
641
642 /* let the kernel do it's intermediate duty */
643 error = ioctl(pu->pu_fd, PUFFSSIZEOP, &pop);
644 /*
645 * XXX: I don't actually know what the correct
646 * thing to do in case of an error is, so I'll
647 * just ignore it for the time being.
648 */
649 error = pu->pu_pvn.puffs_ioctl2(pu, preq->preq_cookie,
650 (struct puffs_vnreq_ioctl *)preq->preq_aux, &pop);
651 break;
652
653 case PUFFS_VN_FCNTL:
654 error = pu->pu_pvn.puffs_fcntl1(pu, preq->preq_cookie,
655 (struct puffs_vnreq_fcntl *)preq->preq_aux, &pop);
656 if (error != 0)
657 break;
658 pop.pso_reqid = preq->preq_id;
659
660 /* let the kernel do it's intermediate duty */
661 error = ioctl(pu->pu_fd, PUFFSSIZEOP, &pop);
662 /*
663 * XXX: I don't actually know what the correct
664 * thing to do in case of an error is, so I'll
665 * just ignore it for the time being.
666 */
667 error = pu->pu_pvn.puffs_fcntl2(pu, preq->preq_cookie,
668 (struct puffs_vnreq_fcntl *)preq->preq_aux, &pop);
669 break;
670
671 default:
672 printf("inval op %d\n", preq->preq_optype);
673 error = EINVAL;
674 break;
675 }
676 } else {
677 /*
678 * this one also
679 */
680 error = EINVAL;
681 }
682
683 preq->preq_rv = error;
684 return rv;
685 }
686
687
688 #if 0
689 case PUFFS_VN_IOCTL:
690 {
691 struct puffs_vnreq_ioctl *auxt = preq->preq_aux;
692 if (pu->pu_pvn.puffs_ioctl == NULL) {
693 error = 0;
694 break;
695 }
696
697 error = pu->pu_pvn.puffs_ioctl(pu,
698 preq->preq_cookie, );
699 break;
700 }
701
702 case PUFFS_VN_FCNTL:
703 {
704 struct puffs_vnreq_fcntl *auxt = preq->preq_aux;
705 if (pu->pu_pvn.puffs_fcntl == NULL) {
706 error = 0;
707 break;
708 }
709
710 error = pu->pu_pvn.puffs_fcntl(pu,
711 preq->preq_cookie, );
712 break;
713 }
714
715
716 case PUFFS_VN_ABORTOP:
717 {
718 struct puffs_vnreq_abortop *auxt = preq->preq_aux;
719 if (pu->pu_pvn.puffs_abortop == NULL) {
720 error = 0;
721 break;
722 }
723
724 error = pu->pu_pvn.puffs_abortop(pu,
725 preq->preq_cookie, );
726 break;
727 }
728
729 case PUFFS_VN_LOCK:
730 {
731 struct puffs_vnreq_lock *auxt = preq->preq_aux;
732 if (pu->pu_pvn.puffs_lock == NULL) {
733 error = 0;
734 break;
735 }
736
737 error = pu->pu_pvn.puffs_lock(pu,
738 preq->preq_cookie, );
739 break;
740 }
741
742 case PUFFS_VN_UNLOCK:
743 {
744 struct puffs_vnreq_unlock *auxt = preq->preq_aux;
745 if (pu->pu_pvn.puffs_unlock == NULL) {
746 error = 0;
747 break;
748 }
749
750 error = pu->pu_pvn.puffs_unlock(pu,
751 preq->preq_cookie, );
752 break;
753 }
754
755 case PUFFS_VN_ISLOCKED:
756 {
757 struct puffs_vnreq_islocked *auxt = preq->preq_aux;
758 if (pu->pu_pvn.puffs_islocked == NULL) {
759 error = 0;
760 break;
761 }
762
763 error = pu->pu_pvn.puffs_islocked(pu,
764 preq->preq_cookie, );
765 break;
766 }
767
768 case PUFFS_VN_LEASE:
769 {
770 struct puffs_vnreq_lease *auxt = preq->preq_aux;
771 if (pu->pu_pvn.puffs_lease == NULL) {
772 error = 0;
773 break;
774 }
775
776 error = pu->pu_pvn.puffs_lease(pu,
777 preq->preq_cookie, );
778 break;
779 }
780
781 case PUFFS_VN_WHITEOUT:
782 {
783 struct puffs_vnreq_whiteout *auxt = preq->preq_aux;
784 if (pu->pu_pvn.puffs_whiteout == NULL) {
785 error = 0;
786 break;
787 }
788
789 error = pu->pu_pvn.puffs_whiteout(pu,
790 preq->preq_cookie, );
791 break;
792 }
793
794 case PUFFS_VN_GETPAGES:
795 {
796 struct puffs_vnreq_getpages *auxt = preq->preq_aux;
797 if (pu->pu_pvn.puffs_getpages == NULL) {
798 error = 0;
799 break;
800 }
801
802 error = pu->pu_pvn.puffs_getpages(pu,
803 preq->preq_cookie, );
804 break;
805 }
806
807 case PUFFS_VN_PUTPAGES:
808 {
809 struct puffs_vnreq_putpages *auxt = preq->preq_aux;
810 if (pu->pu_pvn.puffs_putpages == NULL) {
811 error = 0;
812 break;
813 }
814
815 error = pu->pu_pvn.puffs_putpages(pu,
816 preq->preq_cookie, );
817 break;
818 }
819
820 case PUFFS_VN_CLOSEEXTATTR:
821 {
822 struct puffs_vnreq_closeextattr *auxt = preq->preq_aux;
823 if (pu->pu_pvn.puffs_closeextattr == NULL) {
824 error = 0;
825 break;
826 }
827
828 error = pu->pu_pvn.puffs_closeextattr(pu,
829 preq->preq_cookie, );
830 break;
831 }
832
833 case PUFFS_VN_GETEXTATTR:
834 {
835 struct puffs_vnreq_getextattr *auxt = preq->preq_aux;
836 if (pu->pu_pvn.puffs_getextattr == NULL) {
837 error = 0;
838 break;
839 }
840
841 error = pu->pu_pvn.puffs_getextattr(pu,
842 preq->preq_cookie, );
843 break;
844 }
845
846 case PUFFS_VN_LISTEXTATTR:
847 {
848 struct puffs_vnreq_listextattr *auxt = preq->preq_aux;
849 if (pu->pu_pvn.puffs_listextattr == NULL) {
850 error = 0;
851 break;
852 }
853
854 error = pu->pu_pvn.puffs_listextattr(pu,
855 preq->preq_cookie, );
856 break;
857 }
858
859 case PUFFS_VN_OPENEXTATTR:
860 {
861 struct puffs_vnreq_openextattr *auxt = preq->preq_aux;
862 if (pu->pu_pvn.puffs_openextattr == NULL) {
863 error = 0;
864 break;
865 }
866
867 error = pu->pu_pvn.puffs_openextattr(pu,
868 preq->preq_cookie, );
869 break;
870 }
871
872 case PUFFS_VN_DELETEEXTATTR:
873 {
874 struct puffs_vnreq_deleteextattr *auxt = preq->preq_aux;
875 if (pu->pu_pvn.puffs_deleteextattr == NULL) {
876 error = 0;
877 break;
878 }
879
880 error = pu->pu_pvn.puffs_deleteextattr(pu,
881 preq->preq_cookie, );
882 break;
883 }
884
885 case PUFFS_VN_SETEXTATTR:
886 {
887 struct puffs_vnreq_setextattr *auxt = preq->preq_aux;
888 if (pu->pu_pvn.puffs_setextattr == NULL) {
889 error = 0;
890 break;
891 }
892
893 error = pu->pu_pvn.puffs_setextattr(pu,
894 preq->preq_cookie, );
895 break;
896 }
897
898 #endif
899