opdump.c revision 1.28
1/*	$NetBSD: opdump.c,v 1.28 2010/01/07 18:09:07 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 *
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.28 2010/01/07 18:09:07 pooka 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 <stdio.h>
47
48#include "puffs_priv.h"
49
50#define DINT "    "
51
52/* XXX! */
53const char *vfsop_revmap[] = {
54	"PUFFS_VFS_MOUNT",
55	"PUFFS_VFS_START",
56	"PUFFS_VFS_UNMOUNT",
57	"PUFFS_VFS_ROOT",
58	"PUFFS_VFS_STATVFS",
59	"PUFFS_VFS_SYNC",
60	"PUFFS_VFS_VGET",
61	"PUFFS_VFS_FHTOVP",
62	"PUFFS_VFS_VPTOFH",
63	"PUFFS_VFS_INIT",
64	"PUFFS_VFS_DONE",
65	"PUFFS_VFS_SNAPSHOT",
66	"PUFFS_VFS_EXTATTCTL",
67	"PUFFS_VFS_SUSPEND"
68};
69/* XXX! */
70const char *vnop_revmap[] = {
71	"PUFFS_VN_LOOKUP",
72	"PUFFS_VN_CREATE",
73	"PUFFS_VN_MKNOD",
74	"PUFFS_VN_OPEN",
75	"PUFFS_VN_CLOSE",
76	"PUFFS_VN_ACCESS",
77	"PUFFS_VN_GETATTR",
78	"PUFFS_VN_SETATTR",
79	"PUFFS_VN_READ",
80	"PUFFS_VN_WRITE",
81	"PUFFS_VN_IOCTL",
82	"PUFFS_VN_FCNTL",
83	"PUFFS_VN_POLL",
84	"PUFFS_VN_KQFILTER",
85	"PUFFS_VN_REVOKE",
86	"PUFFS_VN_MMAP",
87	"PUFFS_VN_FSYNC",
88	"PUFFS_VN_SEEK",
89	"PUFFS_VN_REMOVE",
90	"PUFFS_VN_LINK",
91	"PUFFS_VN_RENAME",
92	"PUFFS_VN_MKDIR",
93	"PUFFS_VN_RMDIR",
94	"PUFFS_VN_SYMLINK",
95	"PUFFS_VN_READDIR",
96	"PUFFS_VN_READLINK",
97	"PUFFS_VN_ABORTOP",
98	"PUFFS_VN_INACTIVE",
99	"PUFFS_VN_RECLAIM",
100	"PUFFS_VN_LOCK",
101	"PUFFS_VN_UNLOCK",
102	"PUFFS_VN_BMAP",
103	"PUFFS_VN_STRATEGY",
104	"PUFFS_VN_PRINT",
105	"PUFFS_VN_ISLOCKED",
106	"PUFFS_VN_PATHCONF",
107	"PUFFS_VN_ADVLOCK",
108	"PUFFS_VN_LEASE",
109	"PUFFS_VN_WHITEOUT",
110	"PUFFS_VN_GETPAGES",
111	"PUFFS_VN_PUTPAGES",
112	"PUFFS_VN_BWRITE",
113	"PUFFS_VN_GETEXTATTR",
114	"PUFFS_VN_LISTEXTATTR",
115	"PUFFS_VN_OPENEXTATTR",
116	"PUFFS_VN_DELETEEXTATTR",
117	"PUFFS_VN_SETEXTATTR",
118};
119/* XXX! */
120const char *cacheop_revmap[] = {
121	"PUFFS_CACHE_WRITE"
122};
123/* XXX! */
124const char *errnot_revmap[] = {
125	"PUFFS_ERR_MAKENODE",
126	"PUFFS_ERR_LOOKUP",
127	"PUFFS_ERR_READDIR",
128	"PUFFS_ERR_READLINK",
129	"PUFFS_ERR_READ",
130	"PUFFS_ERR_WRITE",
131	"PUFFS_ERR_VPTOFH"
132};
133/* XXX! */
134const char *flush_revmap[] = {
135	"PUFFS_INVAL_NAMECACHE_NODE",
136	"PUFFS_INVAL_NAMECACHE_DIR",
137	"PUFFS_INVAL_NAMECACHE_ALL",
138	"PUFFS_INVAL_PAGECACHE_NODE_RANGE",
139	"PUFFS_FLUSH_PAGECACHE_NODE_RANGE",
140};
141
142void
143puffsdump_req(struct puffs_req *preq)
144{
145	static struct timeval tv_prev;
146	struct timeval tv_now, tv;
147	const char **map;
148	int isvn = 0;
149
150	map = NULL; /* yes, we are all interested in your opinion, gcc */
151	switch (PUFFSOP_OPCLASS(preq->preq_opclass)) {
152	case PUFFSOP_VFS:
153		map = vfsop_revmap;
154		break;
155	case PUFFSOP_VN:
156		map = vnop_revmap;
157		isvn = 1;
158		break;
159	case PUFFSOP_CACHE:
160		map = cacheop_revmap;
161		break;
162	case PUFFSOP_ERROR:
163		map = errnot_revmap;
164		break;
165	case PUFFSOP_FLUSH:
166		map = flush_revmap;
167		break;
168	}
169
170	printf("reqid: %" PRIu64 ", opclass %d%s, optype: %s, "
171	    "cookie: %p,\n" DINT "aux: %p, auxlen: %zu, pid: %d, lwpid: %d\n",
172	    preq->preq_id, PUFFSOP_OPCLASS(preq->preq_opclass),
173	    PUFFSOP_WANTREPLY(preq->preq_opclass) ? "" : " (FAF)",
174	    map[preq->preq_optype], preq->preq_cookie,
175	    preq->preq_buf, preq->preq_buflen,
176	    preq->preq_pid, preq->preq_lid);
177
178	if (isvn) {
179		switch (preq->preq_optype) {
180		case PUFFS_VN_LOOKUP:
181			puffsdump_lookup(preq);
182			break;
183		case PUFFS_VN_READ:
184		case PUFFS_VN_WRITE:
185			puffsdump_readwrite(preq);
186			break;
187		case PUFFS_VN_OPEN:
188			puffsdump_open(preq);
189			break;
190		case PUFFS_VN_REMOVE:
191		case PUFFS_VN_RMDIR:
192		case PUFFS_VN_LINK:
193			puffsdump_targ(preq);
194			break;
195		case PUFFS_VN_READDIR:
196			puffsdump_readdir(preq);
197			break;
198		default:
199			break;
200		}
201	}
202
203	PU_LOCK();
204	gettimeofday(&tv_now, NULL);
205	timersub(&tv_now, &tv_prev, &tv);
206	printf(DINT "since previous call: %lld.%06ld\n",
207	    (long long)tv.tv_sec, (long)tv.tv_usec);
208	gettimeofday(&tv_prev, NULL);
209	PU_UNLOCK();
210}
211
212void
213puffsdump_rv(struct puffs_req *preq)
214{
215
216	if (PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VN) {
217		switch (preq->preq_optype) {
218		case PUFFS_VN_LOOKUP:
219			puffsdump_lookup_rv(preq);
220			break;
221		case PUFFS_VN_CREATE:
222		case PUFFS_VN_MKDIR:
223		case PUFFS_VN_MKNOD:
224		case PUFFS_VN_SYMLINK:
225			puffsdump_create_rv(preq);
226			break;
227		case PUFFS_VN_READ:
228		case PUFFS_VN_WRITE:
229			puffsdump_readwrite_rv(preq);
230			break;
231		case PUFFS_VN_READDIR:
232			puffsdump_readdir_rv(preq);
233			break;
234		default:
235			break;
236		}
237	}
238
239	printf("RV reqid: %" PRIu64 ", result: %d %s\n",
240	    preq->preq_id, preq->preq_rv,
241	    preq->preq_rv ? strerror(preq->preq_rv) : "");
242}
243
244void
245puffsdump_cookie(puffs_cookie_t c, const char *cookiename)
246{
247
248	printf("%scookie: at %p\n", cookiename, c);
249}
250
251static const char *cn_opnames[] = {
252	"LOOKUP",
253	"CREATE",
254	"DELETE",
255	"RENAME"
256};
257
258void
259puffsdump_cn(struct puffs_kcn *pkcn)
260{
261
262	printf(DINT "puffs_cn: \"%s\", len %zu op %s (flags 0x%x)\n",
263	    pkcn->pkcn_name, pkcn->pkcn_namelen,
264	    cn_opnames[pkcn->pkcn_nameiop & NAMEI_OPMASK],
265	    pkcn->pkcn_flags);
266}
267
268void
269puffsdump_lookup(struct puffs_req *preq)
270{
271	struct puffs_vnmsg_lookup *lookup_msg = (void *)preq;
272
273	puffsdump_cn(&lookup_msg->pvnr_cn);
274}
275
276void
277puffsdump_lookup_rv(struct puffs_req *preq)
278{
279	struct puffs_vnmsg_lookup *lookup_msg = (void *)preq;
280
281	printf(DINT "new %p, type 0x%x, size 0x%"PRIu64", dev 0x%llx\n",
282	    lookup_msg->pvnr_newnode, lookup_msg->pvnr_vtype,
283	    lookup_msg->pvnr_size, (unsigned long long)lookup_msg->pvnr_rdev);
284}
285
286void
287puffsdump_create_rv(struct puffs_req *preq)
288{
289	/* XXX: wrong type, but we know it fits the slot */
290	struct puffs_vnmsg_create *create_msg = (void *)preq;
291
292	printf(DINT "new %p\n", create_msg->pvnr_newnode);
293}
294
295void
296puffsdump_readwrite(struct puffs_req *preq)
297{
298	struct puffs_vnmsg_rw *rw_msg = (void *)preq;
299
300	printf(DINT "offset: %" PRId64 ", resid %zu, ioflag 0x%x\n",
301	    rw_msg->pvnr_offset, rw_msg->pvnr_resid, rw_msg->pvnr_ioflag);
302}
303
304void
305puffsdump_readwrite_rv(struct puffs_req *preq)
306{
307	struct puffs_vnmsg_rw *rw_msg = (void *)preq;
308
309	printf(DINT "resid after op: %zu\n", rw_msg->pvnr_resid);
310}
311
312void
313puffsdump_readdir_rv(struct puffs_req *preq)
314{
315	struct puffs_vnmsg_readdir *readdir_msg = (void *)preq;
316
317	printf(DINT "resid after op: %zu, eofflag %d\n",
318	    readdir_msg->pvnr_resid, readdir_msg->pvnr_eofflag);
319}
320
321void
322puffsdump_open(struct puffs_req *preq)
323{
324	struct puffs_vnmsg_open *open_msg = (void *)preq;
325
326	printf(DINT "mode: 0x%x\n", open_msg->pvnr_mode);
327}
328
329void
330puffsdump_targ(struct puffs_req *preq)
331{
332	struct puffs_vnmsg_remove *remove_msg = (void *)preq; /* XXX! */
333
334	printf(DINT "target cookie: %p\n", remove_msg->pvnr_cookie_targ);
335}
336
337void
338puffsdump_readdir(struct puffs_req *preq)
339{
340	struct puffs_vnmsg_readdir *readdir_msg = (void *)preq;
341
342	printf(DINT "read offset: %" PRId64 "\n", readdir_msg->pvnr_offset);
343}
344