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;