Home | History | Annotate | Line # | Download | only in libpuffs
puffs.c revision 1.8
      1 /*	$NetBSD: puffs.c,v 1.8 2006/11/18 12:40:35 pooka Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2005, 2006  Antti Kantee.  All Rights Reserved.
      5  *
      6  * Development of this software was supported by the
      7  * Google Summer of Code program and the Ulla Tuominen Foundation.
      8  * The Google SoC project was mentored by Bill Studenmund.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. The name of the company nor the name of the author may be used to
     19  *    endorse or promote products derived from this software without specific
     20  *    prior written permission.
     21  *
     22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
     23  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     24  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     25  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     32  * SUCH DAMAGE.
     33  */
     34 
     35 #include <sys/cdefs.h>
     36 #if !defined(lint)
     37 __RCSID("$NetBSD: puffs.c,v 1.8 2006/11/18 12:40:35 pooka Exp $");
     38 #endif /* !lint */
     39 
     40 #include <sys/param.h>
     41 #include <sys/mount.h>
     42 
     43 #include <errno.h>
     44 #include <fcntl.h>
     45 #include <puffs.h>
     46 #include <puffsdump.h>
     47 #include <stdio.h>
     48 #include <stdlib.h>
     49 #include <string.h>
     50 #include <syslog.h>
     51 #include <unistd.h>
     52 
     53 static int puffcall(struct puffs_usermount *, struct puffs_req *);
     54 
     55 struct puffs_usermount *
     56 puffs_mount(struct puffs_vfsops *pvfs, struct puffs_vnops *pvn,
     57 	const char *dir, int mntflags, const char *puffsname,
     58 	uint32_t pflags, size_t maxreqlen)
     59 {
     60 	struct puffs_startreq sreq;
     61 	struct puffs_args pargs;
     62 	struct puffs_usermount *pu;
     63 	int fd = 0, rv;
     64 
     65 	if (pvfs->puffs_mount == NULL) {
     66 		errno = EINVAL;
     67 		return NULL;
     68 	}
     69 
     70 	fd = open("/dev/puffs", O_RDONLY);
     71 	if (fd == -1)
     72 		return NULL;
     73 
     74 	pargs.pa_vers = 0; /* XXX: for now */
     75 	pargs.pa_flags = PUFFSFLAG_KERN(pflags);
     76 	pargs.pa_fd = fd;
     77 	pargs.pa_maxreqlen = maxreqlen;
     78 	(void)strlcpy(pargs.pa_name, puffsname, sizeof(pargs.pa_name));
     79 
     80 	pu = malloc(sizeof(struct puffs_usermount));
     81 	if (!pu)
     82 		return NULL;
     83 
     84 	pu->pu_flags = pflags;
     85 	pu->pu_pvfs = *pvfs;
     86 	pu->pu_pvn = *pvn;
     87 	pu->pu_fd = fd;
     88 	if ((pu->pu_rootpath = strdup(dir)) == NULL)
     89 		goto failfree;
     90 	LIST_INIT(&pu->pu_pnodelst);
     91 
     92 	if (mount(MOUNT_PUFFS, dir, mntflags, &pargs) == -1)
     93 		goto failfree;
     94 	pu->pu_maxreqlen = pargs.pa_maxreqlen;
     95 
     96 	if ((rv = pu->pu_pvfs.puffs_mount(pu, &sreq.psr_cookie)) != 0) {
     97 		errno = rv;
     98 		goto failfree;
     99 	}
    100 
    101 	if ((rv = pu->pu_pvfs.puffs_statvfs(pu, &sreq.psr_sb, 0)) != 0) {
    102 		errno = rv;
    103 		goto failfree;
    104 	}
    105 
    106 	/* tell kernel we're flying */
    107 	if (ioctl(pu->pu_fd, PUFFSSTARTOP, &sreq) == -1)
    108 		goto failfree;
    109 
    110 	return pu;
    111 
    112  failfree:
    113 	/* can't unmount() from here for obvious reasons */
    114 	if (fd)
    115 		close(fd);
    116 	free(pu);
    117 	return NULL;
    118 }
    119 
    120 int
    121 puffs_mainloop(struct puffs_usermount *pu)
    122 {
    123 	uint8_t *buf;
    124 	int rv;
    125 
    126 	buf = malloc(pu->pu_maxreqlen);
    127 	if (!buf)
    128 		return -1;
    129 
    130 	for (;;)
    131 		if ((rv = puffs_oneop(pu, buf, pu->pu_maxreqlen)) != 0)
    132 			return rv;
    133 }
    134 
    135 int
    136 puffs_oneop(struct puffs_usermount *pu, uint8_t *buf, size_t buflen)
    137 {
    138 	struct puffs_req preq;
    139 	int rv;
    140 
    141 	preq.preq_aux = buf;
    142 	preq.preq_auxlen = buflen;
    143 
    144 	/* get op from kernel */
    145 	if (ioctl(pu->pu_fd, PUFFSGETOP, &preq) == -1)
    146 		return -1;
    147 
    148 	/* deal with it */
    149 	rv = puffcall(pu, &preq);
    150 
    151 	/* stuff result back to the kernel in case required */
    152 	if (PUFFSOP_WANTREPLY(preq.preq_opclass)) {
    153 		if (ioctl(pu->pu_fd, PUFFSPUTOP, &preq) == -1)
    154 			return -1;
    155 	}
    156 
    157 	return rv;
    158 }
    159 
    160 int
    161 puffs_getselectable(struct puffs_usermount *pu)
    162 {
    163 
    164 	return pu->pu_fd;
    165 }
    166 
    167 int
    168 puffs_setblockingmode(struct puffs_usermount *pu, int mode)
    169 {
    170 	int x;
    171 
    172 	x = mode;
    173 	return ioctl(pu->pu_fd, FIONBIO, &x);
    174 }
    175 
    176 static int
    177 puffcall(struct puffs_usermount *pu, struct puffs_req *preq)
    178 {
    179 	struct puffs_sizeop pop;
    180 	int error, rv;
    181 
    182 	rv = 0;
    183 
    184 	if (pu->pu_flags & PUFFSFLAG_OPDUMP)
    185 		puffsdump_req(preq);
    186 
    187 	if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VFS) {
    188 		switch (preq->preq_optype) {
    189 		case PUFFS_VFS_UNMOUNT:
    190 		{
    191 			struct puffs_vfsreq_unmount *auxt = preq->preq_aux;
    192 
    193 			error = pu->pu_pvfs.puffs_unmount(pu,
    194 			    auxt->pvfsr_flags, auxt->pvfsr_pid);
    195 			rv = 1;
    196 			break;
    197 		}
    198 		case PUFFS_VFS_STATVFS:
    199 		{
    200 			struct puffs_vfsreq_statvfs *auxt = preq->preq_aux;
    201 
    202 			error = pu->pu_pvfs.puffs_statvfs(pu,
    203 			    &auxt->pvfsr_sb, auxt->pvfsr_pid);
    204 			break;
    205 		}
    206 		case PUFFS_VFS_SYNC:
    207 		{
    208 			struct puffs_vfsreq_sync *auxt = preq->preq_aux;
    209 
    210 			error = pu->pu_pvfs.puffs_sync(pu,
    211 			    auxt->pvfsr_waitfor, &auxt->pvfsr_cred,
    212 			    auxt->pvfsr_pid);
    213 			break;
    214 		}
    215 		default:
    216 			/*
    217 			 * I guess the kernel sees this one coming
    218 			 */
    219 			error = EINVAL;
    220 			break;
    221 		}
    222 
    223 	/* XXX: audit return values */
    224 	} else if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VN) {
    225 		switch (preq->preq_optype) {
    226 		case PUFFS_VN_LOOKUP:
    227 		{
    228 			struct puffs_vnreq_lookup *auxt = preq->preq_aux;
    229 
    230 			/* lookup *must* be present */
    231 			error = pu->pu_pvn.puffs_lookup(pu, preq->preq_cookie,
    232 			    &auxt->pvnr_newnode, &auxt->pvnr_vtype,
    233 			    &auxt->pvnr_size, &auxt->pvnr_rdev,
    234 			    &auxt->pvnr_cn);
    235 			break;
    236 		}
    237 
    238 		case PUFFS_VN_CREATE:
    239 		{
    240 			struct puffs_vnreq_create *auxt = preq->preq_aux;
    241 			if (pu->pu_pvn.puffs_create == NULL) {
    242 				error = 0;
    243 				break;
    244 			}
    245 
    246 			error = pu->pu_pvn.puffs_create(pu,
    247 			    preq->preq_cookie, &auxt->pvnr_newnode,
    248 			    &auxt->pvnr_cn, &auxt->pvnr_va);
    249 			break;
    250 		}
    251 
    252 		case PUFFS_VN_MKNOD:
    253 		{
    254 			struct puffs_vnreq_mknod *auxt = preq->preq_aux;
    255 			if (pu->pu_pvn.puffs_mknod == NULL) {
    256 				error = 0;
    257 				break;
    258 			}
    259 
    260 			error = pu->pu_pvn.puffs_mknod(pu,
    261 			    preq->preq_cookie, &auxt->pvnr_newnode,
    262 			    &auxt->pvnr_cn, &auxt->pvnr_va);
    263 			break;
    264 		}
    265 
    266 		case PUFFS_VN_OPEN:
    267 		{
    268 			struct puffs_vnreq_open *auxt = preq->preq_aux;
    269 			if (pu->pu_pvn.puffs_open == NULL) {
    270 				error = 0;
    271 				break;
    272 			}
    273 
    274 			error = pu->pu_pvn.puffs_open(pu,
    275 			    preq->preq_cookie, auxt->pvnr_mode,
    276 			    &auxt->pvnr_cred, auxt->pvnr_pid);
    277 			break;
    278 		}
    279 
    280 		case PUFFS_VN_CLOSE:
    281 		{
    282 			struct puffs_vnreq_close *auxt = preq->preq_aux;
    283 			if (pu->pu_pvn.puffs_close == NULL) {
    284 				error = 0;
    285 				break;
    286 			}
    287 
    288 			error = pu->pu_pvn.puffs_close(pu,
    289 			    preq->preq_cookie, auxt->pvnr_fflag,
    290 			    &auxt->pvnr_cred, auxt->pvnr_pid);
    291 			break;
    292 		}
    293 
    294 		case PUFFS_VN_ACCESS:
    295 		{
    296 			struct puffs_vnreq_access *auxt = preq->preq_aux;
    297 			if (pu->pu_pvn.puffs_access == NULL) {
    298 				error = 0;
    299 				break;
    300 			}
    301 
    302 			error = pu->pu_pvn.puffs_access(pu,
    303 			    preq->preq_cookie, auxt->pvnr_mode,
    304 			    &auxt->pvnr_cred, auxt->pvnr_pid);
    305 			break;
    306 		}
    307 
    308 		case PUFFS_VN_GETATTR:
    309 		{
    310 			struct puffs_vnreq_getattr *auxt = preq->preq_aux;
    311 			if (pu->pu_pvn.puffs_getattr == NULL) {
    312 				error = 0;
    313 				break;
    314 			}
    315 
    316 			error = pu->pu_pvn.puffs_getattr(pu,
    317 			    preq->preq_cookie, &auxt->pvnr_va,
    318 			    &auxt->pvnr_cred, auxt->pvnr_pid);
    319 			break;
    320 		}
    321 
    322 		case PUFFS_VN_SETATTR:
    323 		{
    324 			struct puffs_vnreq_setattr *auxt = preq->preq_aux;
    325 			if (pu->pu_pvn.puffs_setattr == NULL) {
    326 				error = 0;
    327 				break;
    328 			}
    329 
    330 			error = pu->pu_pvn.puffs_setattr(pu,
    331 			    preq->preq_cookie, &auxt->pvnr_va,
    332 			    &auxt->pvnr_cred, auxt->pvnr_pid);
    333 			break;
    334 		}
    335 
    336 /* notyet */
    337 #if 0
    338 		case PUFFS_VN_POLL:
    339 		{
    340 			struct puffs_vnreq_poll *auxt = preq->preq_aux;
    341 			if (pu->pu_pvn.puffs_poll == NULL) {
    342 				error = 0;
    343 				break;
    344 			}
    345 
    346 			error = pu->pu_pvn.puffs_poll(pu,
    347 			    preq->preq_cookie, preq-);
    348 			break;
    349 		}
    350 
    351 		case PUFFS_VN_KQFILTER:
    352 		{
    353 			struct puffs_vnreq_kqfilter *auxt = preq->preq_aux;
    354 			if (pu->pu_pvn.puffs_kqfilter == NULL) {
    355 				error = 0;
    356 				break;
    357 			}
    358 
    359 			error = pu->pu_pvn.puffs_kqfilter(pu,
    360 			    preq->preq_cookie, );
    361 			break;
    362 		}
    363 
    364 		case PUFFS_VN_MMAP:
    365 		{
    366 			struct puffs_vnreq_mmap *auxt = preq->preq_aux;
    367 			if (pu->pu_pvn.puffs_mmap == NULL) {
    368 				error = 0;
    369 				break;
    370 			}
    371 
    372 			error = pu->pu_pvn.puffs_mmap(pu,
    373 			    preq->preq_cookie, );
    374 			break;
    375 		}
    376 #endif
    377 
    378 		case PUFFS_VN_REVOKE:
    379 		{
    380 			struct puffs_vnreq_revoke *auxt = preq->preq_aux;
    381 			if (pu->pu_pvn.puffs_revoke == NULL) {
    382 				error = 0;
    383 				break;
    384 			}
    385 
    386 			error = pu->pu_pvn.puffs_revoke(pu,
    387 			    preq->preq_cookie, auxt->pvnr_flags);
    388 			break;
    389 		}
    390 
    391 		case PUFFS_VN_FSYNC:
    392 		{
    393 			struct puffs_vnreq_fsync *auxt = preq->preq_aux;
    394 			if (pu->pu_pvn.puffs_fsync == NULL) {
    395 				error = 0;
    396 				break;
    397 			}
    398 
    399 			error = pu->pu_pvn.puffs_fsync(pu,
    400 			    preq->preq_cookie, &auxt->pvnr_cred,
    401 			    auxt->pvnr_flags, auxt->pvnr_offlo,
    402 			    auxt->pvnr_offhi, auxt->pvnr_pid);
    403 			break;
    404 		}
    405 
    406 		case PUFFS_VN_SEEK:
    407 		{
    408 			struct puffs_vnreq_seek *auxt = preq->preq_aux;
    409 			if (pu->pu_pvn.puffs_seek == NULL) {
    410 				error = 0;
    411 				break;
    412 			}
    413 
    414 			error = pu->pu_pvn.puffs_seek(pu,
    415 			    preq->preq_cookie, auxt->pvnr_oldoff,
    416 			    auxt->pvnr_newoff, &auxt->pvnr_cred);
    417 			break;
    418 		}
    419 
    420 		case PUFFS_VN_REMOVE:
    421 		{
    422 			struct puffs_vnreq_remove *auxt = preq->preq_aux;
    423 			if (pu->pu_pvn.puffs_remove == NULL) {
    424 				error = 0;
    425 				break;
    426 			}
    427 
    428 			error = pu->pu_pvn.puffs_remove(pu,
    429 			    preq->preq_cookie, auxt->pvnr_cookie_targ,
    430 			    &auxt->pvnr_cn);
    431 			break;
    432 		}
    433 
    434 		case PUFFS_VN_LINK:
    435 		{
    436 			struct puffs_vnreq_link *auxt = preq->preq_aux;
    437 			if (pu->pu_pvn.puffs_link == NULL) {
    438 				error = 0;
    439 				break;
    440 			}
    441 
    442 			error = pu->pu_pvn.puffs_link(pu,
    443 			    preq->preq_cookie, auxt->pvnr_cookie_targ,
    444 			    &auxt->pvnr_cn);
    445 			break;
    446 		}
    447 
    448 		case PUFFS_VN_RENAME:
    449 		{
    450 			struct puffs_vnreq_rename *auxt = preq->preq_aux;
    451 			if (pu->pu_pvn.puffs_rename == NULL) {
    452 				error = 0;
    453 				break;
    454 			}
    455 
    456 			error = pu->pu_pvn.puffs_rename(pu,
    457 			    preq->preq_cookie, auxt->pvnr_cookie_src,
    458 			    &auxt->pvnr_cn_src, auxt->pvnr_cookie_targdir,
    459 			    auxt->pvnr_cookie_targ, &auxt->pvnr_cn_targ);
    460 			break;
    461 		}
    462 
    463 		case PUFFS_VN_MKDIR:
    464 		{
    465 			struct puffs_vnreq_mkdir *auxt = preq->preq_aux;
    466 			if (pu->pu_pvn.puffs_mkdir == NULL) {
    467 				error = 0;
    468 				break;
    469 			}
    470 
    471 			error = pu->pu_pvn.puffs_mkdir(pu,
    472 			    preq->preq_cookie, &auxt->pvnr_newnode,
    473 			    &auxt->pvnr_cn, &auxt->pvnr_va);
    474 			break;
    475 		}
    476 
    477 		case PUFFS_VN_RMDIR:
    478 		{
    479 			struct puffs_vnreq_rmdir *auxt = preq->preq_aux;
    480 			if (pu->pu_pvn.puffs_rmdir == NULL) {
    481 				error = 0;
    482 				break;
    483 			}
    484 
    485 			error = pu->pu_pvn.puffs_rmdir(pu,
    486 			    preq->preq_cookie, auxt->pvnr_cookie_targ,
    487 			    &auxt->pvnr_cn);
    488 			break;
    489 		}
    490 
    491 		case PUFFS_VN_SYMLINK:
    492 		{
    493 			struct puffs_vnreq_symlink *auxt = preq->preq_aux;
    494 			if (pu->pu_pvn.puffs_symlink == NULL) {
    495 				error = 0;
    496 				break;
    497 			}
    498 
    499 			error = pu->pu_pvn.puffs_symlink(pu,
    500 			    preq->preq_cookie, &auxt->pvnr_newnode,
    501 			    &auxt->pvnr_cn, &auxt->pvnr_va, auxt->pvnr_link);
    502 			break;
    503 		}
    504 
    505 		case PUFFS_VN_READDIR:
    506 		{
    507 			struct puffs_vnreq_readdir *auxt = preq->preq_aux;
    508 			size_t res;
    509 
    510 			if (pu->pu_pvn.puffs_readdir == NULL) {
    511 				error = 0;
    512 				break;
    513 			}
    514 
    515 			res = auxt->pvnr_resid;
    516 			error = pu->pu_pvn.puffs_readdir(pu,
    517 			    preq->preq_cookie, auxt->pvnr_dent,
    518 			    &auxt->pvnr_cred, &auxt->pvnr_offset,
    519 			    &auxt->pvnr_resid);
    520 
    521 			/* need to move a bit more */
    522 			preq->preq_auxlen += res - auxt->pvnr_resid;
    523 			break;
    524 		}
    525 
    526 		case PUFFS_VN_READLINK:
    527 		{
    528 			struct puffs_vnreq_readlink *auxt = preq->preq_aux;
    529 			if (pu->pu_pvn.puffs_readlink == NULL) {
    530 				error = EOPNOTSUPP;
    531 				break;
    532 			}
    533 
    534 			error = pu->pu_pvn.puffs_readlink(pu,
    535 			    preq->preq_cookie, &auxt->pvnr_cred,
    536 			    auxt->pvnr_link, &auxt->pvnr_linklen);
    537 			break;
    538 		}
    539 
    540 		case PUFFS_VN_RECLAIM:
    541 		{
    542 			struct puffs_vnreq_reclaim *auxt = preq->preq_aux;
    543 			if (pu->pu_pvn.puffs_reclaim == NULL) {
    544 				error = 0;
    545 				break;
    546 			}
    547 
    548 			error = pu->pu_pvn.puffs_reclaim(pu,
    549 			    preq->preq_cookie, auxt->pvnr_pid);
    550 			break;
    551 		}
    552 
    553 		case PUFFS_VN_INACTIVE:
    554 		{
    555 			struct puffs_vnreq_inactive *auxt = preq->preq_aux;
    556 			if (pu->pu_pvn.puffs_inactive == NULL) {
    557 				error = EOPNOTSUPP;
    558 				break;
    559 			}
    560 
    561 			error = pu->pu_pvn.puffs_inactive(pu,
    562 			    preq->preq_cookie, auxt->pvnr_pid,
    563 			    &auxt->pvnr_backendrefs);
    564 			break;
    565 		}
    566 
    567 		case PUFFS_VN_PATHCONF:
    568 		{
    569 			struct puffs_vnreq_pathconf *auxt = preq->preq_aux;
    570 			if (pu->pu_pvn.puffs_pathconf == NULL) {
    571 				error = 0;
    572 				break;
    573 			}
    574 
    575 			error = pu->pu_pvn.puffs_pathconf(pu,
    576 			    preq->preq_cookie, auxt->pvnr_name,
    577 			    &auxt->pvnr_retval);
    578 			break;
    579 		}
    580 
    581 		case PUFFS_VN_ADVLOCK:
    582 		{
    583 			struct puffs_vnreq_advlock *auxt = preq->preq_aux;
    584 			if (pu->pu_pvn.puffs_advlock == NULL) {
    585 				error = 0;
    586 				break;
    587 			}
    588 
    589 			error = pu->pu_pvn.puffs_advlock(pu,
    590 			    preq->preq_cookie, auxt->pvnr_id, auxt->pvnr_op,
    591 			    &auxt->pvnr_fl, auxt->pvnr_flags);
    592 			break;
    593 		}
    594 
    595 		case PUFFS_VN_PRINT:
    596 		{
    597 			if (pu->pu_pvn.puffs_print == NULL) {
    598 				error = 0;
    599 				break;
    600 			}
    601 
    602 			error = pu->pu_pvn.puffs_print(pu,
    603 			    preq->preq_cookie);
    604 			break;
    605 		}
    606 
    607 		case PUFFS_VN_READ:
    608 		{
    609 			struct puffs_vnreq_read *auxt = preq->preq_aux;
    610 			size_t res;
    611 
    612 			if (pu->pu_pvn.puffs_read == NULL) {
    613 				error = EIO;
    614 				break;
    615 			}
    616 
    617 			res = auxt->pvnr_resid;
    618 			error = pu->pu_pvn.puffs_read(pu,
    619 			    preq->preq_cookie, auxt->pvnr_data,
    620 			    auxt->pvnr_offset, &auxt->pvnr_resid,
    621 			    &auxt->pvnr_cred, auxt->pvnr_ioflag);
    622 
    623 			/* need to move a bit more */
    624 			preq->preq_auxlen += res - auxt->pvnr_resid;
    625 			break;
    626 		}
    627 
    628 		case PUFFS_VN_WRITE:
    629 		{
    630 			struct puffs_vnreq_write *auxt = preq->preq_aux;
    631 
    632 			if (pu->pu_pvn.puffs_write == NULL) {
    633 				error = EIO;
    634 				break;
    635 			}
    636 
    637 			error = pu->pu_pvn.puffs_write(pu,
    638 			    preq->preq_cookie, auxt->pvnr_data,
    639 			    auxt->pvnr_offset, &auxt->pvnr_resid,
    640 			    &auxt->pvnr_cred, auxt->pvnr_ioflag);
    641 
    642 			/* don't need to move data back to the kernel */
    643 			preq->preq_auxlen = sizeof(struct puffs_vnreq_write);
    644 			break;
    645 		}
    646 
    647 		case PUFFS_VN_IOCTL:
    648 			error = pu->pu_pvn.puffs_ioctl1(pu, preq->preq_cookie,
    649 			     (struct puffs_vnreq_ioctl *)preq->preq_aux, &pop);
    650 			if (error != 0)
    651 				break;
    652 			pop.pso_reqid = preq->preq_id;
    653 
    654 			/* let the kernel do it's intermediate duty */
    655 			error = ioctl(pu->pu_fd, PUFFSSIZEOP, &pop);
    656 			/*
    657 			 * XXX: I don't actually know what the correct
    658 			 * thing to do in case of an error is, so I'll
    659 			 * just ignore it for the time being.
    660 			 */
    661 			error = pu->pu_pvn.puffs_ioctl2(pu, preq->preq_cookie,
    662 			    (struct puffs_vnreq_ioctl *)preq->preq_aux, &pop);
    663 			break;
    664 
    665 		case PUFFS_VN_FCNTL:
    666 			error = pu->pu_pvn.puffs_fcntl1(pu, preq->preq_cookie,
    667 			     (struct puffs_vnreq_fcntl *)preq->preq_aux, &pop);
    668 			if (error != 0)
    669 				break;
    670 			pop.pso_reqid = preq->preq_id;
    671 
    672 			/* let the kernel do it's intermediate duty */
    673 			error = ioctl(pu->pu_fd, PUFFSSIZEOP, &pop);
    674 			/*
    675 			 * XXX: I don't actually know what the correct
    676 			 * thing to do in case of an error is, so I'll
    677 			 * just ignore it for the time being.
    678 			 */
    679 			error = pu->pu_pvn.puffs_fcntl2(pu, preq->preq_cookie,
    680 			    (struct puffs_vnreq_fcntl *)preq->preq_aux, &pop);
    681 			break;
    682 
    683 		default:
    684 			printf("inval op %d\n", preq->preq_optype);
    685 			error = EINVAL;
    686 			break;
    687 		}
    688 	} else {
    689 		/*
    690 		 * this one also
    691 		 */
    692 		error = EINVAL;
    693 	}
    694 
    695 	preq->preq_rv = error;
    696 	return rv;
    697 }
    698 
    699 
    700 #if 0
    701 		case PUFFS_VN_IOCTL:
    702 		{
    703 			struct puffs_vnreq_ioctl *auxt = preq->preq_aux;
    704 			if (pu->pu_pvn.puffs_ioctl == NULL) {
    705 				error = 0;
    706 				break;
    707 			}
    708 
    709 			error = pu->pu_pvn.puffs_ioctl(pu,
    710 			    preq->preq_cookie, );
    711 			break;
    712 		}
    713 
    714 		case PUFFS_VN_FCNTL:
    715 		{
    716 			struct puffs_vnreq_fcntl *auxt = preq->preq_aux;
    717 			if (pu->pu_pvn.puffs_fcntl == NULL) {
    718 				error = 0;
    719 				break;
    720 			}
    721 
    722 			error = pu->pu_pvn.puffs_fcntl(pu,
    723 			    preq->preq_cookie, );
    724 			break;
    725 		}
    726 
    727 
    728 		case PUFFS_VN_ABORTOP:
    729 		{
    730 			struct puffs_vnreq_abortop *auxt = preq->preq_aux;
    731 			if (pu->pu_pvn.puffs_abortop == NULL) {
    732 				error = 0;
    733 				break;
    734 			}
    735 
    736 			error = pu->pu_pvn.puffs_abortop(pu,
    737 			    preq->preq_cookie, );
    738 			break;
    739 		}
    740 
    741 		case PUFFS_VN_LOCK:
    742 		{
    743 			struct puffs_vnreq_lock *auxt = preq->preq_aux;
    744 			if (pu->pu_pvn.puffs_lock == NULL) {
    745 				error = 0;
    746 				break;
    747 			}
    748 
    749 			error = pu->pu_pvn.puffs_lock(pu,
    750 			    preq->preq_cookie, );
    751 			break;
    752 		}
    753 
    754 		case PUFFS_VN_UNLOCK:
    755 		{
    756 			struct puffs_vnreq_unlock *auxt = preq->preq_aux;
    757 			if (pu->pu_pvn.puffs_unlock == NULL) {
    758 				error = 0;
    759 				break;
    760 			}
    761 
    762 			error = pu->pu_pvn.puffs_unlock(pu,
    763 			    preq->preq_cookie, );
    764 			break;
    765 		}
    766 
    767 		case PUFFS_VN_ISLOCKED:
    768 		{
    769 			struct puffs_vnreq_islocked *auxt = preq->preq_aux;
    770 			if (pu->pu_pvn.puffs_islocked == NULL) {
    771 				error = 0;
    772 				break;
    773 			}
    774 
    775 			error = pu->pu_pvn.puffs_islocked(pu,
    776 			    preq->preq_cookie, );
    777 			break;
    778 		}
    779 
    780 		case PUFFS_VN_LEASE:
    781 		{
    782 			struct puffs_vnreq_lease *auxt = preq->preq_aux;
    783 			if (pu->pu_pvn.puffs_lease == NULL) {
    784 				error = 0;
    785 				break;
    786 			}
    787 
    788 			error = pu->pu_pvn.puffs_lease(pu,
    789 			    preq->preq_cookie, );
    790 			break;
    791 		}
    792 
    793 		case PUFFS_VN_WHITEOUT:
    794 		{
    795 			struct puffs_vnreq_whiteout *auxt = preq->preq_aux;
    796 			if (pu->pu_pvn.puffs_whiteout == NULL) {
    797 				error = 0;
    798 				break;
    799 			}
    800 
    801 			error = pu->pu_pvn.puffs_whiteout(pu,
    802 			    preq->preq_cookie, );
    803 			break;
    804 		}
    805 
    806 		case PUFFS_VN_CLOSEEXTATTR:
    807 		{
    808 			struct puffs_vnreq_closeextattr *auxt = preq->preq_aux;
    809 			if (pu->pu_pvn.puffs_closeextattr == NULL) {
    810 				error = 0;
    811 				break;
    812 			}
    813 
    814 			error = pu->pu_pvn.puffs_closeextattr(pu,
    815 			    preq->preq_cookie, );
    816 			break;
    817 		}
    818 
    819 		case PUFFS_VN_GETEXTATTR:
    820 		{
    821 			struct puffs_vnreq_getextattr *auxt = preq->preq_aux;
    822 			if (pu->pu_pvn.puffs_getextattr == NULL) {
    823 				error = 0;
    824 				break;
    825 			}
    826 
    827 			error = pu->pu_pvn.puffs_getextattr(pu,
    828 			    preq->preq_cookie, );
    829 			break;
    830 		}
    831 
    832 		case PUFFS_VN_LISTEXTATTR:
    833 		{
    834 			struct puffs_vnreq_listextattr *auxt = preq->preq_aux;
    835 			if (pu->pu_pvn.puffs_listextattr == NULL) {
    836 				error = 0;
    837 				break;
    838 			}
    839 
    840 			error = pu->pu_pvn.puffs_listextattr(pu,
    841 			    preq->preq_cookie, );
    842 			break;
    843 		}
    844 
    845 		case PUFFS_VN_OPENEXTATTR:
    846 		{
    847 			struct puffs_vnreq_openextattr *auxt = preq->preq_aux;
    848 			if (pu->pu_pvn.puffs_openextattr == NULL) {
    849 				error = 0;
    850 				break;
    851 			}
    852 
    853 			error = pu->pu_pvn.puffs_openextattr(pu,
    854 			    preq->preq_cookie, );
    855 			break;
    856 		}
    857 
    858 		case PUFFS_VN_DELETEEXTATTR:
    859 		{
    860 			struct puffs_vnreq_deleteextattr *auxt = preq->preq_aux;
    861 			if (pu->pu_pvn.puffs_deleteextattr == NULL) {
    862 				error = 0;
    863 				break;
    864 			}
    865 
    866 			error = pu->pu_pvn.puffs_deleteextattr(pu,
    867 			    preq->preq_cookie, );
    868 			break;
    869 		}
    870 
    871 		case PUFFS_VN_SETEXTATTR:
    872 		{
    873 			struct puffs_vnreq_setextattr *auxt = preq->preq_aux;
    874 			if (pu->pu_pvn.puffs_setextattr == NULL) {
    875 				error = 0;
    876 				break;
    877 			}
    878 
    879 			error = pu->pu_pvn.puffs_setextattr(pu,
    880 			    preq->preq_cookie, );
    881 			break;
    882 		}
    883 
    884 #endif
    885