Commit 742ae1e35b038ed65ddd86182723441ea74db765

Authored by Dave Chinner
Committed by Ben Myers
1 parent cab09a81fb

xfs: introduce CONFIG_XFS_WARN

Running a CONFIG_XFS_DEBUG kernel in production environments is not
the best idea as it introduces significant overhead, can change
the behaviour of algorithms (such as allocation) to improve test
coverage, and (most importantly) panic the machine on non-fatal
errors.

There are many cases where all we want to do is run a
kernel with more bounds checking enabled, such as is provided by the
ASSERT() statements throughout the code, but without all the
potential overhead and drawbacks.

This patch converts all the ASSERT statements to evaluate as
WARN_ON(1) statements and hence if they fail dump a warning and a
stack trace to the log. This has minimal overhead and does not
change any algorithms, and will allow us to find strange "out of
bounds" problems more easily on production machines.

There are a few places where assert statements contain debug only
code. These are converted to be debug-or-warn only code so that we
still get all the assert checks in the code.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Ben Myers <bpm@sgi.com>

Showing 13 changed files with 63 additions and 24 deletions Side-by-side Diff

... ... @@ -69,6 +69,19 @@
69 69  
70 70 If unsure, say N.
71 71  
  72 +config XFS_WARN
  73 + bool "XFS Verbose Warnings"
  74 + depends on XFS_FS && !XFS_DEBUG
  75 + help
  76 + Say Y here to get an XFS build with many additional warnings.
  77 + It converts ASSERT checks to WARN, so will log any out-of-bounds
  78 + conditions that occur that would otherwise be missed. It is much
  79 + lighter weight than XFS_DEBUG and does not modify algorithms and will
  80 + not cause the kernel to panic on non-fatal errors.
  81 +
  82 + However, similar to XFS_DEBUG, it is only advisable to use this if you
  83 + are debugging a particular problem.
  84 +
72 85 config XFS_DEBUG
73 86 bool "XFS Debugging support"
74 87 depends on XFS_FS
... ... @@ -22,12 +22,12 @@
22 22  
23 23 typedef struct {
24 24 struct rw_semaphore mr_lock;
25   -#ifdef DEBUG
  25 +#if defined(DEBUG) || defined(XFS_WARN)
26 26 int mr_writer;
27 27 #endif
28 28 } mrlock_t;
29 29  
30   -#ifdef DEBUG
  30 +#if defined(DEBUG) || defined(XFS_WARN)
