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