]>
Commit | Line | Data |
---|---|---|
1c79356b A |
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 */ |