1 /* $NetBSD: dispatcher.c,v 1.36 2011/07/04 08:07:30 manu Exp $ */
4 * Copyright (c) 2006, 2007, 2008 Antti Kantee. All Rights Reserved.
6 * Development of this software was supported by the
7 * Ulla Tuominen Foundation, the Finnish Cultural Foundation and
8 * Research Foundation of Helsinki University of Technology.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
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.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
20 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/types.h>
43 #include "puffsdump.h"
44 #include "puffs_priv.h"
46 static void dispatch(struct puffs_cc
*);
48 /* for our eyes only */
50 puffs__ml_dispatch(struct puffs_usermount
*pu
, struct puffs_framebuf
*pb
)
52 struct puffs_cc
*pcc
= puffs_cc_getcc(pu
);
53 struct puffs_req
*preq
;
56 pcc
->pcc_flags
|= PCC_MLCONT
;
59 /* Put result to kernel sendqueue if necessary */
60 preq
= puffs__framebuf_getdataptr(pcc
->pcc_pb
);
61 if (PUFFSOP_WANTREPLY(preq
->preq_opclass
)) {
62 if (pu
->pu_flags
& PUFFS_FLAG_OPDUMP
)
65 puffs_framev_enqueue_justsend(pu
, pu
->pu_fd
,
68 puffs_framebuf_destroy(pcc
->pcc_pb
);
71 /* who needs information when you're living on borrowed time? */
72 if (pcc
->pcc_flags
& PCC_BORROWED
) {
73 puffs_cc_yield(pcc
); /* back to borrow source */
78 /* public, but not really tested and only semi-supported */
80 puffs_dispatch_create(struct puffs_usermount
*pu
, struct puffs_framebuf
*pb
,
81 struct puffs_cc
**pccp
)
85 if (puffs__cc_create(pu
, dispatch
, &pcc
) == -1)
95 puffs_dispatch_exec(struct puffs_cc
*pcc
, struct puffs_framebuf
**pbp
)
99 puffs_cc_continue(pcc
);
101 if (pcc
->pcc_flags
& PCC_DONE
) {
105 puffs__cc_destroy(pcc
, 0);
114 dispatch(struct puffs_cc
*pcc
)
116 struct puffs_usermount
*pu
= pcc
->pcc_pu
;
117 struct puffs_ops
*pops
= &pu
->pu_ops
;
118 struct puffs_req
*preq
= puffs__framebuf_getdataptr(pcc
->pcc_pb
);
119 void *auxbuf
; /* help with typecasting */
120 puffs_cookie_t opcookie
;
121 int error
= 0, buildpath
;
123 /* XXX: smaller hammer, please */
124 if ((PUFFSOP_OPCLASS(preq
->preq_opclass
== PUFFSOP_VFS
&&
125 preq
->preq_optype
== PUFFS_VFS_VPTOFH
)) ||
126 (PUFFSOP_OPCLASS(preq
->preq_opclass
) == PUFFSOP_VN
&&
127 (preq
->preq_optype
== PUFFS_VN_READDIR
128 || preq
->preq_optype
== PUFFS_VN_READ
))) {
129 if (puffs_framebuf_reserve_space(pcc
->pcc_pb
,
130 PUFFS_MSG_MAXSIZE
) == -1)
132 preq
= puffs__framebuf_getdataptr(pcc
->pcc_pb
);
136 opcookie
= preq
->preq_cookie
;
138 assert((pcc
->pcc_flags
& PCC_DONE
) == 0);
140 buildpath
= pu
->pu_flags
& PUFFS_FLAG_BUILDPATH
;
141 preq
->preq_setbacks
= 0;
143 if (pu
->pu_flags
& PUFFS_FLAG_OPDUMP
)
146 puffs__cc_setcaller(pcc
, preq
->preq_pid
, preq
->preq_lid
);
155 /* Execute actual operation */
156 if (PUFFSOP_OPCLASS(preq
->preq_opclass
) == PUFFSOP_VFS
) {
157 switch (preq
->preq_optype
) {
158 case PUFFS_VFS_UNMOUNT
:
160 struct puffs_vfsmsg_unmount
*auxt
= auxbuf
;
162 PU_SETSTATE(pu
, PUFFS_STATE_UNMOUNTING
);
163 error
= pops
->puffs_fs_unmount(pu
, auxt
->pvfsr_flags
);
165 PU_SETSTATE(pu
, PUFFS_STATE_UNMOUNTED
);
167 PU_SETSTATE(pu
, PUFFS_STATE_RUNNING
);
171 case PUFFS_VFS_STATVFS
:
173 struct puffs_vfsmsg_statvfs
*auxt
= auxbuf
;
175 error
= pops
->puffs_fs_statvfs(pu
, &auxt
->pvfsr_sb
);
181 struct puffs_vfsmsg_sync
*auxt
= auxbuf
;
183 error
= pops
->puffs_fs_sync(pu
,
184 auxt
->pvfsr_waitfor
);
188 case PUFFS_VFS_FHTOVP
:
190 struct puffs_vfsmsg_fhtonode
*auxt
= auxbuf
;
191 struct puffs_newinfo pni
;
193 pni
.pni_cookie
= &auxt
->pvfsr_fhcookie
;
194 pni
.pni_vtype
= &auxt
->pvfsr_vtype
;
195 pni
.pni_size
= &auxt
->pvfsr_size
;
197 error
= pops
->puffs_fs_fhtonode(pu
, auxt
->pvfsr_data
,
198 auxt
->pvfsr_dsize
, &pni
);
203 case PUFFS_VFS_VPTOFH
:
205 struct puffs_vfsmsg_nodetofh
*auxt
= auxbuf
;
207 error
= pops
->puffs_fs_nodetofh(pu
,
208 auxt
->pvfsr_fhcookie
, auxt
->pvfsr_data
,
214 case PUFFS_VFS_EXTATTRCTL
:
216 struct puffs_vfsmsg_extattrctl
*auxt
= auxbuf
;
217 const char *attrname
;
220 if (pops
->puffs_fs_extattrctl
== NULL
) {
225 if (auxt
->pvfsr_flags
& PUFFS_EXTATTRCTL_HASATTRNAME
)
226 attrname
= auxt
->pvfsr_attrname
;
230 flags
= auxt
->pvfsr_flags
& PUFFS_EXTATTRCTL_HASNODE
;
231 error
= pops
->puffs_fs_extattrctl(pu
, auxt
->pvfsr_cmd
,
233 auxt
->pvfsr_attrnamespace
, attrname
);
239 * I guess the kernel sees this one coming
245 /* XXX: audit return values */
246 /* XXX: sync with kernel */
247 } else if (PUFFSOP_OPCLASS(preq
->preq_opclass
) == PUFFSOP_VN
) {
248 switch (preq
->preq_optype
) {
249 case PUFFS_VN_LOOKUP
:
251 struct puffs_vnmsg_lookup
*auxt
= auxbuf
;
252 struct puffs_newinfo pni
;
255 pcn
.pcn_pkcnp
= &auxt
->pvnr_cn
;
256 PUFFS_KCREDTOCRED(pcn
.pcn_cred
, &auxt
->pvnr_cn_cred
);
257 pni
.pni_cookie
= &auxt
->pvnr_newnode
;
258 pni
.pni_vtype
= &auxt
->pvnr_vtype
;
259 pni
.pni_size
= &auxt
->pvnr_size
;
262 error
= puffs_path_pcnbuild(pu
, &pcn
, opcookie
);
267 /* lookup *must* be present */
268 error
= pops
->puffs_node_lookup(pu
, opcookie
,
273 pu
->pu_pathfree(pu
, &pcn
.pcn_po_full
);
275 struct puffs_node
*pn
;
278 * did we get a new node or a
281 pn
= PU_CMAP(pu
, auxt
->pvnr_newnode
);
282 if (pn
->pn_po
.po_path
== NULL
)
283 pn
->pn_po
= pcn
.pcn_po_full
;
293 case PUFFS_VN_LOOKUPDOTDOT
:
295 struct puffs_kcn kcn
= {
299 struct puffs_vnmsg_lookupdotdot
*auxt
= auxbuf
;
300 struct puffs_newinfo pni
;
303 pcn
.pcn_pkcnp
= &kcn
;
304 PUFFS_KCREDTOCRED(pcn
.pcn_cred
, &auxt
->pvnr_cred
);
305 pni
.pni_cookie
= &auxt
->pvnr_newnode
;
306 pni
.pni_vtype
= NULL
;
310 error
= puffs_path_pcnbuild(pu
, &pcn
, opcookie
);
315 /* lookup *must* be present */
316 error
= pops
->puffs_node_lookupdotdot(pu
, opcookie
,
321 pu
->pu_pathfree(pu
, &pcn
.pcn_po_full
);
323 struct puffs_node
*pn
;
326 * did we get a new node or a
329 pn
= PU_CMAP(pu
, auxt
->pvnr_newnode
);
330 if (pn
->pn_po
.po_path
== NULL
)
331 pn
->pn_po
= pcn
.pcn_po_full
;
340 case PUFFS_VN_CREATE
:
342 struct puffs_vnmsg_create
*auxt
= auxbuf
;
343 struct puffs_newinfo pni
;
346 if (pops
->puffs_node_create
== NULL
) {
351 pcn
.pcn_pkcnp
= &auxt
->pvnr_cn
;
352 PUFFS_KCREDTOCRED(pcn
.pcn_cred
, &auxt
->pvnr_cn_cred
);
354 memset(&pni
, 0, sizeof(pni
));
355 pni
.pni_cookie
= &auxt
->pvnr_newnode
;
358 error
= puffs_path_pcnbuild(pu
, &pcn
, opcookie
);
363 error
= pops
->puffs_node_create(pu
,
364 opcookie
, &pni
, &pcn
, &auxt
->pvnr_va
);
368 pu
->pu_pathfree(pu
, &pcn
.pcn_po_full
);
370 struct puffs_node
*pn
;
372 pn
= PU_CMAP(pu
, auxt
->pvnr_newnode
);
373 pn
->pn_po
= pcn
.pcn_po_full
;
382 struct puffs_vnmsg_mknod
*auxt
= auxbuf
;
383 struct puffs_newinfo pni
;
386 if (pops
->puffs_node_mknod
== NULL
) {
391 pcn
.pcn_pkcnp
= &auxt
->pvnr_cn
;
392 PUFFS_KCREDTOCRED(pcn
.pcn_cred
, &auxt
->pvnr_cn_cred
);
394 memset(&pni
, 0, sizeof(pni
));
395 pni
.pni_cookie
= &auxt
->pvnr_newnode
;
398 error
= puffs_path_pcnbuild(pu
, &pcn
, opcookie
);
403 error
= pops
->puffs_node_mknod(pu
,
404 opcookie
, &pni
, &pcn
, &auxt
->pvnr_va
);
408 pu
->pu_pathfree(pu
, &pcn
.pcn_po_full
);
410 struct puffs_node
*pn
;
412 pn
= PU_CMAP(pu
, auxt
->pvnr_newnode
);
413 pn
->pn_po
= pcn
.pcn_po_full
;
422 struct puffs_vnmsg_open
*auxt
= auxbuf
;
423 PUFFS_MAKECRED(pcr
, &auxt
->pvnr_cred
);
425 if (pops
->puffs_node_open
== NULL
) {
430 error
= pops
->puffs_node_open(pu
,
431 opcookie
, auxt
->pvnr_mode
, pcr
);
437 struct puffs_vnmsg_close
*auxt
= auxbuf
;
439 if (pops
->puffs_node_close
== NULL
) {
444 error
= pops
->puffs_node_close(pu
,
445 opcookie
, auxt
->pvnr_fflag
);
449 case PUFFS_VN_ACCESS
:
451 struct puffs_vnmsg_access
*auxt
= auxbuf
;
452 PUFFS_MAKECRED(pcr
, &auxt
->pvnr_cred
);
454 if (pops
->puffs_node_access
== NULL
) {
459 error
= pops
->puffs_node_access(pu
,
460 opcookie
, auxt
->pvnr_mode
, pcr
);
464 case PUFFS_VN_GETATTR
:
466 struct puffs_vnmsg_getattr
*auxt
= auxbuf
;
467 PUFFS_MAKECRED(pcr
, &auxt
->pvnr_cred
);
469 if (pops
->puffs_node_getattr
== NULL
) {
474 error
= pops
->puffs_node_getattr(pu
,
475 opcookie
, &auxt
->pvnr_va
, pcr
);
479 case PUFFS_VN_SETATTR
:
481 struct puffs_vnmsg_setattr
*auxt
= auxbuf
;
482 PUFFS_MAKECRED(pcr
, &auxt
->pvnr_cred
);
484 if (pops
->puffs_node_setattr
== NULL
) {
489 error
= pops
->puffs_node_setattr(pu
,
490 opcookie
, &auxt
->pvnr_va
, pcr
);
496 struct puffs_vnmsg_mmap
*auxt
= auxbuf
;
497 PUFFS_MAKECRED(pcr
, &auxt
->pvnr_cred
);
499 if (pops
->puffs_node_mmap
== NULL
) {
504 error
= pops
->puffs_node_mmap(pu
,
505 opcookie
, auxt
->pvnr_prot
, pcr
);
511 struct puffs_vnmsg_fsync
*auxt
= auxbuf
;
513 if (pops
->puffs_node_fsync
== NULL
) {
518 error
= pops
->puffs_node_fsync(pu
, opcookie
,
525 struct puffs_vnmsg_seek
*auxt
= auxbuf
;
526 PUFFS_MAKECRED(pcr
, &auxt
->pvnr_cred
);
528 if (pops
->puffs_node_seek
== NULL
) {
533 error
= pops
->puffs_node_seek(pu
,
534 opcookie
, auxt
->pvnr_oldoff
,
535 auxt
->pvnr_newoff
, pcr
);
539 case PUFFS_VN_REMOVE
:
541 struct puffs_vnmsg_remove
*auxt
= auxbuf
;
543 if (pops
->puffs_node_remove
== NULL
) {
548 pcn
.pcn_pkcnp
= &auxt
->pvnr_cn
;
549 PUFFS_KCREDTOCRED(pcn
.pcn_cred
, &auxt
->pvnr_cn_cred
);
551 error
= pops
->puffs_node_remove(pu
,
552 opcookie
, auxt
->pvnr_cookie_targ
, &pcn
);
558 struct puffs_vnmsg_link
*auxt
= auxbuf
;
560 if (pops
->puffs_node_link
== NULL
) {
565 pcn
.pcn_pkcnp
= &auxt
->pvnr_cn
;
566 PUFFS_KCREDTOCRED(pcn
.pcn_cred
, &auxt
->pvnr_cn_cred
);
569 error
= puffs_path_pcnbuild(pu
, &pcn
, opcookie
);
574 error
= pops
->puffs_node_link(pu
,
575 opcookie
, auxt
->pvnr_cookie_targ
, &pcn
);
577 pu
->pu_pathfree(pu
, &pcn
.pcn_po_full
);
582 case PUFFS_VN_RENAME
:
584 struct puffs_vnmsg_rename
*auxt
= auxbuf
;
585 struct puffs_cn pcn_src
, pcn_targ
;
586 struct puffs_node
*pn_src
;
588 if (pops
->puffs_node_rename
== NULL
) {
593 pcn_src
.pcn_pkcnp
= &auxt
->pvnr_cn_src
;
594 PUFFS_KCREDTOCRED(pcn_src
.pcn_cred
,
595 &auxt
->pvnr_cn_src_cred
);
597 pcn_targ
.pcn_pkcnp
= &auxt
->pvnr_cn_targ
;
598 PUFFS_KCREDTOCRED(pcn_targ
.pcn_cred
,
599 &auxt
->pvnr_cn_targ_cred
);
602 pn_src
= auxt
->pvnr_cookie_src
;
603 pcn_src
.pcn_po_full
= pn_src
->pn_po
;
605 error
= puffs_path_pcnbuild(pu
, &pcn_targ
,
606 auxt
->pvnr_cookie_targdir
);
611 error
= pops
->puffs_node_rename(pu
,
612 opcookie
, auxt
->pvnr_cookie_src
,
613 &pcn_src
, auxt
->pvnr_cookie_targdir
,
614 auxt
->pvnr_cookie_targ
, &pcn_targ
);
619 &pcn_targ
.pcn_po_full
);
621 struct puffs_pathinfo pi
;
622 struct puffs_pathobj po_old
;
624 /* handle this node */
625 po_old
= pn_src
->pn_po
;
626 pn_src
->pn_po
= pcn_targ
.pcn_po_full
;
628 if (pn_src
->pn_va
.va_type
!= VDIR
) {
629 pu
->pu_pathfree(pu
, &po_old
);
633 /* handle all child nodes for DIRs */
634 pi
.pi_old
= &pcn_src
.pcn_po_full
;
635 pi
.pi_new
= &pcn_targ
.pcn_po_full
;
638 if (puffs_pn_nodewalk(pu
,
639 puffs_path_prefixadj
, &pi
) != NULL
)
642 pu
->pu_pathfree(pu
, &po_old
);
650 struct puffs_vnmsg_mkdir
*auxt
= auxbuf
;
651 struct puffs_newinfo pni
;
654 if (pops
->puffs_node_mkdir
== NULL
) {
659 pcn
.pcn_pkcnp
= &auxt
->pvnr_cn
;
660 PUFFS_KCREDTOCRED(pcn
.pcn_cred
, &auxt
->pvnr_cn_cred
);
662 memset(&pni
, 0, sizeof(pni
));
663 pni
.pni_cookie
= &auxt
->pvnr_newnode
;
666 error
= puffs_path_pcnbuild(pu
, &pcn
, opcookie
);
671 error
= pops
->puffs_node_mkdir(pu
,
672 opcookie
, &pni
, &pcn
, &auxt
->pvnr_va
);
676 pu
->pu_pathfree(pu
, &pcn
.pcn_po_full
);
678 struct puffs_node
*pn
;
680 pn
= PU_CMAP(pu
, auxt
->pvnr_newnode
);
681 pn
->pn_po
= pcn
.pcn_po_full
;
690 struct puffs_vnmsg_rmdir
*auxt
= auxbuf
;
692 if (pops
->puffs_node_rmdir
== NULL
) {
697 pcn
.pcn_pkcnp
= &auxt
->pvnr_cn
;
698 PUFFS_KCREDTOCRED(pcn
.pcn_cred
, &auxt
->pvnr_cn_cred
);
700 error
= pops
->puffs_node_rmdir(pu
,
701 opcookie
, auxt
->pvnr_cookie_targ
, &pcn
);
705 case PUFFS_VN_SYMLINK
:
707 struct puffs_vnmsg_symlink
*auxt
= auxbuf
;
708 struct puffs_newinfo pni
;
711 if (pops
->puffs_node_symlink
== NULL
) {
716 pcn
.pcn_pkcnp
= &auxt
->pvnr_cn
;
717 PUFFS_KCREDTOCRED(pcn
.pcn_cred
, &auxt
->pvnr_cn_cred
);
719 memset(&pni
, 0, sizeof(pni
));
720 pni
.pni_cookie
= &auxt
->pvnr_newnode
;
723 error
= puffs_path_pcnbuild(pu
, &pcn
, opcookie
);
728 error
= pops
->puffs_node_symlink(pu
,
729 opcookie
, &pni
, &pcn
,
730 &auxt
->pvnr_va
, auxt
->pvnr_link
);
734 pu
->pu_pathfree(pu
, &pcn
.pcn_po_full
);
736 struct puffs_node
*pn
;
738 pn
= PU_CMAP(pu
, auxt
->pvnr_newnode
);
739 pn
->pn_po
= pcn
.pcn_po_full
;
746 case PUFFS_VN_READDIR
:
748 struct puffs_vnmsg_readdir
*auxt
= auxbuf
;
749 PUFFS_MAKECRED(pcr
, &auxt
->pvnr_cred
);
752 size_t res
, origcookies
;
754 if (pops
->puffs_node_readdir
== NULL
) {
759 if (auxt
->pvnr_ncookies
) {
760 /* LINTED: pvnr_data is __aligned() */
761 cookies
= (off_t
*)auxt
->pvnr_data
;
762 origcookies
= auxt
->pvnr_ncookies
;
767 /* LINTED: dentoff is aligned in the kernel */
768 dent
= (struct dirent
*)
769 (auxt
->pvnr_data
+ auxt
->pvnr_dentoff
);
771 res
= auxt
->pvnr_resid
;
772 error
= pops
->puffs_node_readdir(pu
,
773 opcookie
, dent
, &auxt
->pvnr_offset
,
774 &auxt
->pvnr_resid
, pcr
, &auxt
->pvnr_eofflag
,
775 cookies
, &auxt
->pvnr_ncookies
);
777 /* much easier to track non-working NFS */
778 assert(auxt
->pvnr_ncookies
<= origcookies
);
780 /* need to move a bit more */
781 preq
->preq_buflen
= sizeof(struct puffs_vnmsg_readdir
)
782 + auxt
->pvnr_dentoff
+ (res
- auxt
->pvnr_resid
);
786 case PUFFS_VN_READLINK
:
788 struct puffs_vnmsg_readlink
*auxt
= auxbuf
;
789 PUFFS_MAKECRED(pcr
, &auxt
->pvnr_cred
);
791 if (pops
->puffs_node_readlink
== NULL
) {
797 error
= pops
->puffs_node_readlink(pu
, opcookie
, pcr
,
798 auxt
->pvnr_link
, &auxt
->pvnr_linklen
);
802 case PUFFS_VN_RECLAIM
:
805 if (pops
->puffs_node_reclaim
== NULL
) {
810 error
= pops
->puffs_node_reclaim(pu
, opcookie
);
814 case PUFFS_VN_INACTIVE
:
817 if (pops
->puffs_node_inactive
== NULL
) {
822 error
= pops
->puffs_node_inactive(pu
, opcookie
);
826 case PUFFS_VN_PATHCONF
:
828 struct puffs_vnmsg_pathconf
*auxt
= auxbuf
;
829 if (pops
->puffs_node_pathconf
== NULL
) {
834 error
= pops
->puffs_node_pathconf(pu
,
835 opcookie
, auxt
->pvnr_name
,
840 case PUFFS_VN_ADVLOCK
:
842 struct puffs_vnmsg_advlock
*auxt
= auxbuf
;
843 if (pops
->puffs_node_advlock
== NULL
) {
848 error
= pops
->puffs_node_advlock(pu
,
849 opcookie
, auxt
->pvnr_id
, auxt
->pvnr_op
,
850 &auxt
->pvnr_fl
, auxt
->pvnr_flags
);
856 if (pops
->puffs_node_print
== NULL
) {
861 error
= pops
->puffs_node_print(pu
,
866 case PUFFS_VN_ABORTOP
:
868 struct puffs_vnmsg_abortop
*auxt
= auxbuf
;
871 if (pops
->puffs_node_abortop
== NULL
) {
876 pcn
.pcn_pkcnp
= &auxt
->pvnr_cn
;
877 PUFFS_KCREDTOCRED(pcn
.pcn_cred
, &auxt
->pvnr_cn_cred
);
879 error
= pops
->puffs_node_abortop(pu
, opcookie
, &pcn
);
886 struct puffs_vnmsg_read
*auxt
= auxbuf
;
887 PUFFS_MAKECRED(pcr
, &auxt
->pvnr_cred
);
890 if (pops
->puffs_node_read
== NULL
) {
895 res
= auxt
->pvnr_resid
;
896 error
= pops
->puffs_node_read(pu
,
897 opcookie
, auxt
->pvnr_data
,
898 auxt
->pvnr_offset
, &auxt
->pvnr_resid
,
899 pcr
, auxt
->pvnr_ioflag
);
901 /* need to move a bit more */
902 preq
->preq_buflen
= sizeof(struct puffs_vnmsg_read
)
903 + (res
- auxt
->pvnr_resid
);
909 struct puffs_vnmsg_write
*auxt
= auxbuf
;
910 PUFFS_MAKECRED(pcr
, &auxt
->pvnr_cred
);
912 if (pops
->puffs_node_write
== NULL
) {
917 error
= pops
->puffs_node_write(pu
,
918 opcookie
, auxt
->pvnr_data
,
919 auxt
->pvnr_offset
, &auxt
->pvnr_resid
,
920 pcr
, auxt
->pvnr_ioflag
);
922 /* don't need to move data back to the kernel */
923 preq
->preq_buflen
= sizeof(struct puffs_vnmsg_write
);
929 struct puffs_vnmsg_poll
*auxt
= auxbuf
;
931 if (pops
->puffs_node_poll
== NULL
) {
934 /* emulate genfs_poll() */
935 auxt
->pvnr_events
&= (POLLIN
| POLLOUT
936 | POLLRDNORM
| POLLWRNORM
);
941 error
= pops
->puffs_node_poll(pu
,
942 opcookie
, &auxt
->pvnr_events
);
946 case PUFFS_VN_GETEXTATTR
:
948 struct puffs_vnmsg_getextattr
*auxt
= auxbuf
;
949 PUFFS_MAKECRED(pcr
, &auxt
->pvnr_cred
);
950 size_t res
, *resp
, *sizep
;
953 if (pops
->puffs_node_getextattr
== NULL
) {
958 if (auxt
->pvnr_datasize
)
959 sizep
= &auxt
->pvnr_datasize
;
963 res
= auxt
->pvnr_resid
;
965 data
= auxt
->pvnr_data
;
966 resp
= &auxt
->pvnr_resid
;
972 error
= pops
->puffs_node_getextattr(pu
,
973 opcookie
, auxt
->pvnr_attrnamespace
,
974 auxt
->pvnr_attrname
, sizep
, data
, resp
, pcr
);
976 /* need to move a bit more? */
978 sizeof(struct puffs_vnmsg_getextattr
)
979 + (res
- auxt
->pvnr_resid
);
983 case PUFFS_VN_SETEXTATTR
:
985 struct puffs_vnmsg_setextattr
*auxt
= auxbuf
;
986 PUFFS_MAKECRED(pcr
, &auxt
->pvnr_cred
);
990 if (pops
->puffs_node_setextattr
== NULL
) {
995 if (auxt
->pvnr_resid
> 0) {
996 data
= auxt
->pvnr_data
;
997 resp
= &auxt
->pvnr_resid
;
1003 error
= pops
->puffs_node_setextattr(pu
,
1004 opcookie
, auxt
->pvnr_attrnamespace
,
1005 auxt
->pvnr_attrname
, data
, resp
, pcr
);
1009 case PUFFS_VN_LISTEXTATTR
:
1011 struct puffs_vnmsg_listextattr
*auxt
= auxbuf
;
1012 PUFFS_MAKECRED(pcr
, &auxt
->pvnr_cred
);
1013 size_t res
, *resp
, *sizep
;
1017 if (pops
->puffs_node_listextattr
== NULL
) {
1022 if (auxt
->pvnr_datasize
)
1023 sizep
= &auxt
->pvnr_datasize
;
1027 res
= auxt
->pvnr_resid
;
1029 data
= auxt
->pvnr_data
;
1030 resp
= &auxt
->pvnr_resid
;
1036 res
= auxt
->pvnr_resid
;
1037 flag
= auxt
->pvnr_flag
;
1038 error
= pops
->puffs_node_listextattr(pu
,
1039 opcookie
, auxt
->pvnr_attrnamespace
,
1040 sizep
, data
, resp
, flag
, pcr
);
1042 /* need to move a bit more? */
1044 sizeof(struct puffs_vnmsg_listextattr
)
1045 + (res
- auxt
->pvnr_resid
);
1049 case PUFFS_VN_DELETEEXTATTR
:
1051 struct puffs_vnmsg_deleteextattr
*auxt
= auxbuf
;
1052 PUFFS_MAKECRED(pcr
, &auxt
->pvnr_cred
);
1054 if (pops
->puffs_node_deleteextattr
== NULL
) {
1059 error
= pops
->puffs_node_deleteextattr(pu
,
1060 opcookie
, auxt
->pvnr_attrnamespace
,
1061 auxt
->pvnr_attrname
, pcr
);
1066 printf("inval op %d\n", preq
->preq_optype
);
1072 /* not issued by kernel currently */
1073 } else if (PUFFSOP_OPCLASS(preq
->preq_opclass
) == PUFFSOP_CACHE
) {
1074 struct puffs_cacheinfo
*pci
= (void *)preq
;
1076 if (pu
->pu_ops
.puffs_cache_write
) {
1077 pu
->pu_ops
.puffs_cache_write(pu
, preq
->preq_cookie
,
1078 pci
->pcache_nruns
, pci
->pcache_runs
);
1083 } else if (PUFFSOP_OPCLASS(preq
->preq_opclass
) == PUFFSOP_ERROR
) {
1084 struct puffs_error
*perr
= (void *)preq
;
1086 pu
->pu_errnotify(pu
, preq
->preq_optype
,
1087 perr
->perr_error
, perr
->perr_str
, preq
->preq_cookie
);
1091 * I guess the kernel sees this one coming also
1097 preq
->preq_rv
= error
;
1102 pcc
->pcc_flags
|= PCC_DONE
;