31 31 #define mrinit(mrp, name) \
32 32 do { (mrp)->mr_writer = 0; init_rwsem(&(mrp)->mr_lock); } while (0)
33 33 #else
... ... @@ -46,7 +46,7 @@
46 46 static inline void mrupdate_nested(mrlock_t *mrp, int subclass)
47 47 {
48 48 down_write_nested(&mrp->mr_lock, subclass);
49   -#ifdef DEBUG
  49 +#if defined(DEBUG) || defined(XFS_WARN)
50 50 mrp->mr_writer = 1;
51 51 #endif
52 52 }
... ... @@ -60,7 +60,7 @@
60 60 {
61 61 if (!down_write_trylock(&mrp->mr_lock))
62 62 return 0;
63   -#ifdef DEBUG
  63 +#if defined(DEBUG) || defined(XFS_WARN)
64 64 mrp->mr_writer = 1;
65 65 #endif
66 66 return 1;
... ... @@ -68,7 +68,7 @@
68 68  
69 69 static inline void mrunlock_excl(mrlock_t *mrp)
70 70 {
71   -#ifdef DEBUG
  71 +#if defined(DEBUG) || defined(XFS_WARN)
72 72 mrp->mr_writer = 0;
73 73 #endif
74 74 up_write(&mrp->mr_lock);
... ... @@ -81,7 +81,7 @@
81 81  
82 82 static inline void mrdemote(mrlock_t *mrp)
83 83 {
84   -#ifdef DEBUG
  84 +#if defined(DEBUG) || defined(XFS_WARN)
85 85 mrp->mr_writer = 0;
86 86 #endif
87 87 downgrade_write(&mrp->mr_lock);
... ... @@ -24,6 +24,11 @@
24 24 #define XFS_BUF_LOCK_TRACKING 1
25 25 #endif
26 26  
  27 +#ifdef CONFIG_XFS_WARN
  28 +#define XFS_WARN 1
  29 +#endif
  30 +
  31 +
27 32 #include "xfs_linux.h"
28 33  
29 34 #endif /* __XFS_H__ */
fs/xfs/xfs_alloc_btree.c
... ... @@ -386,7 +386,7 @@
386 386 };
387 387  
388 388  
389   -#ifdef DEBUG
  389 +#if defined(DEBUG) || defined(XFS_WARN)
390 390 STATIC int
391 391 xfs_allocbt_keys_inorder(
392 392 struct xfs_btree_cur *cur,
... ... @@ -442,7 +442,7 @@
442 442 .init_ptr_from_cur = xfs_allocbt_init_ptr_from_cur,
443 443 .key_diff = xfs_allocbt_key_diff,
444 444 .buf_ops = &xfs_allocbt_buf_ops,
445   -#ifdef DEBUG
  445 +#if defined(DEBUG) || defined(XFS_WARN)
446 446 .keys_inorder = xfs_allocbt_keys_inorder,
447 447 .recs_inorder = xfs_allocbt_recs_inorder,
448 448 #endif
fs/xfs/xfs_bmap_btree.c
... ... @@ -813,7 +813,7 @@
813 813 };
814 814  
815 815  
816   -#ifdef DEBUG
  816 +#if defined(DEBUG) || defined(XFS_WARN)
817 817 STATIC int
818 818 xfs_bmbt_keys_inorder(
819 819 struct xfs_btree_cur *cur,
... ... @@ -853,7 +853,7 @@
853 853 .init_ptr_from_cur = xfs_bmbt_init_ptr_from_cur,
854 854 .key_diff = xfs_bmbt_key_diff,
855 855 .buf_ops = &xfs_bmbt_buf_ops,
856   -#ifdef DEBUG
  856 +#if defined(DEBUG) || defined(XFS_WARN)
857 857 .keys_inorder = xfs_bmbt_keys_inorder,
858 858 .recs_inorder = xfs_bmbt_recs_inorder,
859 859 #endif
... ... @@ -215,7 +215,7 @@
215 215  
216 216 const struct xfs_buf_ops *buf_ops;
217 217  
218   -#ifdef DEBUG
  218 +#if defined(DEBUG) || defined(XFS_WARN)
219 219 /* check that k1 is lower than k2 */
220 220 int (*keys_inorder)(struct xfs_btree_cur *cur,
221 221 union xfs_btree_key *k1,
fs/xfs/xfs_dir2_node.c
... ... @@ -993,7 +993,7 @@
993 993 xfs_dir2_leaf_t *leaf1; /* first leaf structure */
994 994 xfs_dir2_leaf_t *leaf2; /* second leaf structure */
995 995 int mid; /* midpoint leaf index */
996   -#ifdef DEBUG
  996 +#if defined(DEBUG) || defined(XFS_WARN)
997 997 int oldstale; /* old count of stale leaves */
998 998 #endif
999 999 int oldsum; /* old total leaf count */
... ... @@ -1022,7 +1022,7 @@
1022 1022 ents2 = xfs_dir3_leaf_ents_p(leaf2);
1023 1023  
1024 1024 oldsum = hdr1.count + hdr2.count;
1025   -#ifdef DEBUG
  1025 +#if defined(DEBUG) || defined(XFS_WARN)
1026 1026 oldstale = hdr1.stale + hdr2.stale;
1027 1027 #endif
1028 1028 mid = oldsum >> 1;
fs/xfs/xfs_ialloc_btree.c
... ... @@ -272,7 +272,7 @@
272 272 .verify_write = xfs_inobt_write_verify,
273 273 };
274 274  
275   -#ifdef DEBUG
  275 +#if defined(DEBUG) || defined(XFS_WARN)
276 276 STATIC int
277 277 xfs_inobt_keys_inorder(
278 278 struct xfs_btree_cur *cur,
... ... @@ -310,7 +310,7 @@
310 310 .init_ptr_from_cur = xfs_inobt_init_ptr_from_cur,
311 311 .key_diff = xfs_inobt_key_diff,
312 312 .buf_ops = &xfs_inobt_buf_ops,
313   -#ifdef DEBUG
  313 +#if defined(DEBUG) || defined(XFS_WARN)
314 314 .keys_inorder = xfs_inobt_keys_inorder,
315 315 .recs_inorder = xfs_inobt_recs_inorder,
316 316 #endif
... ... @@ -287,7 +287,7 @@
287 287 trace_xfs_ilock_demote(ip, lock_flags, _RET_IP_);
288 288 }
289 289  
290   -#ifdef DEBUG
  290 +#if defined(DEBUG) || defined(XFS_WARN)
291 291 int
292 292 xfs_isilocked(
293 293 xfs_inode_t *ip,
... ... @@ -293,22 +293,34 @@
293 293 #define ASSERT_ALWAYS(expr) \
294 294 (unlikely(expr) ? (void)0 : assfail(#expr, __FILE__, __LINE__))
295 295  
296   -#ifndef DEBUG
297   -#define ASSERT(expr) ((void)0)
  296 +#ifdef DEBUG
  297 +#define ASSERT(expr) \
  298 + (unlikely(expr) ? (void)0 : assfail(#expr, __FILE__, __LINE__))
298 299  
299 300 #ifndef STATIC
300   -# define STATIC static noinline
  301 +# define STATIC noinline
301 302 #endif
302 303  
303   -#else /* DEBUG */
  304 +#else /* !DEBUG */
304 305  
  306 +#ifdef XFS_WARN
  307 +
305 308 #define ASSERT(expr) \
306   - (unlikely(expr) ? (void)0 : assfail(#expr, __FILE__, __LINE__))
  309 + (unlikely(expr) ? (void)0 : asswarn(#expr, __FILE__, __LINE__))
307 310  
308 311 #ifndef STATIC
309   -# define STATIC noinline
  312 +# define STATIC static noinline
310 313 #endif
311 314  
  315 +#else /* !DEBUG && !XFS_WARN */
  316 +
  317 +#define ASSERT(expr) ((void)0)
  318 +
  319 +#ifndef STATIC
  320 +# define STATIC static noinline
  321 +#endif
  322 +
  323 +#endif /* XFS_WARN */
312 324 #endif /* DEBUG */
313 325  
314 326 #endif /* __XFS_LINUX__ */
fs/xfs/xfs_message.c
... ... @@ -93,6 +93,14 @@
93 93 }
94 94  
95 95 void
  96 +asswarn(char *expr, char *file, int line)
  97 +{
  98 + xfs_warn(NULL, "Assertion failed: %s, file: %s, line: %d",
  99 + expr, file, line);
  100 + WARN_ON(1);
  101 +}
  102 +
  103 +void
96 104 assfail(char *expr, char *file, int line)
97 105 {
98 106 xfs_emerg(NULL, "Assertion failed: %s, file: %s, line: %d",
fs/xfs/xfs_message.h
... ... @@ -57,6 +57,7 @@
57 57 xfs_printk_ratelimited(xfs_debug, dev, fmt, ##__VA_ARGS__)
58 58  
59 59 extern void assfail(char *expr, char *f, int l);
  60 +extern void asswarn(char *expr, char *f, int l);
60 61  
61 62 extern void xfs_hex_dump(void *p, int length);
62 63  
... ... @@ -405,7 +405,7 @@
405 405 int64_t t_res_fdblocks_delta; /* on-disk only chg */
406 406 int64_t t_frextents_delta;/* superblock freextents chg*/
407 407 int64_t t_res_frextents_delta; /* on-disk only chg */
408   -#ifdef DEBUG
  408 +#if defined(DEBUG) || defined(XFS_WARN)
409 409 int64_t t_ag_freeblks_delta; /* debugging counter */
410 410 int64_t t_ag_flist_delta; /* debugging counter */
411 411 int64_t t_ag_btree_delta; /* debugging counter */
... ... @@ -433,7 +433,7 @@
433 433 #define xfs_trans_get_block_res(tp) ((tp)->t_blk_res)
434 434 #define xfs_trans_set_sync(tp) ((tp)->t_flags |= XFS_TRANS_SYNC)
435 435  
436   -#ifdef DEBUG
  436 +#if defined(DEBUG) || defined(XFS_WARN)
437 437 #define xfs_trans_agblocks_delta(tp, d) ((tp)->t_ag_freeblks_delta += (int64_t)d)
438 438 #define xfs_trans_agflist_delta(tp, d) ((tp)->t_ag_flist_delta += (int64_t)d)
439 439 #define xfs_trans_agbtree_delta(tp, d) ((tp)->t_ag_btree_delta += (int64_t)d)