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