1 /* $NetBSD: dispatcher.c,v 1.32 2008/08/12 19:44:39 pooka 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/cdefs.h>
34 __RCSID("$NetBSD: dispatcher.c,v 1.32 2008/08/12 19:44:39 pooka Exp $");
37 #include <sys/types.h>
42 #ifdef PUFFS_WITH_THREADS
46 #include <puffsdump.h>
51 #include "puffs_priv.h"
53 #if 0 /* me not worka now */
55 * Set the following to 1 to handle each request in a separate pthread.
56 * This is not exported as it should not be used yet unless having a
57 * very good knowledge of what you're signing up for (libpuffs is not
63 static void dispatch(struct puffs_cc
*);
65 /* for our eyes only */
67 puffs__ml_dispatch(struct puffs_usermount
*pu
, struct puffs_framebuf
*pb
)
69 struct puffs_cc
*pcc
= puffs_cc_getcc(pu
);
70 struct puffs_req
*preq
;
73 pcc
->pcc_flags
|= PCC_MLCONT
;
76 /* Put result to kernel sendqueue if necessary */
77 preq
= puffs__framebuf_getdataptr(pcc
->pcc_pb
);
78 if (PUFFSOP_WANTREPLY(preq
->preq_opclass
)) {
79 if (pu
->pu_flags
& PUFFS_FLAG_OPDUMP
)
82 puffs_framev_enqueue_justsend(pu
, pu
->pu_fd
,
85 puffs_framebuf_destroy(pcc
->pcc_pb
);
88 /* who needs information when you're living on borrowed time? */
89 if (pcc
->pcc_flags
& PCC_BORROWED
) {
90 puffs_cc_yield(pcc
); /* back to borrow source */
95 /* public, but not really tested and only semi-supported */
97 puffs_dispatch_create(struct puffs_usermount
*pu
, struct puffs_framebuf
*pb
,
98 struct puffs_cc
**pccp
)
100 struct puffs_cc
*pcc
;
102 if (puffs__cc_create(pu
, dispatch
, &pcc
) == -1)
112 puffs_dispatch_exec(struct puffs_cc
*pcc
, struct puffs_framebuf
**pbp
)
116 puffs_cc_continue(pcc
);
118 if (pcc
->pcc_flags
& PCC_DONE
) {
122 puffs__cc_destroy(pcc
, 0);
131 dispatch(struct puffs_cc
*pcc
)
133 struct puffs_usermount
*pu
= pcc
->pcc_pu
;
134 struct puffs_ops
*pops
= &pu
->pu_ops
;
135 struct puffs_req
*preq
= puffs__framebuf_getdataptr(pcc
->pcc_pb
);
136 void *auxbuf
; /* help with typecasting */
137 puffs_cookie_t opcookie
;
138 int error
= 0, buildpath
;
140 /* XXX: smaller hammer, please */
141 if ((PUFFSOP_OPCLASS(preq
->preq_opclass
== PUFFSOP_VFS
&&
142 preq
->preq_optype
== PUFFS_VFS_VPTOFH
)) ||
143 (PUFFSOP_OPCLASS(preq
->preq_opclass
) == PUFFSOP_VN
&&
144 (preq
->preq_optype
== PUFFS_VN_READDIR
145 || preq
->preq_optype
== PUFFS_VN_READ
))) {
146 if (puffs_framebuf_reserve_space(pcc
->pcc_pb
,
147 PUFFS_MSG_MAXSIZE
) == -1)
149 preq
= puffs__framebuf_getdataptr(pcc
->pcc_pb
);
153 opcookie
= preq
->preq_cookie
;
155 assert((pcc
->pcc_flags
& PCC_DONE
) == 0);
157 buildpath
= pu
->pu_flags
& PUFFS_FLAG_BUILDPATH
;
158 preq
->preq_setbacks
= 0;
160 if (pu
->pu_flags
& PUFFS_FLAG_OPDUMP
)
163 puffs__cc_setcaller(pcc
, preq
->preq_pid
, preq
->preq_lid
);
172 /* Execute actual operation */
173 if (PUFFSOP_OPCLASS(preq
->preq_opclass
) == PUFFSOP_VFS
) {
174 switch (preq
->preq_optype
) {
175 case PUFFS_VFS_UNMOUNT
:
177 struct puffs_vfsmsg_unmount
*auxt
= auxbuf
;
179 PU_SETSTATE(pu
, PUFFS_STATE_UNMOUNTING
);
180 error
= pops
->puffs_fs_unmount(pu
, auxt
->pvfsr_flags
);
182 PU_SETSTATE(pu
, PUFFS_STATE_UNMOUNTED
);
184 PU_SETSTATE(pu
, PUFFS_STATE_RUNNING
);
188 case PUFFS_VFS_STATVFS
:
190 struct puffs_vfsmsg_statvfs
*auxt
= auxbuf
;
192 error
= pops
->puffs_fs_statvfs(pu
, &auxt
->pvfsr_sb
);
198 struct puffs_vfsmsg_sync
*auxt
= auxbuf
;
199 PUFFS_MAKECRED(pcr
, &auxt
->pvfsr_cred
);
201 error
= pops
->puffs_fs_sync(pu
,
202 auxt
->pvfsr_waitfor
, pcr
);
206 case PUFFS_VFS_FHTOVP
:
208 struct puffs_vfsmsg_fhtonode
*auxt
= auxbuf
;
209 struct puffs_newinfo pni
;
211 pni
.pni_cookie
= &auxt
->pvfsr_fhcookie
;
212 pni
.pni_vtype
= &auxt
->pvfsr_vtype
;
213 pni
.pni_size
= &auxt
->pvfsr_size
;
214 pni
.pni_rdev
= &auxt
->pvfsr_rdev
;
216 error
= pops
->puffs_fs_fhtonode(pu
, auxt
->pvfsr_data
,
217 auxt
->pvfsr_dsize
, &pni
);
222 case PUFFS_VFS_VPTOFH
:
224 struct puffs_vfsmsg_nodetofh
*auxt
= auxbuf
;
226 error
= pops
->puffs_fs_nodetofh(pu
,
227 auxt
->pvfsr_fhcookie
, auxt
->pvfsr_data
,
233 case PUFFS_VFS_SUSPEND
:
235 struct puffs_vfsmsg_suspend
*auxt
= auxbuf
;
238 if (pops
->puffs_fs_suspend
== NULL
)
241 pops
->puffs_fs_suspend(pu
, auxt
->pvfsr_status
);
247 * I guess the kernel sees this one coming
253 /* XXX: audit return values */
254 /* XXX: sync with kernel */
255 } else if (PUFFSOP_OPCLASS(preq
->preq_opclass
) == PUFFSOP_VN
) {
256 switch (preq
->preq_optype
) {
257 case PUFFS_VN_LOOKUP
:
259 struct puffs_vnmsg_lookup
*auxt
= auxbuf
;
260 struct puffs_newinfo pni
;
263 pcn
.pcn_pkcnp
= &auxt
->pvnr_cn
;
264 PUFFS_KCREDTOCRED(pcn
.pcn_cred
, &auxt
->pvnr_cn_cred
);
265 pni
.pni_cookie
= &auxt
->pvnr_newnode
;
266 pni
.pni_vtype
= &auxt
->pvnr_vtype
;
267 pni
.pni_size
= &auxt
->pvnr_size
;
268 pni
.pni_rdev
= &auxt
->pvnr_rdev
;
271 error
= puffs_path_pcnbuild(pu
, &pcn
, opcookie
);
276 /* lookup *must* be present */
277 error
= pops
->puffs_node_lookup(pu
, opcookie
,
282 pu
->pu_pathfree(pu
, &pcn
.pcn_po_full
);
284 struct puffs_node
*pn
;
287 * did we get a new node or a
290 pn
= PU_CMAP(pu
, auxt
->pvnr_newnode
);
291 if (pn
->pn_po
.po_path
== NULL
)
292 pn
->pn_po
= pcn
.pcn_po_full
;
302 case PUFFS_VN_CREATE
:
304 struct puffs_vnmsg_create
*auxt
= auxbuf
;
305 struct puffs_newinfo pni
;
308 if (pops
->puffs_node_create
== NULL
) {
313 pcn
.pcn_pkcnp
= &auxt
->pvnr_cn
;
314 PUFFS_KCREDTOCRED(pcn
.pcn_cred
, &auxt
->pvnr_cn_cred
);
316 memset(&pni
, 0, sizeof(pni
));
317 pni
.pni_cookie
= &auxt
->pvnr_newnode
;
320 error
= puffs_path_pcnbuild(pu
, &pcn
, opcookie
);
325 error
= pops
->puffs_node_create(pu
,
326 opcookie
, &pni
, &pcn
, &auxt
->pvnr_va
);
330 pu
->pu_pathfree(pu
, &pcn
.pcn_po_full
);
332 struct puffs_node
*pn
;
334 pn
= PU_CMAP(pu
, auxt
->pvnr_newnode
);
335 pn
->pn_po
= pcn
.pcn_po_full
;
344 struct puffs_vnmsg_mknod
*auxt
= auxbuf
;
345 struct puffs_newinfo pni
;
348 if (pops
->puffs_node_mknod
== NULL
) {
353 pcn
.pcn_pkcnp
= &auxt
->pvnr_cn
;
354 PUFFS_KCREDTOCRED(pcn
.pcn_cred
, &auxt
->pvnr_cn_cred
);
356 memset(&pni
, 0, sizeof(pni
));
357 pni
.pni_cookie
= &auxt
->pvnr_newnode
;
360 error
= puffs_path_pcnbuild(pu
, &pcn
, opcookie
);
365 error
= pops
->puffs_node_mknod(pu
,
366 opcookie
, &pni
, &pcn
, &auxt
->pvnr_va
);
370 pu
->pu_pathfree(pu
, &pcn
.pcn_po_full
);
372 struct puffs_node
*pn
;
374 pn
= PU_CMAP(pu
, auxt
->pvnr_newnode
);
375 pn
->pn_po
= pcn
.pcn_po_full
;
384 struct puffs_vnmsg_open
*auxt
= auxbuf
;
385 PUFFS_MAKECRED(pcr
, &auxt
->pvnr_cred
);
387 if (pops
->puffs_node_open
== NULL
) {
392 error
= pops
->puffs_node_open(pu
,
393 opcookie
, auxt
->pvnr_mode
, pcr
);
399 struct puffs_vnmsg_close
*auxt
= auxbuf
;
400 PUFFS_MAKECRED(pcr
, &auxt
->pvnr_cred
);
402 if (pops
->puffs_node_close
== NULL
) {
407 error
= pops
->puffs_node_close(pu
,
408 opcookie
, auxt
->pvnr_fflag
, pcr
);
412 case PUFFS_VN_ACCESS
:
414 struct puffs_vnmsg_access
*auxt
= auxbuf
;
415 PUFFS_MAKECRED(pcr
, &auxt
->pvnr_cred
);
417 if (pops
->puffs_node_access
== NULL
) {
422 error
= pops
->puffs_node_access(pu
,
423 opcookie
, auxt
->pvnr_mode
, pcr
);
427 case PUFFS_VN_GETATTR
:
429 struct puffs_vnmsg_getattr
*auxt
= auxbuf
;
430 PUFFS_MAKECRED(pcr
, &auxt
->pvnr_cred
);
432 if (pops
->puffs_node_getattr
== NULL
) {
437 error
= pops
->puffs_node_getattr(pu
,
438 opcookie
, &auxt
->pvnr_va
, pcr
);
442 case PUFFS_VN_SETATTR
:
444 struct puffs_vnmsg_setattr
*auxt
= auxbuf
;
445 PUFFS_MAKECRED(pcr
, &auxt
->pvnr_cred
);
447 if (pops
->puffs_node_setattr
== NULL
) {
452 error
= pops
->puffs_node_setattr(pu
,
453 opcookie
, &auxt
->pvnr_va
, pcr
);
459 struct puffs_vnmsg_mmap
*auxt
= auxbuf
;
460 PUFFS_MAKECRED(pcr
, &auxt
->pvnr_cred
);
462 if (pops
->puffs_node_mmap
== NULL
) {
467 error
= pops
->puffs_node_mmap(pu
,
468 opcookie
, auxt
->pvnr_prot
, pcr
);
474 struct puffs_vnmsg_fsync
*auxt
= auxbuf
;
475 PUFFS_MAKECRED(pcr
, &auxt
->pvnr_cred
);
477 if (pops
->puffs_node_fsync
== NULL
) {
482 error
= pops
->puffs_node_fsync(pu
, opcookie
, pcr
,
483 auxt
->pvnr_flags
, auxt
->pvnr_offlo
,
490 struct puffs_vnmsg_seek
*auxt
= auxbuf
;
491 PUFFS_MAKECRED(pcr
, &auxt
->pvnr_cred
);
493 if (pops
->puffs_node_seek
== NULL
) {
498 error
= pops
->puffs_node_seek(pu
,
499 opcookie
, auxt
->pvnr_oldoff
,
500 auxt
->pvnr_newoff
, pcr
);
504 case PUFFS_VN_REMOVE
:
506 struct puffs_vnmsg_remove
*auxt
= auxbuf
;
508 if (pops
->puffs_node_remove
== NULL
) {
513 pcn
.pcn_pkcnp
= &auxt
->pvnr_cn
;
514 PUFFS_KCREDTOCRED(pcn
.pcn_cred
, &auxt
->pvnr_cn_cred
);
516 error
= pops
->puffs_node_remove(pu
,
517 opcookie
, auxt
->pvnr_cookie_targ
, &pcn
);
523 struct puffs_vnmsg_link
*auxt
= auxbuf
;
525 if (pops
->puffs_node_link
== NULL
) {
530 pcn
.pcn_pkcnp
= &auxt
->pvnr_cn
;
531 PUFFS_KCREDTOCRED(pcn
.pcn_cred
, &auxt
->pvnr_cn_cred
);
534 error
= puffs_path_pcnbuild(pu
, &pcn
, opcookie
);
539 error
= pops
->puffs_node_link(pu
,
540 opcookie
, auxt
->pvnr_cookie_targ
, &pcn
);
542 pu
->pu_pathfree(pu
, &pcn
.pcn_po_full
);
547 case PUFFS_VN_RENAME
:
549 struct puffs_vnmsg_rename
*auxt
= auxbuf
;
550 struct puffs_cn pcn_src
, pcn_targ
;
551 struct puffs_node
*pn_src
;
553 if (pops
->puffs_node_rename
== NULL
) {
558 pcn_src
.pcn_pkcnp
= &auxt
->pvnr_cn_src
;
559 PUFFS_KCREDTOCRED(pcn_src
.pcn_cred
,
560 &auxt
->pvnr_cn_src_cred
);
562 pcn_targ
.pcn_pkcnp
= &auxt
->pvnr_cn_targ
;
563 PUFFS_KCREDTOCRED(pcn_targ
.pcn_cred
,
564 &auxt
->pvnr_cn_targ_cred
);
567 pn_src
= auxt
->pvnr_cookie_src
;
568 pcn_src
.pcn_po_full
= pn_src
->pn_po
;
570 error
= puffs_path_pcnbuild(pu
, &pcn_targ
,
571 auxt
->pvnr_cookie_targdir
);
576 error
= pops
->puffs_node_rename(pu
,
577 opcookie
, auxt
->pvnr_cookie_src
,
578 &pcn_src
, auxt
->pvnr_cookie_targdir
,
579 auxt
->pvnr_cookie_targ
, &pcn_targ
);
584 &pcn_targ
.pcn_po_full
);
586 struct puffs_pathinfo pi
;
587 struct puffs_pathobj po_old
;
589 /* handle this node */
590 po_old
= pn_src
->pn_po
;
591 pn_src
->pn_po
= pcn_targ
.pcn_po_full
;
593 if (pn_src
->pn_va
.va_type
!= VDIR
) {
594 pu
->pu_pathfree(pu
, &po_old
);
598 /* handle all child nodes for DIRs */
599 pi
.pi_old
= &pcn_src
.pcn_po_full
;
600 pi
.pi_new
= &pcn_targ
.pcn_po_full
;
603 if (puffs_pn_nodewalk(pu
,
604 puffs_path_prefixadj
, &pi
) != NULL
)
607 pu
->pu_pathfree(pu
, &po_old
);
615 struct puffs_vnmsg_mkdir
*auxt
= auxbuf
;
616 struct puffs_newinfo pni
;
619 if (pops
->puffs_node_mkdir
== NULL
) {
624 pcn
.pcn_pkcnp
= &auxt
->pvnr_cn
;
625 PUFFS_KCREDTOCRED(pcn
.pcn_cred
, &auxt
->pvnr_cn_cred
);
627 memset(&pni
, 0, sizeof(pni
));
628 pni
.pni_cookie
= &auxt
->pvnr_newnode
;
631 error
= puffs_path_pcnbuild(pu
, &pcn
, opcookie
);
636 error
= pops
->puffs_node_mkdir(pu
,
637 opcookie
, &pni
, &pcn
, &auxt
->pvnr_va
);
641 pu
->pu_pathfree(pu
, &pcn
.pcn_po_full
);
643 struct puffs_node
*pn
;
645 pn
= PU_CMAP(pu
, auxt
->pvnr_newnode
);
646 pn
->pn_po
= pcn
.pcn_po_full
;
655 struct puffs_vnmsg_rmdir
*auxt
= auxbuf
;
657 if (pops
->puffs_node_rmdir
== NULL
) {
662 pcn
.pcn_pkcnp
= &auxt
->pvnr_cn
;
663 PUFFS_KCREDTOCRED(pcn
.pcn_cred
, &auxt
->pvnr_cn_cred
);
665 error
= pops
->puffs_node_rmdir(pu
,
666 opcookie
, auxt
->pvnr_cookie_targ
, &pcn
);
670 case PUFFS_VN_SYMLINK
:
672 struct puffs_vnmsg_symlink
*auxt
= auxbuf
;
673 struct puffs_newinfo pni
;
676 if (pops
->puffs_node_symlink
== NULL
) {
681 pcn
.pcn_pkcnp
= &auxt
->pvnr_cn
;
682 PUFFS_KCREDTOCRED(pcn
.pcn_cred
, &auxt
->pvnr_cn_cred
);
684 memset(&pni
, 0, sizeof(pni
));
685 pni
.pni_cookie
= &auxt
->pvnr_newnode
;
688 error
= puffs_path_pcnbuild(pu
, &pcn
, opcookie
);
693 error
= pops
->puffs_node_symlink(pu
,
694 opcookie
, &pni
, &pcn
,
695 &auxt
->pvnr_va
, auxt
->pvnr_link
);
699 pu
->pu_pathfree(pu
, &pcn
.pcn_po_full
);
701 struct puffs_node
*pn
;
703 pn
= PU_CMAP(pu
, auxt
->pvnr_newnode
);
704 pn
->pn_po
= pcn
.pcn_po_full
;
711 case PUFFS_VN_READDIR
:
713 struct puffs_vnmsg_readdir
*auxt
= auxbuf
;
714 PUFFS_MAKECRED(pcr
, &auxt
->pvnr_cred
);
717 size_t res
, origcookies
;
719 if (pops
->puffs_node_readdir
== NULL
) {
724 if (auxt
->pvnr_ncookies
) {
725 /* LINTED: pvnr_data is __aligned() */
726 cookies
= (off_t
*)auxt
->pvnr_data
;
727 origcookies
= auxt
->pvnr_ncookies
;
732 /* LINTED: dentoff is aligned in the kernel */
733 dent
= (struct dirent
*)
734 (auxt
->pvnr_data
+ auxt
->pvnr_dentoff
);
736 res
= auxt
->pvnr_resid
;
737 error
= pops
->puffs_node_readdir(pu
,
738 opcookie
, dent
, &auxt
->pvnr_offset
,
739 &auxt
->pvnr_resid
, pcr
, &auxt
->pvnr_eofflag
,
740 cookies
, &auxt
->pvnr_ncookies
);
742 /* much easier to track non-working NFS */
743 assert(auxt
->pvnr_ncookies
<= origcookies
);
745 /* need to move a bit more */
746 preq
->preq_buflen
= sizeof(struct puffs_vnmsg_readdir
)
747 + auxt
->pvnr_dentoff
+ (res
- auxt
->pvnr_resid
);
751 case PUFFS_VN_READLINK
:
753 struct puffs_vnmsg_readlink
*auxt
= auxbuf
;
754 PUFFS_MAKECRED(pcr
, &auxt
->pvnr_cred
);
756 if (pops
->puffs_node_readlink
== NULL
) {
762 error
= pops
->puffs_node_readlink(pu
, opcookie
, pcr
,
763 auxt
->pvnr_link
, &auxt
->pvnr_linklen
);
767 case PUFFS_VN_RECLAIM
:
770 if (pops
->puffs_node_reclaim
== NULL
) {
775 error
= pops
->puffs_node_reclaim(pu
, opcookie
);
779 case PUFFS_VN_INACTIVE
:
782 if (pops
->puffs_node_inactive
== NULL
) {
787 error
= pops
->puffs_node_inactive(pu
, opcookie
);
791 case PUFFS_VN_PATHCONF
:
793 struct puffs_vnmsg_pathconf
*auxt
= auxbuf
;
794 if (pops
->puffs_node_pathconf
== NULL
) {
799 error
= pops
->puffs_node_pathconf(pu
,
800 opcookie
, auxt
->pvnr_name
,
805 case PUFFS_VN_ADVLOCK
:
807 struct puffs_vnmsg_advlock
*auxt
= auxbuf
;
808 if (pops
->puffs_node_advlock
== NULL
) {
813 error
= pops
->puffs_node_advlock(pu
,
814 opcookie
, auxt
->pvnr_id
, auxt
->pvnr_op
,
815 &auxt
->pvnr_fl
, auxt
->pvnr_flags
);
821 if (pops
->puffs_node_print
== NULL
) {
826 error
= pops
->puffs_node_print(pu
,
831 case PUFFS_VN_ABORTOP
:
833 struct puffs_vnmsg_abortop
*auxt
= auxbuf
;
836 if (pops
->puffs_node_abortop
== NULL
) {
841 pcn
.pcn_pkcnp
= &auxt
->pvnr_cn
;
842 PUFFS_KCREDTOCRED(pcn
.pcn_cred
, &auxt
->pvnr_cn_cred
);
844 error
= pops
->puffs_node_abortop(pu
, opcookie
, &pcn
);
851 struct puffs_vnmsg_read
*auxt
= auxbuf
;
852 PUFFS_MAKECRED(pcr
, &auxt
->pvnr_cred
);
855 if (pops
->puffs_node_read
== NULL
) {
860 res
= auxt
->pvnr_resid
;
861 error
= pops
->puffs_node_read(pu
,
862 opcookie
, auxt
->pvnr_data
,
863 auxt
->pvnr_offset
, &auxt
->pvnr_resid
,
864 pcr
, auxt
->pvnr_ioflag
);
866 /* need to move a bit more */
867 preq
->preq_buflen
= sizeof(struct puffs_vnmsg_read
)
868 + (res
- auxt
->pvnr_resid
);
874 struct puffs_vnmsg_write
*auxt
= auxbuf
;
875 PUFFS_MAKECRED(pcr
, &auxt
->pvnr_cred
);
877 if (pops
->puffs_node_write
== NULL
) {
882 error
= pops
->puffs_node_write(pu
,
883 opcookie
, auxt
->pvnr_data
,
884 auxt
->pvnr_offset
, &auxt
->pvnr_resid
,
885 pcr
, auxt
->pvnr_ioflag
);
887 /* don't need to move data back to the kernel */
888 preq
->preq_buflen
= sizeof(struct puffs_vnmsg_write
);
894 struct puffs_vnmsg_poll
*auxt
= auxbuf
;
896 if (pops
->puffs_node_poll
== NULL
) {
899 /* emulate genfs_poll() */
900 auxt
->pvnr_events
&= (POLLIN
| POLLOUT
901 | POLLRDNORM
| POLLWRNORM
);
906 error
= pops
->puffs_node_poll(pu
,
907 opcookie
, &auxt
->pvnr_events
);
912 printf("inval op %d\n", preq
->preq_optype
);
918 /* not issued by kernel currently */
919 } else if (PUFFSOP_OPCLASS(preq
->preq_opclass
) == PUFFSOP_CACHE
) {
920 struct puffs_cacheinfo
*pci
= (void *)preq
;
922 if (pu
->pu_ops
.puffs_cache_write
) {
923 pu
->pu_ops
.puffs_cache_write(pu
, preq
->preq_cookie
,
924 pci
->pcache_nruns
, pci
->pcache_runs
);
929 } else if (PUFFSOP_OPCLASS(preq
->preq_opclass
) == PUFFSOP_ERROR
) {
930 struct puffs_error
*perr
= (void *)preq
;
932 pu
->pu_errnotify(pu
, preq
->preq_optype
,
933 perr
->perr_error
, perr
->perr_str
, preq
->preq_cookie
);
937 * I guess the kernel sees this one coming also
943 preq
->preq_rv
= error
;
948 pcc
->pcc_flags
|= PCC_DONE
;