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