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