|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* hfs_dbg.h ! 26: * ! 27: * (c) 1997 Apple Computer, Inc. All Rights Reserved ! 28: * ! 29: * hfs_dbg.h -- debugging macros for HFS file system. ! 30: * ! 31: * HISTORY ! 32: * 10-Nov-1998 Pat Dirks Cleaned up definition of DBG_ASSERT to handle embedded '%' correctly. ! 33: * 28-Apr-1998 Scott Roberts Reorganized and added DEBUG_STAGE ! 34: * 17-Nov-1997 Pat Dirks Pat Dirks at Apple Computer ! 35: * Derived from old hfs version. ! 36: */ ! 37: ! 38: #ifdef KERNEL ! 39: #include <libkern/libkern.h> ! 40: #else /* KERNEL */ ! 41: #include <bsd/stdio.h> ! 42: #endif /* KERNEL */ ! 43: ! 44: extern void call_kdp(void); ! 45: extern int lbolt; ! 46: ! 47: /* Define the debugging stage... ! 48: 4 -> Do all, aggresive, call_kdp ! 49: 3 -> debug asserts and debug err, panic instead of call_kdp ! 50: 2 -> debug error, no kdb ! 51: 1 -> very little, panic only ! 52: */ ! 53: #if DIAGNOSTIC ! 54: /* OK, we're doing a debug build; DIAGNOSTIC=1 */ ! 55: #else ! 56: /* This is a debug build (DIAGNOSTIC is undefined or DIAGNOSTIC=0); make sure DIAGNOSTIC=0 */ ! 57: #ifdef DIAGNOSTIC ! 58: #warning DIAGNOSTIC defined but not set! ! 59: #endif ! 60: /* XXX PPD Is this just totally superfluous, or even dangerous? #if DIAGNOSTIC already fails, and now #ifdef DIAGNOSTIC will fire... */ ! 61: #define DIAGNOSTIC 0 ! 62: #endif ! 63: ! 64: #if DIAGNOSTIC ! 65: #define DEBUG_STAGE 3 ! 66: #else ! 67: #define DEBUG_STAGE 1 ! 68: #endif /* KERNEL */ ! 69: ! 70: #ifdef KERNEL ! 71: #define PRINTIT kprintf ! 72: #else /* KERNEL */ ! 73: #define PRINTIT printf ! 74: #endif /* KERNEL */ ! 75: ! 76: #if (DEBUG_STAGE > 2) ! 77: #define DEBUG_BREAK call_kdp(); ! 78: #else ! 79: #define DEBUG_BREAK ! 80: #endif ! 81: ! 82: #if (DEBUG_STAGE == 4) ! 83: #define DEBUG_BREAK_MSG(PRINTF_ARGS) { PRINTIT PRINTF_ARGS; DEBUG_BREAK }; ! 84: #elif (DEBUG_STAGE == 3) ! 85: #define DEBUG_BREAK_MSG(PRINTF_ARGS) { panic PRINTF_ARGS;}; ! 86: #else ! 87: #define DEBUG_BREAK_MSG(PRINTF_ARGS) { PRINTIT PRINTF_ARGS; }; ! 88: #endif ! 89: ! 90: ! 91: //#define PRINT_DELAY (void) tsleep((caddr_t)&lbolt, PPAUSE, "hfs kprintf", 0) ! 92: #define PRINT_DELAY ! 93: ! 94: /* ! 95: * Debugging macros. ! 96: */ ! 97: #if DIAGNOSTIC ! 98: extern int hfs_dbg_all; ! 99: extern int hfs_dbg_vfs; ! 100: extern int hfs_dbg_vop; ! 101: extern int hfs_dbg_load; ! 102: extern int hfs_dbg_io; ! 103: extern int hfs_dbg_utils; ! 104: extern int hfs_dbg_rw; ! 105: extern int hfs_dbg_DIT; ! 106: extern int hfs_dbg_tree; ! 107: extern int hfs_dbg_err; ! 108: extern int hfs_dbg_test; ! 109: ! 110: #ifdef KERNEL ! 111: #if (DEBUG_STAGE == 4) ! 112: #define DBG_ASSERT(a) { if (!(a)) { PRINTIT("Oops - File "__FILE__", line %d: assertion '%s' failed.\n", __LINE__, #a); DEBUG_BREAK } } ! 113: #else ! 114: #define DBG_ASSERT(a) { if (!(a)) { panic("File "__FILE__", line %d: assertion '%s' failed.\n", __LINE__, #a); } } ! 115: #endif /* DEBUG_STAGE */ ! 116: #else ! 117: #define DBG_ASSERT(a) assert(a) ! 118: #endif /* KERNEL */ ! 119: ! 120: //#define DBG_VFS if (hfs_dbg_all || hfs_dbg_vfs) PRINTIT ! 121: #define DBG_VFS(x) { \ ! 122: if(hfs_dbg_all || hfs_dbg_vfs) { \ ! 123: PRINTIT("%X: ", CURRENT_PROC->p_pid); \ ! 124: PRINTIT x; \ ! 125: PRINT_DELAY; \ ! 126: }; \ ! 127: } ! 128: #define DBG_VFS_CONT(x) { \ ! 129: if(hfs_dbg_all || hfs_dbg_vfs) { \ ! 130: PRINTIT x; \ ! 131: PRINT_DELAY; \ ! 132: }; \ ! 133: } ! 134: #define DBG_VOP(x) { \ ! 135: if(hfs_dbg_all || hfs_dbg_vop) { \ ! 136: PRINTIT("%X: ", CURRENT_PROC->p_pid); \ ! 137: PRINTIT x; \ ! 138: PRINT_DELAY; \ ! 139: }; \ ! 140: } ! 141: #define DBG_VOP_CONT(x) { \ ! 142: if(hfs_dbg_all || hfs_dbg_vop) { \ ! 143: PRINTIT x; \ ! 144: PRINT_DELAY; \ ! 145: }; \ ! 146: } ! 147: #define DBG_LOAD(x) { \ ! 148: if(hfs_dbg_all || hfs_dbg_load) { \ ! 149: PRINTIT("%X: ", CURRENT_PROC->p_pid); \ ! 150: PRINTIT x; \ ! 151: PRINT_DELAY; \ ! 152: }; \ ! 153: } ! 154: #define DBG_IO(x) { \ ! 155: if(hfs_dbg_all || hfs_dbg_io) { \ ! 156: PRINTIT("%X: ", CURRENT_PROC->p_pid); \ ! 157: PRINTIT x; \ ! 158: PRINT_DELAY; \ ! 159: }; \ ! 160: } ! 161: #define DBG_UTILS(x) { \ ! 162: if(hfs_dbg_all || hfs_dbg_utils) { \ ! 163: PRINTIT("%X: ", CURRENT_PROC->p_pid); \ ! 164: PRINTIT x; \ ! 165: PRINT_DELAY; \ ! 166: }; \ ! 167: } ! 168: #define DBG_RW(x) { \ ! 169: if(hfs_dbg_all || hfs_dbg_rw) { \ ! 170: PRINTIT("%X: ", CURRENT_PROC->p_pid); \ ! 171: PRINTIT x; \ ! 172: PRINT_DELAY; \ ! 173: }; \ ! 174: } ! 175: #define DBG_DIT(x) { \ ! 176: if(hfs_dbg_all || hfs_dbg_DIT) { \ ! 177: PRINTIT("%X: ", CURRENT_PROC->p_pid); \ ! 178: PRINTIT x; \ ! 179: PRINT_DELAY; \ ! 180: }; \ ! 181: } ! 182: #define DBG_TREE(x) { \ ! 183: if(hfs_dbg_all || hfs_dbg_tree) { \ ! 184: PRINTIT("%X: ", CURRENT_PROC->p_pid); \ ! 185: PRINTIT x; \ ! 186: PRINT_DELAY; \ ! 187: }; \ ! 188: } ! 189: #define DBG_ERR(x) { \ ! 190: if(hfs_dbg_all || hfs_dbg_err) { \ ! 191: PRINTIT("%X: ", CURRENT_PROC->p_pid); \ ! 192: PRINTIT("HFS ERROR: "); \ ! 193: PRINTIT x; \ ! 194: PRINT_DELAY; \ ! 195: }; \ ! 196: } ! 197: #define DBG_TEST(x) { \ ! 198: if(hfs_dbg_all || hfs_dbg_test) { \ ! 199: PRINTIT("%X: ", CURRENT_PROC->p_pid); \ ! 200: PRINTIT x; \ ! 201: PRINT_DELAY; \ ! 202: }; \ ! 203: } ! 204: #else // DIAGNOSTIC ! 205: #define DBG_ASSERT(a) ! 206: #define DBG_VFS(x) ! 207: #define DBG_VFS_CONT(x) ! 208: #define DBG_VOP(x) ! 209: #define DBG_VOP_CONT(x) ! 210: #define DBG_LOAD(x) ! 211: #define DBG_IO(x) ! 212: #define DBG_UTILS(x) ! 213: #define DBG_RW(x) ! 214: #define DBG_DIT(x) ! 215: #define DBG_TREE(x) ! 216: #define DBG_ERR(x) ! 217: #define DBG_TEST(x) ! 218: #endif // DIAGNOSTIC ! 219: ! 220: ! 221: /* Used to help print commone values in the vnode ops */ ! 222: #if DIAGNOSTIC ! 223: extern void debug_vn_status (char* introStr, struct vnode *vn); ! 224: extern void debug_vn_print (char* introStr, struct vnode *vn); ! 225: ! 226: #define DBG_VN_STATUS (introStr, vn) debug_vn_status (introStr, vn) ! 227: #define DBG_VN_PRINT (introStr, vn) debug_vn_print (introStr, vn) ! 228: #define DBG_FUNC_NAME(FSTR) static char *funcname = FSTR ! 229: #define DBG_PRINT_FUNC_NAME() PRINTIT("%X: %s\n", CURRENT_PROC->p_pid, funcname) ! 230: #define DBG_VOP_PRINT_FUNCNAME() DBG_VOP(("%s: ", funcname)); ! 231: ! 232: ! 233: /* This checks to make sure the passed in node is valid and HFS */ ! 234: #define DBG_HFS_NODE_CHECK(VP) { \ ! 235: if ((VP) == NULL || VTOH((VP))->h_valid != HFS_VNODE_MAGIC) { \ ! 236: DBG_VOP_CONT(("%s: INVALID VNODE: ", funcname)); \ ! 237: DBG_VOP_PRINT_VNODE_INFO(VP); \ ! 238: DBG_VOP_CONT(("\n")); \ ! 239: return (EINVAL); \ ! 240: } \ ! 241: } ! 242: ! 243: #define DBG_VOP_PRINT_VNODE_INFO(VP) { if (VP && VTOH((VP))->h_valid == HFS_VNODE_MAGIC) { \ ! 244: DBG_VOP_CONT(("\tn: %s, p: %ld, id: %ld, f: %d, u: %d, v: 0x%x ",H_NAME(VTOH(VP)), \ ! 245: H_DIRID(VTOH(VP)), H_FILEID(VTOH(VP)), H_FORKTYPE(VTOH(VP)), (VP)->v_usecount, (u_int)(VP))); \ ! 246: } else { \ ! 247: DBG_VOP_CONT(("\tBAD MACNODE"));}} ! 248: ! 249: #define DBG_VOP_PRINT_CPN_INFO(CN) DBG_VOP_CONT(("name: %s",(CN)->cn_nameptr)); ! 250: ! 251: #else /* DIAGNOSTIC */ ! 252: ! 253: #define DBG_VN_PRINT(introStr,vn) ! 254: #define DBG_VN_STATUS(introStr,vn) ! 255: #define DBG_FUNC_NAME(FSTR) ! 256: #define DBG_PRINT_FUNC_NAME() ! 257: #define DBG_HFS_NODE_CHECK(VP) ! 258: #define DBG_VOP_PRINT_FUNCNAME() ! 259: #define DBG_VOP_PRINT_VNODE_INFO(VP) ! 260: #define DBG_VOP_PRINT_CPN_INFO(CN) ! 261: ! 262: #endif /* DIAGNOSTIC */ ! 263: ! 264: ! 265: #if DIAGNOSTIC ! 266: #define DBG_VOP_TEST_LOCKS 1 ! 267: #else /* DIAGNOSTIC */ ! 268: #undef DBG_VOP_TEST_LOCKS ! 269: #endif /* DIAGNOSTIC */ ! 270: ! 271: ! 272: ! 273: #if DBG_VOP_TEST_LOCKS ! 274: ! 275: typedef struct VopDbgStoreRec { ! 276: short id; ! 277: struct vnode *vp; ! 278: short inState; ! 279: short outState; ! 280: short errState; ! 281: int inValue; ! 282: int outValue; ! 283: } VopDbgStoreRec; ! 284: ! 285: ! 286: void DbgVopTest (int max, int error, VopDbgStoreRec *VopDbgStore, char *funcname); ! 287: void DbgLookupTest(char *funcname, struct componentname *cnp, struct vnode *dvp, struct vnode *vp); ! 288: ! 289: #define VOPDBG_IGNORE 0 ! 290: #define VOPDBG_LOCKED 1 ! 291: #define VOPDBG_UNLOCKED -1 ! 292: #define VOPDBG_LOCKNOTNIL 2 ! 293: #define VOPDBG_SAME 3 ! 294: ! 295: #define VOPDBG_ZERO 0 ! 296: #define VOPDBG_POS 1 ! 297: ! 298: /* This sets up the test for the lock state of vnodes. The entry paramaters are: ! 299: * I = index of paramater ! 300: * VP = pointer to a vnode ! 301: * ENTRYSTATE = the inState of the lock ! 302: * EXITSTATE = the outState of the lock ! 303: * ERRORSTATE = the error state of the lock ! 304: * It initializes the structure, does some preliminary validity checks, but does nothing ! 305: * if the instate is set to be ignored. ! 306: */ ! 307: ! 308: ! 309: #define DBG_VOP_LOCKS_DECL(I) VopDbgStoreRec VopDbgStore[I];short numOfLockSlots=I ! 310: #define DBG_VOP_LOCKS_INIT(I,VP,ENTRYSTATE,EXITSTATE,ERRORSTATE,CHECKFLAG) \ ! 311: if (I >= numOfLockSlots) { \ ! 312: DEBUG_BREAK_MSG(("%s: DBG_VOP_LOCKS_INIT: Entry #%d greater than allocated slots!\n", funcname, I)); \ ! 313: }; \ ! 314: VopDbgStore[I].id = I; \ ! 315: VopDbgStore[I].vp = VP; \ ! 316: VopDbgStore[I].inState = ENTRYSTATE; \ ! 317: VopDbgStore[I].outState = EXITSTATE; \ ! 318: VopDbgStore[I].errState = ERRORSTATE; \ ! 319: VopDbgStore[I].inValue = 0; \ ! 320: VopDbgStore[I].outValue = 0; \ ! 321: if ((VopDbgStore[I].inState != VOPDBG_IGNORE)) { \ ! 322: if ((VP) == NULL) \ ! 323: PRINTIT ("%X: %s: DBG_VOP_LOCK on start: Null vnode ptr\n", CURRENT_PROC->p_pid, funcname); \ ! 324: else \ ! 325: VopDbgStore[I].inValue = lockstatus (&(VTOH(VP))->h_lock); \ ! 326: } \ ! 327: if ((VP) != NULL) \ ! 328: { \ ! 329: if (CHECKFLAG==VOPDBG_POS && (VP)->v_usecount <= 0) \ ! 330: PRINTIT("%X: %s: BAD USECOUNT OF %d !!!!\n", CURRENT_PROC->p_pid, funcname, (VP)->v_usecount); \ ! 331: else if ((VP)->v_usecount < 0) \ ! 332: PRINTIT("%X: %s: BAD USECOUNT OF %d !!!!\n", CURRENT_PROC->p_pid, funcname, (VP)->v_usecount); \ ! 333: } ! 334: ! 335: #define DBG_VOP_UPDATE_VP(I, VP) \ ! 336: VopDbgStore[I].vp = VP; ! 337: ! 338: #define DBG_VOP_LOCKS_TEST(status) DbgVopTest (numOfLockSlots, status, VopDbgStore, funcname); ! 339: #define DBG_VOP_LOOKUP_TEST(funcname, cnp, dvp, vp) DbgLookupTest (funcname, cnp, dvp, vp); ! 340: ! 341: #else /* DBG_VOP_TEST_LOCKS */ ! 342: ! 343: #define DBG_VOP_LOCKS_DECL(A) ! 344: #define DBG_VOP_LOCKS_INIT(A,B,C,D,E,F) ! 345: #define DBG_VOP_LOCKS_TEST(a) ! 346: #define DBG_VOP_LOOKUP_TEST(funcname, cnp, dvp, vp) ! 347: #define DBG_VOP_UPDATE_VP(I, VP) ! 348: #endif /* DBG_VOP_TEST_LOCKS */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.