1 /* Copyright 2001, 2002, 2003 by Hans Reiser, licensing governed by
4 /* Declarations of debug macros. */
6 #if !defined(__FS_REISER4_DEBUG_H__)
7 #define __FS_REISER4_DEBUG_H__
12 /* generic function to produce formatted output, decorating it with
13 whatever standard prefixes/postfixes we want. "Fun" is a function
14 that will be actually called, can be printk, panic etc.
15 This is for use by other debugging macros, not by users. */
16 #define DCALL(lev, fun, reperr, label, format, ...) \
18 fun(lev "reiser4[%.16s(%i)]: %s (%s:%i)[%s]:\n" format "\n" , \
19 current->comm, task_pid_nr(current), __FUNCTION__, \
20 __FILE__, __LINE__, label, ## __VA_ARGS__); \
24 * cause kernel to crash
26 #define reiser4_panic(mid, format, ...) \
27 DCALL("", reiser4_do_panic, 1, mid, format , ## __VA_ARGS__)
29 /* print message with indication of current process, file, line and
31 #define reiser4_log(label, format, ...) \
32 DCALL(KERN_DEBUG, printk, 0, label, format , ## __VA_ARGS__)
34 /* Assertion checked during compilation.
35 If "cond" is false (0) we get duplicate case label in switch.
36 Use this to check something like famous
37 cassert (sizeof(struct reiserfs_journal_commit) == 4096) ;
38 in 3.x journal.c. If cassertion fails you get compiler error,
39 so no "maintainer-id".
41 #define cassert(cond) ({ switch (-1) { case (cond): case 0: break; } })
43 #define noop do {; } while (0)
46 /* version of info that only actually prints anything when _d_ebugging
48 #define dinfo(format, ...) printk(format , ## __VA_ARGS__)
49 /* macro to catch logical errors. Put it into `default' clause of
50 switch() statement. */
51 #define impossible(label, format, ...) \
52 reiser4_panic(label, "impossible: " format , ## __VA_ARGS__)
53 /* assert assures that @cond is true. If it is not, reiser4_panic() is
54 called. Use this for checking logical consistency and _never_ call
55 this to check correctness of external data: disk blocks and user-input . */
56 #define assert(label, cond) \
58 /* call_on_each_assert(); */ \
60 /* put negated check to avoid using !(cond) that would lose \
61 * warnings for things like assert(a = b); */ \
65 reiser4_panic(label, "assertion failed: %s", #cond); \
69 /* like assertion, but @expr is evaluated even if REISER4_DEBUG is off. */
70 #define check_me(label, expr) assert(label, (expr))
72 #define ON_DEBUG(exp) exp
74 extern int reiser4_schedulable(void);
75 extern void call_on_each_assert(void);
79 #define dinfo(format, args...) noop
80 #define impossible(label, format, args...) noop
81 #define assert(label, cond) noop
82 #define check_me(label, expr) ((void) (expr))
84 #define reiser4_schedulable() might_sleep()
90 /* per-thread information about lock acquired by this thread. Used by lock
91 * ordering checking in spin_macros.h */
92 typedef struct reiser4_lock_cnt_info
{
95 int write_locked_tree
;
101 int rw_locked_cbk_cache
;
102 int read_locked_cbk_cache
;
103 int write_locked_cbk_cache
;
105 int spin_locked_zlock
;
106 int spin_locked_jnode
;
107 int spin_locked_jload
;
108 int spin_locked_txnh
;
109 int spin_locked_atom
;
110 int spin_locked_stack
;
111 int spin_locked_txnmgr
;
112 int spin_locked_ktxnmgrd
;
114 int spin_locked_inode
;
115 int spin_locked_super_eflush
;
117 int long_term_locked_znode
;
125 } reiser4_lock_cnt_info
;
127 extern struct reiser4_lock_cnt_info
*reiser4_lock_counters(void);
128 #define IN_CONTEXT(a, b) (is_in_reiser4_context() ? (a) : (b))
130 /* increment lock-counter @counter, if present */
131 #define LOCK_CNT_INC(counter) \
132 IN_CONTEXT(++(reiser4_lock_counters()->counter), 0)
134 /* decrement lock-counter @counter, if present */
135 #define LOCK_CNT_DEC(counter) \
136 IN_CONTEXT(--(reiser4_lock_counters()->counter), 0)
138 /* check that lock-counter is zero. This is for use in assertions */
139 #define LOCK_CNT_NIL(counter) \
140 IN_CONTEXT(reiser4_lock_counters()->counter == 0, 1)
142 /* check that lock-counter is greater than zero. This is for use in
144 #define LOCK_CNT_GTZ(counter) \
145 IN_CONTEXT(reiser4_lock_counters()->counter > 0, 1)
146 #define LOCK_CNT_LT(counter,n) \
147 IN_CONTEXT(reiser4_lock_counters()->counter < n, 1)
149 #else /* REISER4_DEBUG */
151 /* no-op versions on the above */
153 typedef struct reiser4_lock_cnt_info
{
154 } reiser4_lock_cnt_info
;
156 #define reiser4_lock_counters() ((reiser4_lock_cnt_info *)NULL)
157 #define LOCK_CNT_INC(counter) noop
158 #define LOCK_CNT_DEC(counter) noop
159 #define LOCK_CNT_NIL(counter) (1)
160 #define LOCK_CNT_GTZ(counter) (1)
161 #define LOCK_CNT_LT(counter, n) (1)
163 #endif /* REISER4_DEBUG */
165 #define assert_spin_not_locked(lock) BUG_ON(0)
166 #define assert_rw_write_locked(lock) BUG_ON(0)
167 #define assert_rw_read_locked(lock) BUG_ON(0)
168 #define assert_rw_locked(lock) BUG_ON(0)
169 #define assert_rw_not_write_locked(lock) BUG_ON(0)
170 #define assert_rw_not_read_locked(lock) BUG_ON(0)
171 #define assert_rw_not_locked(lock) BUG_ON(0)
173 /* flags controlling debugging behavior. Are set through debug_flags=N mount
176 /* print a lot of information during panic. When this is on all jnodes
177 * are listed. This can be *very* large output. Usually you don't want
178 * this. Especially over serial line. */
179 REISER4_VERBOSE_PANIC
= 0x00000001,
180 /* print a lot of information during umount */
181 REISER4_VERBOSE_UMOUNT
= 0x00000002,
182 /* print gathered statistics on umount */
183 REISER4_STATS_ON_UMOUNT
= 0x00000004,
184 /* check node consistency */
185 REISER4_CHECK_NODE
= 0x00000008
186 } reiser4_debug_flags
;
188 extern int is_in_reiser4_context(void);
191 * evaluate expression @e only if with reiser4 context
193 #define ON_CONTEXT(e) do { \
194 if (is_in_reiser4_context()) { \
199 * evaluate expression @e only when within reiser4_context and debugging is
202 #define ON_DEBUG_CONTEXT(e) ON_DEBUG(ON_CONTEXT(e))
205 * complain about unexpected function result and crash. Used in "default"
206 * branches of switch statements and alike to assert that invalid results are
207 * not silently ignored.
209 #define wrong_return_value(label, function) \
210 impossible(label, "wrong return value from " function)
212 /* Issue different types of reiser4 messages to the console */
213 #define warning(label, format, ...) \
214 DCALL(KERN_WARNING, \
215 printk, 1, label, "WARNING: " format , ## __VA_ARGS__)
216 #define notice(label, format, ...) \
218 printk, 1, label, "NOTICE: " format , ## __VA_ARGS__)
220 /* mark not yet implemented functionality */
221 #define not_yet(label, format, ...) \
222 reiser4_panic(label, "NOT YET IMPLEMENTED: " format , ## __VA_ARGS__)
224 extern void reiser4_do_panic(const char *format
, ...)
225 __attribute__ ((noreturn
, format(printf
, 1, 2)));
227 extern int reiser4_preempt_point(void);
228 extern void reiser4_print_stats(void);
231 extern int reiser4_no_counters_are_held(void);
232 extern int reiser4_commit_check_locks(void);
234 #define reiser4_no_counters_are_held() (1)
235 #define reiser4_commit_check_locks() (1)
238 /* true if @i is power-of-two. Useful for rate-limited warnings, etc. */
244 !(__i & (__i - 1)); \
247 #define KERNEL_DEBUGGER (1)
251 extern void reiser4_debugtrap(void);
254 * Check condition @cond and drop into kernel debugger (kgdb) if it's true. If
255 * kgdb is not compiled in, do nothing.
257 #define DEBUGON(cond) \
259 if (unlikely(cond)) \
260 reiser4_debugtrap(); \
263 #define DEBUGON(cond) noop
267 * Error code tracing facility. (Idea is borrowed from XFS code.)
269 * Suppose some strange and/or unexpected code is returned from some function
270 * (for example, write(2) returns -EEXIST). It is possible to place a
271 * breakpoint in the reiser4_write(), but it is too late here. How to find out
272 * in what particular place -EEXIST was generated first?
274 * In reiser4 all places where actual error codes are produced (that is,
275 * statements of the form
277 * return -EFOO; // (1), or
279 * result = -EFOO; // (2)
283 * return RETERR(-EFOO); // (1a), and
285 * result = RETERR(-EFOO); // (2a) respectively
287 * RETERR() macro fills a backtrace in reiser4_context. This back-trace is
288 * printed in error and warning messages. Moreover, it's possible to put a
289 * conditional breakpoint in reiser4_return_err (low-level function called
290 * by RETERR() to do the actual work) to break into debugger immediately
291 * when particular error happens.
298 * data-type to store information about where error happened ("error site").
300 typedef struct err_site
{
301 int code
; /* error code */
302 const char *file
; /* source file, filled by __FILE__ */
303 int line
; /* source file line, filled by __LINE__ */
306 extern void reiser4_return_err(int code
, const char *file
, int line
);
309 * fill &get_current_context()->err_site with error information.
311 #define RETERR(code) \
313 typeof(code) __code; \
316 reiser4_return_err(__code, __FILE__, __LINE__); \
323 * no-op versions of the above
326 typedef struct err_site
{
328 #define RETERR(code) code
331 #if REISER4_LARGE_KEY
333 * conditionally compile arguments only if REISER4_LARGE_KEY is on.
335 #define ON_LARGE_KEY(...) __VA_ARGS__
337 #define ON_LARGE_KEY(...)
340 /* __FS_REISER4_DEBUG_H__ */
345 c-indentation-style: "K&R"