|
|
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.