Home | History | Annotate | Line # | Download | only in libpuffs
dispatcher.c revision 1.32.10.1
      1  1.32.10.1   matt /*	$NetBSD: dispatcher.c,v 1.32.10.1 2010/04/21 05:28:11 matt Exp $	*/
      2        1.1  pooka 
      3        1.1  pooka /*
      4       1.30  pooka  * Copyright (c) 2006, 2007, 2008 Antti Kantee.  All Rights Reserved.
      5        1.1  pooka  *
      6        1.1  pooka  * Development of this software was supported by the
      7       1.30  pooka  * Ulla Tuominen Foundation, the Finnish Cultural Foundation and
      8       1.30  pooka  * Research Foundation of Helsinki University of Technology.
      9        1.1  pooka  *
     10        1.1  pooka  * Redistribution and use in source and binary forms, with or without
     11        1.1  pooka  * modification, are permitted provided that the following conditions
     12        1.1  pooka  * are met:
     13        1.1  pooka  * 1. Redistributions of source code must retain the above copyright
     14        1.1  pooka  *    notice, this list of conditions and the following disclaimer.
     15        1.1  pooka  * 2. Redistributions in binary form must reproduce the above copyright
     16        1.1  pooka  *    notice, this list of conditions and the following disclaimer in the
     17        1.1  pooka  *    documentation and/or other materials provided with the distribution.
     18        1.1  pooka  *
     19        1.1  pooka  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
     20        1.1  pooka  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     21        1.1  pooka  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     22        1.1  pooka  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     23        1.1  pooka  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24        1.1  pooka  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     25        1.1  pooka  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26        1.1  pooka  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27        1.1  pooka  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28        1.1  pooka  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29        1.1  pooka  * SUCH DAMAGE.
     30        1.1  pooka  */
     31        1.1  pooka 
     32        1.1  pooka #include <sys/cdefs.h>
     33        1.1  pooka #if !defined(lint)
     34  1.32.10.1   matt __RCSID("$NetBSD: dispatcher.c,v 1.32.10.1 2010/04/21 05:28:11 matt Exp $");
     35        1.1  pooka #endif /* !lint */
     36        1.1  pooka 
     37        1.1  pooka #include <sys/types.h>
     38        1.4  pooka #include <sys/poll.h>
     39        1.1  pooka 
     40        1.1  pooka #include <assert.h>
     41        1.1  pooka #include <errno.h>
     42       1.17  pooka #ifdef PUFFS_WITH_THREADS
     43       1.17  pooka #include <pthread.h>
     44       1.17  pooka #endif
     45        1.1  pooka #include <puffs.h>
     46        1.1  pooka #include <puffsdump.h>
     47        1.1  pooka #include <stdio.h>
     48        1.1  pooka #include <stdlib.h>
     49        1.1  pooka #include <unistd.h>
     50        1.1  pooka 
     51        1.1  pooka #include "puffs_priv.h"
     52        1.1  pooka 
     53       1.30  pooka #if 0 /* me not worka now */
     54       1.17  pooka /*
     55       1.17  pooka  * Set the following to 1 to handle each request in a separate pthread.
     56       1.17  pooka  * This is not exported as it should not be used yet unless having a
     57       1.17  pooka  * very good knowledge of what you're signing up for (libpuffs is not
     58       1.17  pooka  * threadsafe).
     59       1.17  pooka  */
     60       1.17  pooka int puffs_usethreads;
     61       1.17  pooka #endif
     62       1.17  pooka 
     63       1.30  pooka static void dispatch(struct puffs_cc *);
     64       1.17  pooka 
     65       1.30  pooka /* for our eyes only */
     66       1.30  pooka void
     67       1.30  pooka puffs__ml_dispatch(struct puffs_usermount *pu, struct puffs_framebuf *pb)
     68       1.30  pooka {
     69       1.30  pooka 	struct puffs_cc *pcc = puffs_cc_getcc(pu);
     70       1.30  pooka 	struct puffs_req *preq;
     71       1.17  pooka 
     72       1.30  pooka 	pcc->pcc_pb = pb;
     73       1.30  pooka 	pcc->pcc_flags |= PCC_MLCONT;
     74       1.30  pooka 	dispatch(pcc);
     75       1.17  pooka 
     76       1.30  pooka 	/* Put result to kernel sendqueue if necessary */
     77       1.30  pooka 	preq = puffs__framebuf_getdataptr(pcc->pcc_pb);
     78       1.30  pooka 	if (PUFFSOP_WANTREPLY(preq->preq_opclass)) {
     79       1.30  pooka 		if (pu->pu_flags & PUFFS_FLAG_OPDUMP)
     80       1.30  pooka 			puffsdump_rv(preq);
     81       1.17  pooka 
     82       1.30  pooka 		puffs_framev_enqueue_justsend(pu, pu->pu_fd,
     83       1.30  pooka 		    pcc->pcc_pb, 0, 0);
     84       1.30  pooka 	} else {
     85       1.30  pooka 		puffs_framebuf_destroy(pcc->pcc_pb);
     86       1.30  pooka 	}
     87       1.17  pooka 
     88       1.30  pooka 	/* who needs information when you're living on borrowed time? */
     89       1.30  pooka 	if (pcc->pcc_flags & PCC_BORROWED) {
     90       1.30  pooka 		puffs_cc_yield(pcc); /* back to borrow source */
     91       1.17  pooka 	}
     92       1.30  pooka 	pcc->pcc_flags = 0;
     93       1.17  pooka }
     94       1.17  pooka 
     95       1.30  pooka /* public, but not really tested and only semi-supported */
     96        1.1  pooka int
     97       1.30  pooka puffs_dispatch_create(struct puffs_usermount *pu, struct puffs_framebuf *pb,
     98       1.30  pooka 	struct puffs_cc **pccp)
     99        1.1  pooka {
    100       1.30  pooka 	struct puffs_cc *pcc;
    101        1.1  pooka 
    102       1.30  pooka 	if (puffs__cc_create(pu, dispatch, &pcc) == -1)
    103       1.30  pooka 		return -1;
    104        1.1  pooka 
    105       1.30  pooka 	pcc->pcc_pb = pb;
    106       1.30  pooka 	*pccp = pcc;
    107        1.1  pooka 
    108       1.30  pooka 	return 0;
    109        1.1  pooka }
    110        1.1  pooka 
    111       1.30  pooka int
    112       1.30  pooka puffs_dispatch_exec(struct puffs_cc *pcc, struct puffs_framebuf **pbp)
    113        1.1  pooka {
    114       1.30  pooka 	int rv;
    115        1.1  pooka 
    116       1.30  pooka 	puffs_cc_continue(pcc);
    117       1.25  pooka 
    118       1.30  pooka 	if (pcc->pcc_flags & PCC_DONE) {
    119       1.30  pooka 		rv = 1;
    120       1.30  pooka 		*pbp = pcc->pcc_pb;
    121       1.30  pooka 		pcc->pcc_flags = 0;
    122       1.30  pooka 		puffs__cc_destroy(pcc, 0);
    123       1.30  pooka 	} else {
    124       1.30  pooka 		rv = 0;
    125        1.1  pooka 	}
    126       1.25  pooka 
    127       1.30  pooka 	return rv;
    128        1.1  pooka }
    129        1.1  pooka 
    130       1.30  pooka static void
    131       1.30  pooka dispatch(struct puffs_cc *pcc)
    132        1.1  pooka {
    133        1.1  pooka 	struct puffs_usermount *pu = pcc->pcc_pu;
    134        1.1  pooka 	struct puffs_ops *pops = &pu->pu_ops;
    135       1.25  pooka 	struct puffs_req *preq = puffs__framebuf_getdataptr(pcc->pcc_pb);
    136       1.31  pooka 	void *auxbuf; /* help with typecasting */
    137       1.32  pooka 	puffs_cookie_t opcookie;
    138       1.31  pooka 	int error = 0, buildpath;
    139       1.31  pooka 
    140       1.31  pooka 	/* XXX: smaller hammer, please */
    141       1.31  pooka 	if ((PUFFSOP_OPCLASS(preq->preq_opclass == PUFFSOP_VFS &&
    142       1.31  pooka 	    preq->preq_optype == PUFFS_VFS_VPTOFH)) ||
    143       1.31  pooka 	    (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VN &&
    144       1.31  pooka 	    (preq->preq_optype == PUFFS_VN_READDIR
    145       1.31  pooka 	    || preq->preq_optype == PUFFS_VN_READ))) {
    146       1.31  pooka 		if (puffs_framebuf_reserve_space(pcc->pcc_pb,
    147       1.31  pooka 		    PUFFS_MSG_MAXSIZE) == -1)
    148       1.31  pooka 			error = errno;
    149       1.31  pooka 		preq = puffs__framebuf_getdataptr(pcc->pcc_pb);
    150       1.31  pooka 	}
    151       1.31  pooka 
    152       1.31  pooka 	auxbuf = preq;
    153       1.31  pooka 	opcookie = preq->preq_cookie;
    154        1.1  pooka 
    155       1.30  pooka 	assert((pcc->pcc_flags & PCC_DONE) == 0);
    156        1.1  pooka 
    157        1.1  pooka 	buildpath = pu->pu_flags & PUFFS_FLAG_BUILDPATH;
    158        1.1  pooka 	preq->preq_setbacks = 0;
    159        1.1  pooka 
    160       1.30  pooka 	if (pu->pu_flags & PUFFS_FLAG_OPDUMP)
    161       1.30  pooka 		puffsdump_req(preq);
    162       1.30  pooka 
    163       1.30  pooka 	puffs__cc_setcaller(pcc, preq->preq_pid, preq->preq_lid);
    164       1.30  pooka 
    165       1.30  pooka 	/* pre-operation */
    166       1.18  pooka 	if (pu->pu_oppre)
    167       1.24  pooka 		pu->pu_oppre(pu);
    168       1.18  pooka 
    169       1.31  pooka 	if (error)
    170       1.31  pooka 		goto out;
    171       1.31  pooka 
    172       1.30  pooka 	/* Execute actual operation */
    173        1.1  pooka 	if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VFS) {
    174        1.1  pooka 		switch (preq->preq_optype) {
    175        1.1  pooka 		case PUFFS_VFS_UNMOUNT:
    176        1.1  pooka 		{
    177       1.15  pooka 			struct puffs_vfsmsg_unmount *auxt = auxbuf;
    178        1.1  pooka 
    179        1.1  pooka 			PU_SETSTATE(pu, PUFFS_STATE_UNMOUNTING);
    180       1.24  pooka 			error = pops->puffs_fs_unmount(pu, auxt->pvfsr_flags);
    181        1.1  pooka 			if (!error)
    182        1.1  pooka 				PU_SETSTATE(pu, PUFFS_STATE_UNMOUNTED);
    183        1.1  pooka 			else
    184        1.1  pooka 				PU_SETSTATE(pu, PUFFS_STATE_RUNNING);
    185        1.1  pooka 			break;
    186        1.1  pooka 		}
    187        1.1  pooka 
    188        1.1  pooka 		case PUFFS_VFS_STATVFS:
    189        1.1  pooka 		{
    190       1.15  pooka 			struct puffs_vfsmsg_statvfs *auxt = auxbuf;
    191        1.1  pooka 
    192       1.24  pooka 			error = pops->puffs_fs_statvfs(pu, &auxt->pvfsr_sb);
    193        1.1  pooka 			break;
    194        1.1  pooka 		}
    195        1.1  pooka 
    196        1.1  pooka 		case PUFFS_VFS_SYNC:
    197        1.1  pooka 		{
    198       1.15  pooka 			struct puffs_vfsmsg_sync *auxt = auxbuf;
    199        1.7  pooka 			PUFFS_MAKECRED(pcr, &auxt->pvfsr_cred);
    200        1.1  pooka 
    201       1.24  pooka 			error = pops->puffs_fs_sync(pu,
    202       1.22  pooka 			    auxt->pvfsr_waitfor, pcr);
    203        1.1  pooka 			break;
    204        1.1  pooka 		}
    205        1.1  pooka 
    206        1.1  pooka 		case PUFFS_VFS_FHTOVP:
    207        1.1  pooka 		{
    208       1.15  pooka 			struct puffs_vfsmsg_fhtonode *auxt = auxbuf;
    209        1.9  pooka 			struct puffs_newinfo pni;
    210        1.9  pooka 
    211        1.9  pooka 			pni.pni_cookie = &auxt->pvfsr_fhcookie;
    212        1.9  pooka 			pni.pni_vtype = &auxt->pvfsr_vtype;
    213        1.9  pooka 			pni.pni_size = &auxt->pvfsr_size;
    214        1.9  pooka 			pni.pni_rdev = &auxt->pvfsr_rdev;
    215        1.1  pooka 
    216       1.24  pooka 			error = pops->puffs_fs_fhtonode(pu, auxt->pvfsr_data,
    217        1.9  pooka 			    auxt->pvfsr_dsize, &pni);
    218        1.1  pooka 
    219        1.1  pooka 			break;
    220        1.1  pooka 		}
    221        1.1  pooka 
    222        1.1  pooka 		case PUFFS_VFS_VPTOFH:
    223        1.1  pooka 		{
    224       1.15  pooka 			struct puffs_vfsmsg_nodetofh *auxt = auxbuf;
    225        1.1  pooka 
    226       1.24  pooka 			error = pops->puffs_fs_nodetofh(pu,
    227        1.1  pooka 			    auxt->pvfsr_fhcookie, auxt->pvfsr_data,
    228        1.1  pooka 			    &auxt->pvfsr_dsize);
    229        1.1  pooka 
    230        1.1  pooka 			break;
    231        1.1  pooka 		}
    232        1.1  pooka 
    233        1.1  pooka 		case PUFFS_VFS_SUSPEND:
    234        1.1  pooka 		{
    235       1.15  pooka 			struct puffs_vfsmsg_suspend *auxt = auxbuf;
    236        1.1  pooka 
    237        1.1  pooka 			error = 0;
    238        1.1  pooka 			if (pops->puffs_fs_suspend == NULL)
    239        1.1  pooka 				break;
    240        1.1  pooka 
    241       1.24  pooka 			pops->puffs_fs_suspend(pu, auxt->pvfsr_status);
    242        1.1  pooka 			break;
    243        1.1  pooka 		}
    244        1.1  pooka 
    245        1.1  pooka 		default:
    246        1.1  pooka 			/*
    247        1.1  pooka 			 * I guess the kernel sees this one coming
    248        1.1  pooka 			 */
    249        1.1  pooka 			error = EINVAL;
    250        1.1  pooka 			break;
    251        1.1  pooka 		}
    252        1.1  pooka 
    253        1.1  pooka 	/* XXX: audit return values */
    254        1.1  pooka 	/* XXX: sync with kernel */
    255        1.1  pooka 	} else if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VN) {
    256        1.1  pooka 		switch (preq->preq_optype) {
    257        1.1  pooka 		case PUFFS_VN_LOOKUP:
    258        1.1  pooka 		{
    259       1.15  pooka 			struct puffs_vnmsg_lookup *auxt = auxbuf;
    260        1.9  pooka 			struct puffs_newinfo pni;
    261        1.1  pooka 			struct puffs_cn pcn;
    262        1.1  pooka 
    263        1.1  pooka 			pcn.pcn_pkcnp = &auxt->pvnr_cn;
    264        1.7  pooka 			PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
    265        1.9  pooka 			pni.pni_cookie = &auxt->pvnr_newnode;
    266        1.9  pooka 			pni.pni_vtype = &auxt->pvnr_vtype;
    267        1.9  pooka 			pni.pni_size = &auxt->pvnr_size;
    268        1.9  pooka 			pni.pni_rdev = &auxt->pvnr_rdev;
    269        1.7  pooka 
    270        1.1  pooka 			if (buildpath) {
    271        1.1  pooka 				error = puffs_path_pcnbuild(pu, &pcn, opcookie);
    272        1.1  pooka 				if (error)
    273        1.1  pooka 					break;
    274        1.1  pooka 			}
    275        1.1  pooka 
    276        1.1  pooka 			/* lookup *must* be present */
    277       1.24  pooka 			error = pops->puffs_node_lookup(pu, opcookie,
    278        1.9  pooka 			    &pni, &pcn);
    279        1.1  pooka 
    280        1.1  pooka 			if (buildpath) {
    281        1.1  pooka 				if (error) {
    282        1.1  pooka 					pu->pu_pathfree(pu, &pcn.pcn_po_full);
    283        1.1  pooka 				} else {
    284        1.1  pooka 					struct puffs_node *pn;
    285        1.1  pooka 
    286        1.1  pooka 					/*
    287        1.1  pooka 					 * did we get a new node or a
    288        1.1  pooka 					 * recycled node?
    289        1.1  pooka 					 */
    290        1.1  pooka 					pn = PU_CMAP(pu, auxt->pvnr_newnode);
    291        1.1  pooka 					if (pn->pn_po.po_path == NULL)
    292        1.1  pooka 						pn->pn_po = pcn.pcn_po_full;
    293        1.1  pooka 					else
    294        1.1  pooka 						pu->pu_pathfree(pu,
    295        1.1  pooka 						    &pcn.pcn_po_full);
    296        1.1  pooka 				}
    297        1.1  pooka 			}
    298        1.1  pooka 
    299        1.1  pooka 			break;
    300        1.1  pooka 		}
    301        1.1  pooka 
    302        1.1  pooka 		case PUFFS_VN_CREATE:
    303        1.1  pooka 		{
    304       1.15  pooka 			struct puffs_vnmsg_create *auxt = auxbuf;
    305        1.9  pooka 			struct puffs_newinfo pni;
    306        1.1  pooka 			struct puffs_cn pcn;
    307        1.9  pooka 
    308        1.1  pooka 			if (pops->puffs_node_create == NULL) {
    309        1.1  pooka 				error = 0;
    310        1.1  pooka 				break;
    311        1.1  pooka 			}
    312        1.1  pooka 
    313        1.1  pooka 			pcn.pcn_pkcnp = &auxt->pvnr_cn;
    314        1.7  pooka 			PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
    315        1.7  pooka 
    316        1.9  pooka 			memset(&pni, 0, sizeof(pni));
    317        1.9  pooka 			pni.pni_cookie = &auxt->pvnr_newnode;
    318        1.9  pooka 
    319        1.1  pooka 			if (buildpath) {
    320        1.1  pooka 				error = puffs_path_pcnbuild(pu, &pcn, opcookie);
    321        1.1  pooka 				if (error)
    322        1.1  pooka 					break;
    323        1.1  pooka 			}
    324        1.1  pooka 
    325       1.24  pooka 			error = pops->puffs_node_create(pu,
    326        1.9  pooka 			    opcookie, &pni, &pcn, &auxt->pvnr_va);
    327        1.1  pooka 
    328        1.1  pooka 			if (buildpath) {
    329        1.1  pooka 				if (error) {
    330        1.1  pooka 					pu->pu_pathfree(pu, &pcn.pcn_po_full);
    331        1.1  pooka 				} else {
    332        1.1  pooka 					struct puffs_node *pn;
    333        1.1  pooka 
    334        1.1  pooka 					pn = PU_CMAP(pu, auxt->pvnr_newnode);
    335        1.1  pooka 					pn->pn_po = pcn.pcn_po_full;
    336        1.1  pooka 				}
    337        1.1  pooka 			}
    338        1.1  pooka 
    339        1.1  pooka 			break;
    340        1.1  pooka 		}
    341        1.1  pooka 
    342        1.1  pooka 		case PUFFS_VN_MKNOD:
    343        1.1  pooka 		{
    344       1.15  pooka 			struct puffs_vnmsg_mknod *auxt = auxbuf;
    345        1.9  pooka 			struct puffs_newinfo pni;
    346        1.1  pooka 			struct puffs_cn pcn;
    347        1.9  pooka 
    348        1.1  pooka 			if (pops->puffs_node_mknod == NULL) {
    349        1.1  pooka 				error = 0;
    350        1.1  pooka 				break;
    351        1.1  pooka 			}
    352        1.1  pooka 
    353        1.1  pooka 			pcn.pcn_pkcnp = &auxt->pvnr_cn;
    354        1.7  pooka 			PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
    355        1.7  pooka 
    356        1.9  pooka 			memset(&pni, 0, sizeof(pni));
    357        1.9  pooka 			pni.pni_cookie = &auxt->pvnr_newnode;
    358        1.9  pooka 
    359        1.1  pooka 			if (buildpath) {
    360        1.1  pooka 				error = puffs_path_pcnbuild(pu, &pcn, opcookie);
    361        1.1  pooka 				if (error)
    362        1.1  pooka 					break;
    363        1.1  pooka 			}
    364        1.1  pooka 
    365       1.24  pooka 			error = pops->puffs_node_mknod(pu,
    366        1.9  pooka 			    opcookie, &pni, &pcn, &auxt->pvnr_va);
    367        1.1  pooka 
    368        1.1  pooka 			if (buildpath) {
    369        1.1  pooka 				if (error) {
    370        1.1  pooka 					pu->pu_pathfree(pu, &pcn.pcn_po_full);
    371        1.1  pooka 				} else {
    372        1.1  pooka 					struct puffs_node *pn;
    373        1.1  pooka 
    374        1.1  pooka 					pn = PU_CMAP(pu, auxt->pvnr_newnode);
    375        1.1  pooka 					pn->pn_po = pcn.pcn_po_full;
    376        1.1  pooka 				}
    377        1.1  pooka 			}
    378        1.1  pooka 
    379        1.1  pooka 			break;
    380        1.1  pooka 		}
    381        1.1  pooka 
    382        1.1  pooka 		case PUFFS_VN_OPEN:
    383        1.1  pooka 		{
    384       1.15  pooka 			struct puffs_vnmsg_open *auxt = auxbuf;
    385        1.7  pooka 			PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
    386        1.7  pooka 
    387        1.1  pooka 			if (pops->puffs_node_open == NULL) {
    388        1.1  pooka 				error = 0;
    389        1.1  pooka 				break;
    390        1.1  pooka 			}
    391        1.1  pooka 
    392       1.24  pooka 			error = pops->puffs_node_open(pu,
    393       1.22  pooka 			    opcookie, auxt->pvnr_mode, pcr);
    394        1.1  pooka 			break;
    395        1.1  pooka 		}
    396        1.1  pooka 
    397        1.1  pooka 		case PUFFS_VN_CLOSE:
    398        1.1  pooka 		{
    399       1.15  pooka 			struct puffs_vnmsg_close *auxt = auxbuf;
    400        1.7  pooka 			PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
    401        1.7  pooka 
    402        1.1  pooka 			if (pops->puffs_node_close == NULL) {
    403        1.1  pooka 				error = 0;
    404        1.1  pooka 				break;
    405        1.1  pooka 			}
    406        1.1  pooka 
    407       1.24  pooka 			error = pops->puffs_node_close(pu,
    408       1.22  pooka 			    opcookie, auxt->pvnr_fflag, pcr);
    409        1.1  pooka 			break;
    410        1.1  pooka 		}
    411        1.1  pooka 
    412        1.1  pooka 		case PUFFS_VN_ACCESS:
    413        1.1  pooka 		{
    414       1.15  pooka 			struct puffs_vnmsg_access *auxt = auxbuf;
    415        1.7  pooka 			PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
    416        1.7  pooka 
    417        1.1  pooka 			if (pops->puffs_node_access == NULL) {
    418        1.1  pooka 				error = 0;
    419        1.1  pooka 				break;
    420        1.1  pooka 			}
    421        1.1  pooka 
    422       1.24  pooka 			error = pops->puffs_node_access(pu,
    423       1.22  pooka 			    opcookie, auxt->pvnr_mode, pcr);
    424        1.1  pooka 			break;
    425        1.1  pooka 		}
    426        1.1  pooka 
    427        1.1  pooka 		case PUFFS_VN_GETATTR:
    428        1.1  pooka 		{
    429       1.15  pooka 			struct puffs_vnmsg_getattr *auxt = auxbuf;
    430        1.7  pooka 			PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
    431        1.7  pooka 
    432        1.1  pooka 			if (pops->puffs_node_getattr == NULL) {
    433        1.1  pooka 				error = EOPNOTSUPP;
    434        1.1  pooka 				break;
    435        1.1  pooka 			}
    436        1.1  pooka 
    437       1.24  pooka 			error = pops->puffs_node_getattr(pu,
    438       1.22  pooka 			    opcookie, &auxt->pvnr_va, pcr);
    439        1.1  pooka 			break;
    440        1.1  pooka 		}
    441        1.1  pooka 
    442        1.1  pooka 		case PUFFS_VN_SETATTR:
    443        1.1  pooka 		{
    444       1.15  pooka 			struct puffs_vnmsg_setattr *auxt = auxbuf;
    445        1.7  pooka 			PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
    446        1.7  pooka 
    447        1.1  pooka 			if (pops->puffs_node_setattr == NULL) {
    448        1.1  pooka 				error = EOPNOTSUPP;
    449        1.1  pooka 				break;
    450        1.1  pooka 			}
    451        1.1  pooka 
    452       1.24  pooka 			error = pops->puffs_node_setattr(pu,
    453       1.22  pooka 			    opcookie, &auxt->pvnr_va, pcr);
    454        1.1  pooka 			break;
    455        1.1  pooka 		}
    456        1.1  pooka 
    457        1.1  pooka 		case PUFFS_VN_MMAP:
    458        1.1  pooka 		{
    459       1.15  pooka 			struct puffs_vnmsg_mmap *auxt = auxbuf;
    460        1.7  pooka 			PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
    461        1.7  pooka 
    462        1.1  pooka 			if (pops->puffs_node_mmap == NULL) {
    463        1.1  pooka 				error = 0;
    464        1.1  pooka 				break;
    465        1.1  pooka 			}
    466        1.1  pooka 
    467       1.24  pooka 			error = pops->puffs_node_mmap(pu,
    468       1.22  pooka 			    opcookie, auxt->pvnr_prot, pcr);
    469        1.1  pooka 			break;
    470        1.1  pooka 		}
    471        1.1  pooka 
    472        1.1  pooka 		case PUFFS_VN_FSYNC:
    473        1.1  pooka 		{
    474       1.15  pooka 			struct puffs_vnmsg_fsync *auxt = auxbuf;
    475        1.7  pooka 			PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
    476        1.7  pooka 
    477        1.1  pooka 			if (pops->puffs_node_fsync == NULL) {
    478        1.1  pooka 				error = 0;
    479        1.1  pooka 				break;
    480        1.1  pooka 			}
    481        1.1  pooka 
    482       1.24  pooka 			error = pops->puffs_node_fsync(pu, opcookie, pcr,
    483        1.1  pooka 			    auxt->pvnr_flags, auxt->pvnr_offlo,
    484       1.22  pooka 			    auxt->pvnr_offhi);
    485        1.1  pooka 			break;
    486        1.1  pooka 		}
    487        1.1  pooka 
    488        1.1  pooka 		case PUFFS_VN_SEEK:
    489        1.1  pooka 		{
    490       1.15  pooka 			struct puffs_vnmsg_seek *auxt = auxbuf;
    491        1.7  pooka 			PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
    492        1.7  pooka 
    493        1.1  pooka 			if (pops->puffs_node_seek == NULL) {
    494        1.1  pooka 				error = 0;
    495        1.1  pooka 				break;
    496        1.1  pooka 			}
    497        1.1  pooka 
    498       1.24  pooka 			error = pops->puffs_node_seek(pu,
    499        1.1  pooka 			    opcookie, auxt->pvnr_oldoff,
    500        1.7  pooka 			    auxt->pvnr_newoff, pcr);
    501        1.1  pooka 			break;
    502        1.1  pooka 		}
    503        1.1  pooka 
    504        1.1  pooka 		case PUFFS_VN_REMOVE:
    505        1.1  pooka 		{
    506       1.15  pooka 			struct puffs_vnmsg_remove *auxt = auxbuf;
    507        1.1  pooka 			struct puffs_cn pcn;
    508        1.1  pooka 			if (pops->puffs_node_remove == NULL) {
    509        1.1  pooka 				error = 0;
    510        1.1  pooka 				break;
    511        1.1  pooka 			}
    512        1.1  pooka 
    513        1.1  pooka 			pcn.pcn_pkcnp = &auxt->pvnr_cn;
    514        1.7  pooka 			PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
    515        1.1  pooka 
    516       1.24  pooka 			error = pops->puffs_node_remove(pu,
    517        1.1  pooka 			    opcookie, auxt->pvnr_cookie_targ, &pcn);
    518        1.1  pooka 			break;
    519        1.1  pooka 		}
    520        1.1  pooka 
    521        1.1  pooka 		case PUFFS_VN_LINK:
    522        1.1  pooka 		{
    523       1.15  pooka 			struct puffs_vnmsg_link *auxt = auxbuf;
    524        1.1  pooka 			struct puffs_cn pcn;
    525        1.1  pooka 			if (pops->puffs_node_link == NULL) {
    526        1.1  pooka 				error = 0;
    527        1.1  pooka 				break;
    528        1.1  pooka 			}
    529        1.1  pooka 
    530        1.1  pooka 			pcn.pcn_pkcnp = &auxt->pvnr_cn;
    531        1.7  pooka 			PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
    532        1.7  pooka 
    533        1.1  pooka 			if (buildpath) {
    534        1.1  pooka 				error = puffs_path_pcnbuild(pu, &pcn, opcookie);
    535        1.1  pooka 				if (error)
    536        1.1  pooka 					break;
    537        1.1  pooka 			}
    538        1.1  pooka 
    539       1.24  pooka 			error = pops->puffs_node_link(pu,
    540        1.1  pooka 			    opcookie, auxt->pvnr_cookie_targ, &pcn);
    541        1.1  pooka 			if (buildpath)
    542        1.1  pooka 				pu->pu_pathfree(pu, &pcn.pcn_po_full);
    543        1.1  pooka 
    544        1.1  pooka 			break;
    545        1.1  pooka 		}
    546        1.1  pooka 
    547        1.1  pooka 		case PUFFS_VN_RENAME:
    548        1.1  pooka 		{
    549       1.15  pooka 			struct puffs_vnmsg_rename *auxt = auxbuf;
    550        1.1  pooka 			struct puffs_cn pcn_src, pcn_targ;
    551        1.1  pooka 			struct puffs_node *pn_src;
    552        1.1  pooka 
    553        1.1  pooka 			if (pops->puffs_node_rename == NULL) {
    554        1.1  pooka 				error = 0;
    555        1.1  pooka 				break;
    556        1.1  pooka 			}
    557        1.1  pooka 
    558        1.1  pooka 			pcn_src.pcn_pkcnp = &auxt->pvnr_cn_src;
    559        1.7  pooka 			PUFFS_KCREDTOCRED(pcn_src.pcn_cred,
    560        1.7  pooka 			    &auxt->pvnr_cn_src_cred);
    561        1.8  pooka 
    562        1.1  pooka 			pcn_targ.pcn_pkcnp = &auxt->pvnr_cn_targ;
    563        1.7  pooka 			PUFFS_KCREDTOCRED(pcn_targ.pcn_cred,
    564        1.7  pooka 			    &auxt->pvnr_cn_targ_cred);
    565        1.7  pooka 
    566        1.1  pooka 			if (buildpath) {
    567        1.1  pooka 				pn_src = auxt->pvnr_cookie_src;
    568        1.1  pooka 				pcn_src.pcn_po_full = pn_src->pn_po;
    569        1.1  pooka 
    570        1.1  pooka 				error = puffs_path_pcnbuild(pu, &pcn_targ,
    571        1.1  pooka 				    auxt->pvnr_cookie_targdir);
    572        1.1  pooka 				if (error)
    573        1.1  pooka 					break;
    574        1.1  pooka 			}
    575        1.1  pooka 
    576       1.24  pooka 			error = pops->puffs_node_rename(pu,
    577        1.1  pooka 			    opcookie, auxt->pvnr_cookie_src,
    578        1.1  pooka 			    &pcn_src, auxt->pvnr_cookie_targdir,
    579        1.1  pooka 			    auxt->pvnr_cookie_targ, &pcn_targ);
    580        1.1  pooka 
    581        1.1  pooka 			if (buildpath) {
    582        1.1  pooka 				if (error) {
    583        1.1  pooka 					pu->pu_pathfree(pu,
    584        1.1  pooka 					    &pcn_targ.pcn_po_full);
    585        1.1  pooka 				} else {
    586        1.1  pooka 					struct puffs_pathinfo pi;
    587        1.1  pooka 					struct puffs_pathobj po_old;
    588        1.1  pooka 
    589        1.1  pooka 					/* handle this node */
    590        1.1  pooka 					po_old = pn_src->pn_po;
    591        1.1  pooka 					pn_src->pn_po = pcn_targ.pcn_po_full;
    592        1.1  pooka 
    593        1.1  pooka 					if (pn_src->pn_va.va_type != VDIR) {
    594        1.1  pooka 						pu->pu_pathfree(pu, &po_old);
    595        1.1  pooka 						break;
    596        1.1  pooka 					}
    597        1.1  pooka 
    598        1.1  pooka 					/* handle all child nodes for DIRs */
    599        1.1  pooka 					pi.pi_old = &pcn_src.pcn_po_full;
    600        1.1  pooka 					pi.pi_new = &pcn_targ.pcn_po_full;
    601        1.1  pooka 
    602       1.19  pooka 					PU_LOCK();
    603        1.1  pooka 					if (puffs_pn_nodewalk(pu,
    604        1.1  pooka 					    puffs_path_prefixadj, &pi) != NULL)
    605        1.1  pooka 						error = ENOMEM;
    606       1.19  pooka 					PU_UNLOCK();
    607        1.1  pooka 					pu->pu_pathfree(pu, &po_old);
    608        1.1  pooka 				}
    609        1.1  pooka 			}
    610        1.1  pooka 			break;
    611        1.1  pooka 		}
    612        1.1  pooka 
    613        1.1  pooka 		case PUFFS_VN_MKDIR:
    614        1.1  pooka 		{
    615       1.15  pooka 			struct puffs_vnmsg_mkdir *auxt = auxbuf;
    616        1.9  pooka 			struct puffs_newinfo pni;
    617        1.1  pooka 			struct puffs_cn pcn;
    618        1.9  pooka 
    619        1.1  pooka 			if (pops->puffs_node_mkdir == NULL) {
    620        1.1  pooka 				error = 0;
    621        1.1  pooka 				break;
    622        1.1  pooka 			}
    623        1.1  pooka 
    624        1.1  pooka 			pcn.pcn_pkcnp = &auxt->pvnr_cn;
    625        1.7  pooka 			PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
    626        1.7  pooka 
    627        1.9  pooka 			memset(&pni, 0, sizeof(pni));
    628        1.9  pooka 			pni.pni_cookie = &auxt->pvnr_newnode;
    629        1.9  pooka 
    630        1.1  pooka 			if (buildpath) {
    631        1.1  pooka 				error = puffs_path_pcnbuild(pu, &pcn, opcookie);
    632        1.1  pooka 				if (error)
    633        1.1  pooka 					break;
    634        1.1  pooka 			}
    635        1.1  pooka 
    636       1.24  pooka 			error = pops->puffs_node_mkdir(pu,
    637        1.9  pooka 			    opcookie, &pni, &pcn, &auxt->pvnr_va);
    638        1.1  pooka 
    639        1.1  pooka 			if (buildpath) {
    640        1.1  pooka 				if (error) {
    641        1.1  pooka 					pu->pu_pathfree(pu, &pcn.pcn_po_full);
    642        1.1  pooka 				} else {
    643        1.1  pooka 					struct puffs_node *pn;
    644        1.1  pooka 
    645        1.1  pooka 					pn = PU_CMAP(pu, auxt->pvnr_newnode);
    646        1.1  pooka 					pn->pn_po = pcn.pcn_po_full;
    647        1.1  pooka 				}
    648        1.1  pooka 			}
    649        1.1  pooka 
    650        1.1  pooka 			break;
    651        1.1  pooka 		}
    652        1.1  pooka 
    653        1.1  pooka 		case PUFFS_VN_RMDIR:
    654        1.1  pooka 		{
    655       1.15  pooka 			struct puffs_vnmsg_rmdir *auxt = auxbuf;
    656        1.1  pooka 			struct puffs_cn pcn;
    657        1.1  pooka 			if (pops->puffs_node_rmdir == NULL) {
    658        1.1  pooka 				error = 0;
    659        1.1  pooka 				break;
    660        1.1  pooka 			}
    661        1.1  pooka 
    662        1.1  pooka 			pcn.pcn_pkcnp = &auxt->pvnr_cn;
    663        1.7  pooka 			PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
    664        1.1  pooka 
    665       1.24  pooka 			error = pops->puffs_node_rmdir(pu,
    666        1.1  pooka 			    opcookie, auxt->pvnr_cookie_targ, &pcn);
    667        1.1  pooka 			break;
    668        1.1  pooka 		}
    669        1.1  pooka 
    670        1.1  pooka 		case PUFFS_VN_SYMLINK:
    671        1.1  pooka 		{
    672       1.15  pooka 			struct puffs_vnmsg_symlink *auxt = auxbuf;
    673        1.9  pooka 			struct puffs_newinfo pni;
    674        1.1  pooka 			struct puffs_cn pcn;
    675        1.9  pooka 
    676        1.1  pooka 			if (pops->puffs_node_symlink == NULL) {
    677        1.1  pooka 				error = 0;
    678        1.1  pooka 				break;
    679        1.1  pooka 			}
    680        1.1  pooka 
    681        1.1  pooka 			pcn.pcn_pkcnp = &auxt->pvnr_cn;
    682        1.7  pooka 			PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
    683        1.7  pooka 
    684        1.9  pooka 			memset(&pni, 0, sizeof(pni));
    685        1.9  pooka 			pni.pni_cookie = &auxt->pvnr_newnode;
    686        1.9  pooka 
    687        1.1  pooka 			if (buildpath) {
    688        1.1  pooka 				error = puffs_path_pcnbuild(pu, &pcn, opcookie);
    689        1.1  pooka 				if (error)
    690        1.1  pooka 					break;
    691        1.1  pooka 			}
    692        1.1  pooka 
    693       1.24  pooka 			error = pops->puffs_node_symlink(pu,
    694        1.9  pooka 			    opcookie, &pni, &pcn,
    695        1.9  pooka 			    &auxt->pvnr_va, auxt->pvnr_link);
    696        1.1  pooka 
    697        1.1  pooka 			if (buildpath) {
    698        1.1  pooka 				if (error) {
    699        1.1  pooka 					pu->pu_pathfree(pu, &pcn.pcn_po_full);
    700        1.1  pooka 				} else {
    701        1.1  pooka 					struct puffs_node *pn;
    702        1.1  pooka 
    703        1.1  pooka 					pn = PU_CMAP(pu, auxt->pvnr_newnode);
    704        1.1  pooka 					pn->pn_po = pcn.pcn_po_full;
    705        1.1  pooka 				}
    706        1.1  pooka 			}
    707        1.1  pooka 
    708        1.1  pooka 			break;
    709        1.1  pooka 		}
    710        1.1  pooka 
    711        1.1  pooka 		case PUFFS_VN_READDIR:
    712        1.1  pooka 		{
    713       1.15  pooka 			struct puffs_vnmsg_readdir *auxt = auxbuf;
    714        1.7  pooka 			PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
    715        1.1  pooka 			struct dirent *dent;
    716        1.1  pooka 			off_t *cookies;
    717        1.1  pooka 			size_t res, origcookies;
    718        1.1  pooka 
    719        1.1  pooka 			if (pops->puffs_node_readdir == NULL) {
    720        1.1  pooka 				error = 0;
    721        1.1  pooka 				break;
    722        1.1  pooka 			}
    723        1.1  pooka 
    724        1.1  pooka 			if (auxt->pvnr_ncookies) {
    725        1.1  pooka 				/* LINTED: pvnr_data is __aligned() */
    726        1.1  pooka 				cookies = (off_t *)auxt->pvnr_data;
    727        1.1  pooka 				origcookies = auxt->pvnr_ncookies;
    728        1.1  pooka 			} else {
    729        1.1  pooka 				cookies = NULL;
    730        1.1  pooka 				origcookies = 0;
    731        1.1  pooka 			}
    732        1.1  pooka 			/* LINTED: dentoff is aligned in the kernel */
    733        1.1  pooka 			dent = (struct dirent *)
    734        1.1  pooka 			    (auxt->pvnr_data + auxt->pvnr_dentoff);
    735        1.1  pooka 
    736        1.1  pooka 			res = auxt->pvnr_resid;
    737       1.24  pooka 			error = pops->puffs_node_readdir(pu,
    738        1.1  pooka 			    opcookie, dent, &auxt->pvnr_offset,
    739        1.7  pooka 			    &auxt->pvnr_resid, pcr, &auxt->pvnr_eofflag,
    740        1.7  pooka 			    cookies, &auxt->pvnr_ncookies);
    741        1.1  pooka 
    742        1.1  pooka 			/* much easier to track non-working NFS */
    743        1.1  pooka 			assert(auxt->pvnr_ncookies <= origcookies);
    744        1.1  pooka 
    745        1.1  pooka 			/* need to move a bit more */
    746       1.15  pooka 			preq->preq_buflen = sizeof(struct puffs_vnmsg_readdir)
    747        1.1  pooka 			    + auxt->pvnr_dentoff + (res - auxt->pvnr_resid);
    748        1.1  pooka 			break;
    749        1.1  pooka 		}
    750        1.1  pooka 
    751        1.1  pooka 		case PUFFS_VN_READLINK:
    752        1.1  pooka 		{
    753       1.15  pooka 			struct puffs_vnmsg_readlink *auxt = auxbuf;
    754        1.7  pooka 			PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
    755        1.7  pooka 
    756        1.1  pooka 			if (pops->puffs_node_readlink == NULL) {
    757        1.1  pooka 				error = EOPNOTSUPP;
    758        1.1  pooka 				break;
    759        1.1  pooka 			}
    760        1.1  pooka 
    761        1.7  pooka 			/*LINTED*/
    762       1.24  pooka 			error = pops->puffs_node_readlink(pu, opcookie, pcr,
    763        1.1  pooka 			    auxt->pvnr_link, &auxt->pvnr_linklen);
    764        1.1  pooka 			break;
    765        1.1  pooka 		}
    766        1.1  pooka 
    767        1.1  pooka 		case PUFFS_VN_RECLAIM:
    768        1.1  pooka 		{
    769        1.8  pooka 
    770        1.1  pooka 			if (pops->puffs_node_reclaim == NULL) {
    771        1.1  pooka 				error = 0;
    772        1.1  pooka 				break;
    773        1.1  pooka 			}
    774        1.1  pooka 
    775       1.24  pooka 			error = pops->puffs_node_reclaim(pu, opcookie);
    776        1.1  pooka 			break;
    777        1.1  pooka 		}
    778        1.1  pooka 
    779        1.1  pooka 		case PUFFS_VN_INACTIVE:
    780        1.1  pooka 		{
    781        1.8  pooka 
    782        1.1  pooka 			if (pops->puffs_node_inactive == NULL) {
    783        1.1  pooka 				error = EOPNOTSUPP;
    784        1.1  pooka 				break;
    785        1.1  pooka 			}
    786        1.1  pooka 
    787       1.24  pooka 			error = pops->puffs_node_inactive(pu, opcookie);
    788        1.1  pooka 			break;
    789        1.1  pooka 		}
    790        1.1  pooka 
    791        1.1  pooka 		case PUFFS_VN_PATHCONF:
    792        1.1  pooka 		{
    793       1.15  pooka 			struct puffs_vnmsg_pathconf *auxt = auxbuf;
    794        1.1  pooka 			if (pops->puffs_node_pathconf == NULL) {
    795        1.1  pooka 				error = 0;
    796        1.1  pooka 				break;
    797        1.1  pooka 			}
    798        1.1  pooka 
    799       1.24  pooka 			error = pops->puffs_node_pathconf(pu,
    800        1.1  pooka 			    opcookie, auxt->pvnr_name,
    801        1.1  pooka 			    &auxt->pvnr_retval);
    802        1.1  pooka 			break;
    803        1.1  pooka 		}
    804        1.1  pooka 
    805        1.1  pooka 		case PUFFS_VN_ADVLOCK:
    806        1.1  pooka 		{
    807       1.15  pooka 			struct puffs_vnmsg_advlock *auxt = auxbuf;
    808        1.1  pooka 			if (pops->puffs_node_advlock == NULL) {
    809        1.1  pooka 				error = 0;
    810        1.1  pooka 				break;
    811        1.1  pooka 			}
    812        1.1  pooka 
    813       1.24  pooka 			error = pops->puffs_node_advlock(pu,
    814        1.1  pooka 			    opcookie, auxt->pvnr_id, auxt->pvnr_op,
    815        1.1  pooka 			    &auxt->pvnr_fl, auxt->pvnr_flags);
    816        1.1  pooka 			break;
    817        1.1  pooka 		}
    818        1.1  pooka 
    819        1.1  pooka 		case PUFFS_VN_PRINT:
    820        1.1  pooka 		{
    821        1.1  pooka 			if (pops->puffs_node_print == NULL) {
    822        1.1  pooka 				error = 0;
    823        1.1  pooka 				break;
    824        1.1  pooka 			}
    825        1.1  pooka 
    826       1.24  pooka 			error = pops->puffs_node_print(pu,
    827        1.1  pooka 			    opcookie);
    828        1.1  pooka 			break;
    829        1.1  pooka 		}
    830        1.1  pooka 
    831  1.32.10.1   matt 		case PUFFS_VN_ABORTOP:
    832  1.32.10.1   matt 		{
    833  1.32.10.1   matt 			struct puffs_vnmsg_abortop *auxt = auxbuf;
    834  1.32.10.1   matt 			struct puffs_cn pcn;
    835  1.32.10.1   matt 
    836  1.32.10.1   matt 			if (pops->puffs_node_abortop == NULL) {
    837  1.32.10.1   matt 				error = 0;
    838  1.32.10.1   matt 				break;
    839  1.32.10.1   matt 			}
    840  1.32.10.1   matt 
    841  1.32.10.1   matt 			pcn.pcn_pkcnp = &auxt->pvnr_cn;
    842  1.32.10.1   matt 			PUFFS_KCREDTOCRED(pcn.pcn_cred, &auxt->pvnr_cn_cred);
    843  1.32.10.1   matt 
    844  1.32.10.1   matt 			error = pops->puffs_node_abortop(pu, opcookie, &pcn);
    845  1.32.10.1   matt 
    846  1.32.10.1   matt 			break;
    847  1.32.10.1   matt 		}
    848  1.32.10.1   matt 
    849        1.1  pooka 		case PUFFS_VN_READ:
    850        1.1  pooka 		{
    851       1.15  pooka 			struct puffs_vnmsg_read *auxt = auxbuf;
    852        1.7  pooka 			PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
    853        1.1  pooka 			size_t res;
    854        1.1  pooka 
    855        1.1  pooka 			if (pops->puffs_node_read == NULL) {
    856        1.1  pooka 				error = EIO;
    857        1.1  pooka 				break;
    858        1.1  pooka 			}
    859        1.1  pooka 
    860        1.1  pooka 			res = auxt->pvnr_resid;
    861       1.24  pooka 			error = pops->puffs_node_read(pu,
    862        1.1  pooka 			    opcookie, auxt->pvnr_data,
    863        1.1  pooka 			    auxt->pvnr_offset, &auxt->pvnr_resid,
    864        1.7  pooka 			    pcr, auxt->pvnr_ioflag);
    865        1.1  pooka 
    866        1.1  pooka 			/* need to move a bit more */
    867       1.15  pooka 			preq->preq_buflen = sizeof(struct puffs_vnmsg_read)
    868        1.1  pooka 			    + (res - auxt->pvnr_resid);
    869        1.1  pooka 			break;
    870        1.1  pooka 		}
    871        1.1  pooka 
    872        1.1  pooka 		case PUFFS_VN_WRITE:
    873        1.1  pooka 		{
    874       1.15  pooka 			struct puffs_vnmsg_write *auxt = auxbuf;
    875        1.7  pooka 			PUFFS_MAKECRED(pcr, &auxt->pvnr_cred);
    876        1.1  pooka 
    877        1.1  pooka 			if (pops->puffs_node_write == NULL) {
    878        1.1  pooka 				error = EIO;
    879        1.1  pooka 				break;
    880        1.1  pooka 			}
    881        1.1  pooka 
    882       1.24  pooka 			error = pops->puffs_node_write(pu,
    883        1.1  pooka 			    opcookie, auxt->pvnr_data,
    884        1.1  pooka 			    auxt->pvnr_offset, &auxt->pvnr_resid,
    885        1.7  pooka 			    pcr, auxt->pvnr_ioflag);
    886        1.1  pooka 
    887        1.1  pooka 			/* don't need to move data back to the kernel */
    888       1.15  pooka 			preq->preq_buflen = sizeof(struct puffs_vnmsg_write);
    889        1.1  pooka 			break;
    890        1.1  pooka 		}
    891        1.1  pooka 
    892        1.4  pooka 		case PUFFS_VN_POLL:
    893        1.4  pooka 		{
    894       1.15  pooka 			struct puffs_vnmsg_poll *auxt = auxbuf;
    895        1.8  pooka 
    896        1.4  pooka 			if (pops->puffs_node_poll == NULL) {
    897        1.4  pooka 				error = 0;
    898        1.4  pooka 
    899        1.4  pooka 				/* emulate genfs_poll() */
    900        1.4  pooka 				auxt->pvnr_events &= (POLLIN | POLLOUT
    901        1.4  pooka 						    | POLLRDNORM | POLLWRNORM);
    902        1.4  pooka 
    903        1.4  pooka 				break;
    904        1.4  pooka 			}
    905        1.4  pooka 
    906       1.24  pooka 			error = pops->puffs_node_poll(pu,
    907       1.22  pooka 			    opcookie, &auxt->pvnr_events);
    908        1.4  pooka 			break;
    909        1.4  pooka 		}
    910        1.4  pooka 
    911        1.1  pooka 		default:
    912        1.1  pooka 			printf("inval op %d\n", preq->preq_optype);
    913        1.1  pooka 			error = EINVAL;
    914        1.1  pooka 			break;
    915        1.1  pooka 		}
    916       1.30  pooka 
    917  1.32.10.1   matt #if 0
    918  1.32.10.1   matt 	/* not issued by kernel currently */
    919       1.30  pooka 	} else if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_CACHE) {
    920       1.30  pooka 		struct puffs_cacheinfo *pci = (void *)preq;
    921       1.30  pooka 
    922       1.30  pooka 		if (pu->pu_ops.puffs_cache_write) {
    923       1.30  pooka 			pu->pu_ops.puffs_cache_write(pu, preq->preq_cookie,
    924       1.30  pooka 			    pci->pcache_nruns, pci->pcache_runs);
    925       1.30  pooka 		}
    926       1.30  pooka 		error = 0;
    927  1.32.10.1   matt #endif
    928       1.30  pooka 
    929       1.30  pooka 	} else if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_ERROR) {
    930       1.30  pooka 		struct puffs_error *perr = (void *)preq;
    931       1.30  pooka 
    932       1.30  pooka 		pu->pu_errnotify(pu, preq->preq_optype,
    933       1.30  pooka 		    perr->perr_error, perr->perr_str, preq->preq_cookie);
    934       1.30  pooka 		error = 0;
    935        1.1  pooka 	} else {
    936        1.1  pooka 		/*
    937       1.30  pooka 		 * I guess the kernel sees this one coming also
    938        1.1  pooka 		 */
    939        1.1  pooka 		error = EINVAL;
    940        1.1  pooka 	}
    941       1.31  pooka 
    942       1.31  pooka  out:
    943        1.1  pooka 	preq->preq_rv = error;
    944        1.1  pooka 
    945       1.18  pooka 	if (pu->pu_oppost)
    946       1.24  pooka 		pu->pu_oppost(pu);
    947       1.18  pooka 
    948       1.30  pooka 	pcc->pcc_flags |= PCC_DONE;
    949        1.1  pooka }
    950