Home | History | Annotate | Line # | Download | only in libpuffs
      1 /*	$NetBSD: opdump.c,v 1.38 2021/03/08 17:34:10 christos 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  *
     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
     29  * SUCH DAMAGE.
     30  */
     31 
     32 /* Pretty-printing helper routines for VFS/VOP request contents */
     33 
     34 /* yes, this is pretty much a mess */
     35 
     36 #include <sys/cdefs.h>
     37 #if !defined(lint)
     38 __RCSID("$NetBSD: opdump.c,v 1.38 2021/03/08 17:34:10 christos Exp $");
     39 #endif /* !lint */
     40 
     41 #include <sys/types.h>
     42 #include <sys/time.h>
     43 
     44 #include <puffs.h>
     45 #include <puffsdump.h>
     46 #include <stdarg.h>
     47 #include <stdio.h>
     48 
     49 #include "puffs_priv.h"
     50 
     51 #define DINT "    "
     52 
     53 const char *puffsdump_vfsop_revmap[] = {
     54 	"PUFFS_VFS_MOUNT",
     55 	"PUFFS_VFS_START",
     56 	"PUFFS_VFS_UNMOUNT",
     57 	"PUFFS_VFS_ROOT",
     58 	"PUFFS_VFS_QUOTACTL",
     59 	"PUFFS_VFS_STATVFS",
     60 	"PUFFS_VFS_SYNC",
     61 	"PUFFS_VFS_VGET",
     62 	"PUFFS_VFS_FHTOVP",
     63 	"PUFFS_VFS_VPTOFH",
     64 	"PUFFS_VFS_INIT",
     65 	"PUFFS_VFS_DONE",
     66 	"PUFFS_VFS_SNAPSHOT",
     67 	"PUFFS_VFS_EXTATTRCTL",
     68 	"PUFFS_VFS_SUSPEND"
     69 };
     70 size_t puffsdump_vfsop_count = __arraycount(puffsdump_vfsop_revmap);
     71 
     72 const char *puffsdump_vnop_revmap[] = {
     73 	"PUFFS_VN_LOOKUP",
     74 	"PUFFS_VN_CREATE",
     75 	"PUFFS_VN_MKNOD",
     76 	"PUFFS_VN_OPEN",
     77 	"PUFFS_VN_CLOSE",
     78 	"PUFFS_VN_ACCESS",
     79 	"PUFFS_VN_GETATTR",
     80 	"PUFFS_VN_SETATTR",
     81 	"PUFFS_VN_READ",
     82 	"PUFFS_VN_WRITE",
     83 	"PUFFS_VN_IOCTL",
     84 	"PUFFS_VN_FCNTL",
     85 	"PUFFS_VN_POLL",
     86 	"PUFFS_VN_KQFILTER",
     87 	"PUFFS_VN_REVOKE",
     88 	"PUFFS_VN_MMAP",
     89 	"PUFFS_VN_FSYNC",
     90 	"PUFFS_VN_SEEK",
     91 	"PUFFS_VN_REMOVE",
     92 	"PUFFS_VN_LINK",
     93 	"PUFFS_VN_RENAME",
     94 	"PUFFS_VN_MKDIR",
     95 	"PUFFS_VN_RMDIR",
     96 	"PUFFS_VN_SYMLINK",
     97 	"PUFFS_VN_READDIR",
     98 	"PUFFS_VN_READLINK",
     99 	"PUFFS_VN_ABORTOP",
    100 	"PUFFS_VN_INACTIVE",
    101 	"PUFFS_VN_RECLAIM",
    102 	"PUFFS_VN_LOCK",
    103 	"PUFFS_VN_UNLOCK",
    104 	"PUFFS_VN_BMAP",
    105 	"PUFFS_VN_STRATEGY",
    106 	"PUFFS_VN_PRINT",
    107 	"PUFFS_VN_ISLOCKED",
    108 	"PUFFS_VN_PATHCONF",
    109 	"PUFFS_VN_ADVLOCK",
    110 	"PUFFS_VN_LEASE",
    111 	"PUFFS_VN_WHITEOUT",
    112 	"PUFFS_VN_GETPAGES",
    113 	"PUFFS_VN_PUTPAGES",
    114 	"PUFFS_VN_GETEXTATTR",
    115 	"PUFFS_VN_LISTEXTATTR",
    116 	"PUFFS_VN_OPENEXTATTR",
    117 	"PUFFS_VN_DELETEEXTATTR",
    118 	"PUFFS_VN_SETEXTATTR",
    119 	"PUFFS_VN_CLOSEEXTATTR",
    120 	"PUFFS_VN_FALLOCATE",
    121 	"PUFFS_VN_FDISCARD",
    122 };
    123 size_t puffsdump_vnop_count = __arraycount(puffsdump_vnop_revmap);
    124 
    125 /* XXX! */
    126 const char *puffsdump_cacheop_revmap[] = {
    127 	"PUFFS_CACHE_WRITE"
    128 };
    129 
    130 const char *puffsdump_errnot_revmap[] = {
    131 	"PUFFS_ERR_ERROR",
    132 	"PUFFS_ERR_MAKENODE",
    133 	"PUFFS_ERR_LOOKUP",
    134 	"PUFFS_ERR_READDIR",
    135 	"PUFFS_ERR_READLINK",
    136 	"PUFFS_ERR_READ",
    137 	"PUFFS_ERR_WRITE",
    138 	"PUFFS_ERR_VPTOFH",
    139 	"PUFFS_ERR_GETEXTATTR",
    140 	"PUFFS_ERR_LISTEXTATTR",
    141 };
    142 size_t puffsdump_errnot_count = __arraycount(puffsdump_errnot_revmap);
    143 
    144 const char *puffsdump_flush_revmap[] = {
    145 	"PUFFS_INVAL_NAMECACHE_NODE",
    146 	"PUFFS_INVAL_NAMECACHE_DIR",
    147 	"PUFFS_INVAL_NAMECACHE_ALL",
    148 	"PUFFS_INVAL_PAGECACHE_NODE_RANGE",
    149 	"PUFFS_FLUSH_PAGECACHE_NODE_RANGE",
    150 };
    151 size_t puffsdump_flush_count = __arraycount(puffsdump_flush_revmap);
    152 
    153 static __printflike(1, 2) void
    154 mydprintf(const char *fmt, ...)
    155 {
    156 	va_list ap;
    157 
    158 	va_start(ap, fmt);
    159 	vfprintf(stderr, fmt, ap);
    160 	va_end(ap);
    161 }
    162 
    163 void
    164 puffsdump_req(struct puffs_req *preq)
    165 {
    166 	char buf[128];
    167 	static struct timeval tv_prev;
    168 	struct timeval tv_now, tv;
    169 	const char **map;
    170 	const char *optype;
    171 	size_t maxhandle;
    172 	int opclass, isvn = 0;
    173 
    174 	mydprintf("reqid: %" PRIu64 ", ", preq->preq_id);
    175 	opclass = PUFFSOP_OPCLASS(preq->preq_opclass);
    176 	switch (opclass) {
    177 	case PUFFSOP_VFS:
    178 		map = puffsdump_vfsop_revmap;
    179 		maxhandle = puffsdump_vfsop_count;
    180 		break;
    181 	case PUFFSOP_VN:
    182 		map = puffsdump_vnop_revmap;
    183 		maxhandle = puffsdump_vnop_count;
    184 		isvn = 1;
    185 		break;
    186 	case PUFFSOP_CACHE:
    187 		map = puffsdump_cacheop_revmap;
    188 		maxhandle = __arraycount(puffsdump_cacheop_revmap);
    189 		break;
    190 	case PUFFSOP_ERROR:
    191 		map = puffsdump_errnot_revmap;
    192 		maxhandle = puffsdump_errnot_count;
    193 		break;
    194 	case PUFFSOP_FLUSH:
    195 		map = puffsdump_flush_revmap;
    196 		maxhandle = puffsdump_flush_count;
    197 		break;
    198 	default:
    199 		mydprintf("unhandled opclass %d\n", opclass);
    200 		return;
    201 	}
    202 
    203 	if (preq->preq_optype < maxhandle) {
    204 		optype = map[preq->preq_optype];
    205 	} else {
    206 		snprintf(buf, sizeof(buf), "UNKNOWN (%d)", preq->preq_optype);
    207 		optype = buf;
    208 	}
    209 
    210 	mydprintf("opclass %d%s, optype: %s, "
    211 	    "cookie: %p,\n" DINT "aux: %p, auxlen: %zu, pid: %d, lwpid: %d\n",
    212 	    opclass, PUFFSOP_WANTREPLY(preq->preq_opclass) ? "" : " (FAF)",
    213 	    optype, preq->preq_cookie,
    214 	    preq->preq_buf, preq->preq_buflen,
    215 	    preq->preq_pid, preq->preq_lid);
    216 
    217 	if (isvn) {
    218 		switch ((enum puffs_vn)preq->preq_optype) {
    219 		case PUFFS_VN_LOOKUP:
    220 			puffsdump_lookup(preq);
    221 			break;
    222 		case PUFFS_VN_READ:
    223 		case PUFFS_VN_WRITE:
    224 			puffsdump_readwrite(preq);
    225 			break;
    226 		case PUFFS_VN_OPEN:
    227 			puffsdump_open(preq);
    228 			break;
    229 		case PUFFS_VN_REMOVE:
    230 		case PUFFS_VN_RMDIR:
    231 		case PUFFS_VN_LINK:
    232 			puffsdump_targ(preq);
    233 			break;
    234 		case PUFFS_VN_READDIR:
    235 			puffsdump_readdir(preq);
    236 			break;
    237 		case PUFFS_VN_CREATE:
    238 		case PUFFS_VN_MKDIR:
    239 		case PUFFS_VN_MKNOD:
    240 		case PUFFS_VN_SYMLINK:
    241 			puffsdump_create(preq);
    242 			break;
    243 		case PUFFS_VN_SETATTR:
    244 			puffsdump_attr(preq);
    245 			break;
    246 		default:
    247 			break;
    248 		}
    249 	}
    250 
    251 	PU_LOCK();
    252 	gettimeofday(&tv_now, NULL);
    253 	timersub(&tv_now, &tv_prev, &tv);
    254 	mydprintf(DINT "since previous call: %lld.%06ld\n",
    255 	    (long long)tv.tv_sec, (long)tv.tv_usec);
    256 	gettimeofday(&tv_prev, NULL);
    257 	PU_UNLOCK();
    258 }
    259 
    260 void
    261 puffsdump_rv(struct puffs_req *preq)
    262 {
    263 
    264 	if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VN) {
    265 		switch ((enum puffs_vn)preq->preq_optype) {
    266 		case PUFFS_VN_LOOKUP:
    267 			puffsdump_lookup_rv(preq);
    268 			break;
    269 		case PUFFS_VN_CREATE:
    270 		case PUFFS_VN_MKDIR:
    271 		case PUFFS_VN_MKNOD:
    272 		case PUFFS_VN_SYMLINK:
    273 			puffsdump_create_rv(preq);
    274 			break;
    275 		case PUFFS_VN_READ:
    276 		case PUFFS_VN_WRITE:
    277 			puffsdump_readwrite_rv(preq);
    278 			break;
    279 		case PUFFS_VN_READDIR:
    280 			puffsdump_readdir_rv(preq);
    281 			break;
    282 		case PUFFS_VN_GETATTR:
    283 			puffsdump_attr(preq);
    284 			break;
    285 		default:
    286 			break;
    287 		}
    288 	}
    289 
    290 	mydprintf("RV reqid: %" PRIu64 ", result: %d %s\n",
    291 	    preq->preq_id, preq->preq_rv,
    292 	    preq->preq_rv ? strerror(preq->preq_rv) : "");
    293 }
    294 
    295 /*
    296  * Slightly tedious print-routine so that we get a nice NOVAL instead
    297  * of some tedious output representations for -1, especially (uint64_t)-1
    298  *
    299  * We use typecasting to make this work beyond time_t/dev_t size changes.
    300  */
    301 static void
    302 dumpattr(struct vattr *vap)
    303 {
    304 	const char * const vtypes[] = { VNODE_TYPES };
    305 	char buf[128];
    306 
    307 /* XXX: better readability.  and this is debug, so no cycle-sweat */
    308 #define DEFAULTBUF() snprintf(buf, sizeof(buf), "NOVAL")
    309 
    310 	mydprintf(DINT "vattr:\n");
    311 	mydprintf(DINT DINT "type: %s, ", vtypes[vap->va_type]);
    312 
    313 	DEFAULTBUF();
    314 	if (vap->va_mode != (mode_t)PUFFS_VNOVAL)
    315 		snprintf(buf, sizeof(buf), "0%o", vap->va_mode);
    316 	mydprintf("mode: %s, ", buf);
    317 
    318 	DEFAULTBUF();
    319 	if (vap->va_nlink != (nlink_t)PUFFS_VNOVAL)
    320 		snprintf(buf, sizeof(buf), "%d", vap->va_nlink);
    321 	mydprintf("nlink: %s, ", buf);
    322 
    323 	DEFAULTBUF();
    324 	if (vap->va_uid != (uid_t)PUFFS_VNOVAL)
    325 		snprintf(buf, sizeof(buf), "%d", vap->va_uid);
    326 	mydprintf("uid: %s, ", buf);
    327 
    328 	DEFAULTBUF();
    329 	if (vap->va_gid != (gid_t)PUFFS_VNOVAL)
    330 		snprintf(buf, sizeof(buf), "%d", vap->va_gid);
    331 	mydprintf("gid: %s\n", buf);
    332 
    333 	DEFAULTBUF();
    334 	if ((unsigned long long)vap->va_fsid!=(unsigned long long)PUFFS_VNOVAL)
    335 		snprintf(buf, sizeof(buf), "0x%llx",
    336 		    (unsigned long long)vap->va_fsid);
    337 	mydprintf(DINT DINT "fsid: %s, ", buf);
    338 
    339 	DEFAULTBUF();
    340 	if (vap->va_fileid != (ino_t)PUFFS_VNOVAL)
    341 		snprintf(buf, sizeof(buf), "%" PRIu64, vap->va_fileid);
    342 	mydprintf("ino: %s, ", buf);
    343 
    344 	DEFAULTBUF();
    345 	if (vap->va_size != (u_quad_t)PUFFS_VNOVAL)
    346 		snprintf(buf, sizeof(buf), "%" PRIu64, vap->va_size);
    347 	mydprintf("size: %s, ", buf);
    348 
    349 	DEFAULTBUF();
    350 	if (vap->va_blocksize != (long)PUFFS_VNOVAL)
    351 		snprintf(buf, sizeof(buf), "%ld", vap->va_blocksize);
    352 	mydprintf("bsize: %s\n", buf);
    353 
    354 	DEFAULTBUF();
    355 	if (vap->va_atime.tv_sec != (time_t)PUFFS_VNOVAL)
    356 		snprintf(buf, sizeof(buf), "%lld",
    357 		    (long long)vap->va_atime.tv_sec);
    358 	mydprintf(DINT DINT "a.s: %s, ", buf);
    359 
    360 	DEFAULTBUF();
    361 	if (vap->va_atime.tv_nsec != (long)PUFFS_VNOVAL)
    362 		snprintf(buf, sizeof(buf), "%ld", vap->va_atime.tv_nsec);
    363 	mydprintf("a.ns: %s, ", buf);
    364 
    365 	DEFAULTBUF();
    366 	if (vap->va_mtime.tv_sec != (time_t)PUFFS_VNOVAL)
    367 		snprintf(buf, sizeof(buf), "%lld",
    368 		    (long long)vap->va_mtime.tv_sec);
    369 	mydprintf("m.s: %s, ", buf);
    370 
    371 	DEFAULTBUF();
    372 	if (vap->va_mtime.tv_nsec != (long)PUFFS_VNOVAL)
    373 		snprintf(buf, sizeof(buf), "%ld", vap->va_mtime.tv_nsec);
    374 	mydprintf("m.ns: %s\n", buf);
    375 
    376 	DEFAULTBUF();
    377 	if (vap->va_ctime.tv_sec != (time_t)PUFFS_VNOVAL)
    378 		snprintf(buf, sizeof(buf), "%lld",
    379 		    (long long)vap->va_ctime.tv_sec);
    380 	mydprintf(DINT DINT "c.s: %s, ", buf);
    381 
    382 	DEFAULTBUF();
    383 	if (vap->va_ctime.tv_nsec != (long)PUFFS_VNOVAL)
    384 		snprintf(buf, sizeof(buf), "%ld", vap->va_ctime.tv_nsec);
    385 	mydprintf("c.ns: %s, ", buf);
    386 
    387 	DEFAULTBUF();
    388 	if (vap->va_birthtime.tv_sec != (time_t)PUFFS_VNOVAL)
    389 		snprintf(buf, sizeof(buf), "%lld",
    390 		    (long long)vap->va_birthtime.tv_sec);
    391 	mydprintf("b.s: %s, ", buf);
    392 
    393 	DEFAULTBUF();
    394 	if (vap->va_birthtime.tv_nsec != (long)PUFFS_VNOVAL)
    395 		snprintf(buf, sizeof(buf), "%ld", vap->va_birthtime.tv_nsec);
    396 	mydprintf("b.ns: %s\n", buf);
    397 
    398 	DEFAULTBUF();
    399 	if (vap->va_gen != (u_long)PUFFS_VNOVAL)
    400 		snprintf(buf, sizeof(buf), "%lu", vap->va_gen);
    401 	mydprintf(DINT DINT "gen: %s, ", buf);
    402 
    403 	DEFAULTBUF();
    404 	if (vap->va_flags != (u_long)PUFFS_VNOVAL)
    405 		snprintf(buf, sizeof(buf), "0x%lx", vap->va_flags);
    406 	mydprintf("flags: %s, ", buf);
    407 
    408 	DEFAULTBUF();
    409 	if (vap->va_rdev != (dev_t)PUFFS_VNOVAL)
    410 		snprintf(buf, sizeof(buf), "0x%llx",
    411 		    (unsigned long long)vap->va_rdev);
    412 	mydprintf("rdev: %s\n", buf);
    413 
    414 	DEFAULTBUF();
    415 	if (vap->va_bytes != (u_quad_t)PUFFS_VNOVAL)
    416 		snprintf(buf, sizeof(buf), "%" PRIu64, vap->va_bytes);
    417 	mydprintf(DINT DINT "bytes: %s, ", buf);
    418 
    419 	snprintf(buf, sizeof(buf), "%" PRIu64, vap->va_filerev);
    420 	mydprintf("filerev: %s, ", buf);
    421 
    422 	snprintf(buf, sizeof(buf), "0x%x", vap->va_vaflags);
    423 	mydprintf("vaflags: %s\n", buf);
    424 }
    425 
    426 void
    427 puffsdump_cookie(puffs_cookie_t c, const char *cookiename)
    428 {
    429 
    430 	mydprintf("%scookie: at %p\n", cookiename, c);
    431 }
    432 
    433 static const char *cn_opnames[] = {
    434 	"LOOKUP",
    435 	"CREATE",
    436 	"DELETE",
    437 	"RENAME"
    438 };
    439 
    440 void
    441 puffsdump_cn(struct puffs_kcn *pkcn)
    442 {
    443 
    444 	mydprintf(DINT "puffs_cn: \"%s\", len %zu op %s (flags 0x%x)\n",
    445 	    pkcn->pkcn_name, pkcn->pkcn_namelen,
    446 	    cn_opnames[pkcn->pkcn_nameiop & NAMEI_OPMASK],
    447 	    pkcn->pkcn_flags);
    448 }
    449 
    450 void
    451 puffsdump_lookup(struct puffs_req *preq)
    452 {
    453 	struct puffs_vnmsg_lookup *lookup_msg = (void *)preq;
    454 
    455 	puffsdump_cn(&lookup_msg->pvnr_cn);
    456 }
    457 
    458 void
    459 puffsdump_lookup_rv(struct puffs_req *preq)
    460 {
    461 	struct puffs_vnmsg_lookup *lookup_msg = (void *)preq;
    462 
    463 	mydprintf(DINT "new %p, type 0x%x, size 0x%"PRIu64", dev 0x%llx\n",
    464 	    lookup_msg->pvnr_newnode, lookup_msg->pvnr_vtype,
    465 	    lookup_msg->pvnr_size, (unsigned long long)lookup_msg->pvnr_rdev);
    466 }
    467 
    468 void
    469 puffsdump_create(struct puffs_req *preq)
    470 {
    471 	/* XXX: wrong type, but we know it fits the slot */
    472 	struct puffs_vnmsg_create *create_msg = (void *)preq;
    473 
    474 	dumpattr(&create_msg->pvnr_va);
    475 }
    476 
    477 void
    478 puffsdump_create_rv(struct puffs_req *preq)
    479 {
    480 	/* XXX: wrong type, but we know it fits the slot */
    481 	struct puffs_vnmsg_create *create_msg = (void *)preq;
    482 
    483 	mydprintf(DINT "new %p\n", create_msg->pvnr_newnode);
    484 }
    485 
    486 void
    487 puffsdump_readwrite(struct puffs_req *preq)
    488 {
    489 	struct puffs_vnmsg_rw *rw_msg = (void *)preq;
    490 
    491 	mydprintf(DINT "offset: %" PRId64 ", resid %zu, ioflag 0x%x\n",
    492 	    rw_msg->pvnr_offset, rw_msg->pvnr_resid, rw_msg->pvnr_ioflag);
    493 }
    494 
    495 void
    496 puffsdump_readwrite_rv(struct puffs_req *preq)
    497 {
    498 	struct puffs_vnmsg_rw *rw_msg = (void *)preq;
    499 
    500 	mydprintf(DINT "resid after op: %zu\n", rw_msg->pvnr_resid);
    501 }
    502 
    503 void
    504 puffsdump_readdir_rv(struct puffs_req *preq)
    505 {
    506 	struct puffs_vnmsg_readdir *readdir_msg = (void *)preq;
    507 
    508 	mydprintf(DINT "resid after op: %zu, eofflag %d\n",
    509 	    readdir_msg->pvnr_resid, readdir_msg->pvnr_eofflag);
    510 }
    511 
    512 void
    513 puffsdump_open(struct puffs_req *preq)
    514 {
    515 	struct puffs_vnmsg_open *open_msg = (void *)preq;
    516 
    517 	mydprintf(DINT "mode: 0x%x\n", open_msg->pvnr_mode);
    518 }
    519 
    520 void
    521 puffsdump_targ(struct puffs_req *preq)
    522 {
    523 	struct puffs_vnmsg_remove *remove_msg = (void *)preq; /* XXX! */
    524 
    525 	mydprintf(DINT "target cookie: %p\n", remove_msg->pvnr_cookie_targ);
    526 }
    527 
    528 void
    529 puffsdump_readdir(struct puffs_req *preq)
    530 {
    531 	struct puffs_vnmsg_readdir *readdir_msg = (void *)preq;
    532 
    533 	mydprintf(DINT "read offset: %" PRId64 "\n", readdir_msg->pvnr_offset);
    534 }
    535 
    536 void
    537 puffsdump_attr(struct puffs_req *preq)
    538 {
    539 	struct puffs_vnmsg_setgetattr *attr_msg = (void *)preq;
    540 
    541 	dumpattr(&attr_msg->pvnr_va);
    542 }
    543