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