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