puffs.c revision 1.1 1 /* $NetBSD: puffs.c,v 1.1 2006/10/22 22:52:21 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.1 2006/10/22 22:52:21 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_PATHCONF:
542 {
543 struct puffs_vnreq_pathconf *auxt = preq->preq_aux;
544 if (pu->pu_pvn.puffs_pathconf == NULL) {
545 error = 0;
546 break;
547 }
548
549 error = pu->pu_pvn.puffs_pathconf(pu,
550 preq->preq_cookie, auxt->pvnr_name,
551 &auxt->pvnr_retval);
552 break;
553 }
554
555 case PUFFS_VN_ADVLOCK:
556 {
557 struct puffs_vnreq_advlock *auxt = preq->preq_aux;
558 if (pu->pu_pvn.puffs_advlock == NULL) {
559 error = 0;
560 break;
561 }
562
563 error = pu->pu_pvn.puffs_advlock(pu,
564 preq->preq_cookie, auxt->pvnr_id, auxt->pvnr_op,
565 &auxt->pvnr_fl, auxt->pvnr_flags);
566 break;
567 }
568
569 case PUFFS_VN_PRINT:
570 {
571 struct puffs_vnreq_print *auxt = preq->preq_aux;
572 (void)auxt;
573 if (pu->pu_pvn.puffs_print == NULL) {
574 error = 0;
575 break;
576 }
577
578 error = pu->pu_pvn.puffs_print(pu,
579 preq->preq_cookie);
580 break;
581 }
582
583 case PUFFS_VN_READ:
584 {
585 struct puffs_vnreq_read *auxt = preq->preq_aux;
586 size_t res;
587
588 if (pu->pu_pvn.puffs_read == NULL) {
589 error = EIO;
590 break;
591 }
592
593 res = auxt->pvnr_resid;
594 error = pu->pu_pvn.puffs_read(pu,
595 preq->preq_cookie, auxt->pvnr_data,
596 auxt->pvnr_offset, &auxt->pvnr_resid,
597 &auxt->pvnr_cred, auxt->pvnr_ioflag);
598
599 /* need to move a bit more */
600 preq->preq_auxlen += res - auxt->pvnr_resid;
601 break;
602 }
603
604 case PUFFS_VN_WRITE:
605 {
606 struct puffs_vnreq_write *auxt = preq->preq_aux;
607
608 if (pu->pu_pvn.puffs_write == NULL) {
609 error = EIO;
610 break;
611 }
612
613 error = pu->pu_pvn.puffs_write(pu,
614 preq->preq_cookie, auxt->pvnr_data,
615 auxt->pvnr_offset, &auxt->pvnr_resid,
616 &auxt->pvnr_cred, auxt->pvnr_ioflag);
617
618 /* don't need to move data back to the kernel */
619 preq->preq_auxlen = sizeof(struct puffs_vnreq_write);
620 break;
621 }
622
623 case PUFFS_VN_IOCTL:
624 error = pu->pu_pvn.puffs_ioctl1(pu, preq->preq_cookie,
625 (struct puffs_vnreq_ioctl *)preq->preq_aux, &pop);
626 if (error != 0)
627 break;
628 pop.pso_reqid = preq->preq_id;
629
630 /* let the kernel do it's intermediate duty */
631 error = ioctl(pu->pu_fd, PUFFSSIZEOP, &pop);
632 /*
633 * XXX: I don't actually know what the correct
634 * thing to do in case of an error is, so I'll
635 * just ignore it for the time being.
636 */
637 error = pu->pu_pvn.puffs_ioctl2(pu, preq->preq_cookie,
638 (struct puffs_vnreq_ioctl *)preq->preq_aux, &pop);
639 break;
640
641 case PUFFS_VN_FCNTL:
642 error = pu->pu_pvn.puffs_fcntl1(pu, preq->preq_cookie,
643 (struct puffs_vnreq_fcntl *)preq->preq_aux, &pop);
644 if (error != 0)
645 break;
646 pop.pso_reqid = preq->preq_id;
647
648 /* let the kernel do it's intermediate duty */
649 error = ioctl(pu->pu_fd, PUFFSSIZEOP, &pop);
650 /*
651 * XXX: I don't actually know what the correct
652 * thing to do in case of an error is, so I'll
653 * just ignore it for the time being.
654 */
655 error = pu->pu_pvn.puffs_fcntl2(pu, preq->preq_cookie,
656 (struct puffs_vnreq_fcntl *)preq->preq_aux, &pop);
657 break;
658
659 default:
660 printf("inval op %d\n", preq->preq_optype);
661 error = EINVAL;
662 break;
663 }
664 } else {
665 /*
666 * this one also
667 */
668 error = EINVAL;
669 }
670
671 preq->preq_rv = error;
672 return rv;
673 }
674
675
676 #if 0
677 case PUFFS_VN_IOCTL:
678 {
679 struct puffs_vnreq_ioctl *auxt = preq->preq_aux;
680 if (pu->pu_pvn.puffs_ioctl == NULL) {
681 error = 0;
682 break;
683 }
684
685 error = pu->pu_pvn.puffs_ioctl(pu,
686 preq->preq_cookie, );
687 break;
688 }
689
690 case PUFFS_VN_FCNTL:
691 {
692 struct puffs_vnreq_fcntl *auxt = preq->preq_aux;
693 if (pu->pu_pvn.puffs_fcntl == NULL) {
694 error = 0;
695 break;
696 }
697
698 error = pu->pu_pvn.puffs_fcntl(pu,
699 preq->preq_cookie, );
700 break;
701 }
702
703
704 case PUFFS_VN_ABORTOP:
705 {
706 struct puffs_vnreq_abortop *auxt = preq->preq_aux;
707 if (pu->pu_pvn.puffs_abortop == NULL) {
708 error = 0;
709 break;
710 }
711
712 error = pu->pu_pvn.puffs_abortop(pu,
713 preq->preq_cookie, );
714 break;
715 }
716
717 case PUFFS_VN_INACTIVE:
718 {
719 struct puffs_vnreq_inactive *auxt = preq->preq_aux;
720 if (pu->pu_pvn.puffs_inactive == NULL) {
721 error = 0;
722 break;
723 }
724
725 error = pu->pu_pvn.puffs_inactive(pu,
726 preq->preq_cookie, );
727 break;
728 }
729
730 case PUFFS_VN_LOCK:
731 {
732 struct puffs_vnreq_lock *auxt = preq->preq_aux;
733 if (pu->pu_pvn.puffs_lock == NULL) {
734 error = 0;
735 break;
736 }
737
738 error = pu->pu_pvn.puffs_lock(pu,
739 preq->preq_cookie, );
740 break;
741 }
742
743 case PUFFS_VN_UNLOCK:
744 {
745 struct puffs_vnreq_unlock *auxt = preq->preq_aux;
746 if (pu->pu_pvn.puffs_unlock == NULL) {
747 error = 0;
748 break;
749 }
750
751 error = pu->pu_pvn.puffs_unlock(pu,
752 preq->preq_cookie, );
753 break;
754 }
755
756 case PUFFS_VN_ISLOCKED:
757 {
758 struct puffs_vnreq_islocked *auxt = preq->preq_aux;
759 if (pu->pu_pvn.puffs_islocked == NULL) {
760 error = 0;
761 break;
762 }
763
764 error = pu->pu_pvn.puffs_islocked(pu,
765 preq->preq_cookie, );
766 break;
767 }
768
769 case PUFFS_VN_LEASE:
770 {
771 struct puffs_vnreq_lease *auxt = preq->preq_aux;
772 if (pu->pu_pvn.puffs_lease == NULL) {
773 error = 0;
774 break;
775 }
776
777 error = pu->pu_pvn.puffs_lease(pu,
778 preq->preq_cookie, );
779 break;
780 }
781
782 case PUFFS_VN_WHITEOUT:
783 {
784 struct puffs_vnreq_whiteout *auxt = preq->preq_aux;
785 if (pu->pu_pvn.puffs_whiteout == NULL) {
786 error = 0;
787 break;
788 }
789
790 error = pu->pu_pvn.puffs_whiteout(pu,
791 preq->preq_cookie, );
792 break;
793 }
794
795 case PUFFS_VN_GETPAGES:
796 {
797 struct puffs_vnreq_getpages *auxt = preq->preq_aux;
798 if (pu->pu_pvn.puffs_getpages == NULL) {
799 error = 0;
800 break;
801 }
802
803 error = pu->pu_pvn.puffs_getpages(pu,
804 preq->preq_cookie, );
805 break;
806 }
807
808 case PUFFS_VN_PUTPAGES:
809 {
810 struct puffs_vnreq_putpages *auxt = preq->preq_aux;
811 if (pu->pu_pvn.puffs_putpages == NULL) {
812 error = 0;
813 break;
814 }
815
816 error = pu->pu_pvn.puffs_putpages(pu,
817 preq->preq_cookie, );
818 break;
819 }
820
821 case PUFFS_VN_CLOSEEXTATTR:
822 {
823 struct puffs_vnreq_closeextattr *auxt = preq->preq_aux;
824 if (pu->pu_pvn.puffs_closeextattr == NULL) {
825 error = 0;
826 break;
827 }
828
829 error = pu->pu_pvn.puffs_closeextattr(pu,
830 preq->preq_cookie, );
831 break;
832 }
833
834 case PUFFS_VN_GETEXTATTR:
835 {
836 struct puffs_vnreq_getextattr *auxt = preq->preq_aux;
837 if (pu->pu_pvn.puffs_getextattr == NULL) {
838 error = 0;
839 break;
840 }
841
842 error = pu->pu_pvn.puffs_getextattr(pu,
843 preq->preq_cookie, );
844 break;
845 }
846
847 case PUFFS_VN_LISTEXTATTR:
848 {
849 struct puffs_vnreq_listextattr *auxt = preq->preq_aux;
850 if (pu->pu_pvn.puffs_listextattr == NULL) {
851 error = 0;
852 break;
853 }
854
855 error = pu->pu_pvn.puffs_listextattr(pu,
856 preq->preq_cookie, );
857 break;
858 }
859
860 case PUFFS_VN_OPENEXTATTR:
861 {
862 struct puffs_vnreq_openextattr *auxt = preq->preq_aux;
863 if (pu->pu_pvn.puffs_openextattr == NULL) {
864 error = 0;
865 break;
866 }
867
868 error = pu->pu_pvn.puffs_openextattr(pu,
869 preq->preq_cookie, );
870 break;
871 }
872
873 case PUFFS_VN_DELETEEXTATTR:
874 {
875 struct puffs_vnreq_deleteextattr *auxt = preq->preq_aux;
876 if (pu->pu_pvn.puffs_deleteextattr == NULL) {
877 error = 0;
878 break;
879 }
880
881 error = pu->pu_pvn.puffs_deleteextattr(pu,
882 preq->preq_cookie, );
883 break;
884 }
885
886 case PUFFS_VN_SETEXTATTR:
887 {
888 struct puffs_vnreq_setextattr *auxt = preq->preq_aux;
889 if (pu->pu_pvn.puffs_setextattr == NULL) {
890 error = 0;
891 break;
892 }
893
894 error = pu->pu_pvn.puffs_setextattr(pu,
895 preq->preq_cookie, );
896 break;
897 }
898
899 #endif
900