Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Dave Chinner and committed by
Ben Myers
742ae1e3 cab09a81

+66 -27
+13
fs/xfs/Kconfig
··· 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
+6 -6
fs/xfs/mrlock.h
··· 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 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 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 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 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);
+5
fs/xfs/xfs.h
··· 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__ */
+2 -2
fs/xfs/xfs_alloc_btree.c
··· 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 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
+2 -2
fs/xfs/xfs_bmap_btree.c
··· 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 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
+1 -1
fs/xfs/xfs_btree.h
··· 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,
+2 -2
fs/xfs/xfs_dir2_node.c
··· 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 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;
+2 -2
fs/xfs/xfs_ialloc_btree.c
··· 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 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
+1 -1
fs/xfs/xfs_inode.c
··· 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,
+21 -9
fs/xfs/xfs_linux.h
··· 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) 298 - 299 - #ifndef STATIC 300 - # define STATIC static noinline 301 - #endif 302 - 303 - #else /* DEBUG */ 304 - 296 + #ifdef DEBUG 305 297 #define ASSERT(expr) \ 306 298 (unlikely(expr) ? (void)0 : assfail(#expr, __FILE__, __LINE__)) 307 299 ··· 301 309 # define STATIC noinline 302 310 #endif 303 311 312 + #else /* !DEBUG */ 313 + 314 + #ifdef XFS_WARN 315 + 316 + #define ASSERT(expr) \ 317 + (unlikely(expr) ? (void)0 : asswarn(#expr, __FILE__, __LINE__)) 318 + 319 + #ifndef STATIC 320 + # define STATIC static noinline 321 + #endif 322 + 323 + #else /* !DEBUG && !XFS_WARN */ 324 + 325 + #define ASSERT(expr) ((void)0) 326 + 327 + #ifndef STATIC 328 + # define STATIC static noinline 329 + #endif 330 + 331 + #endif /* XFS_WARN */ 304 332 #endif /* DEBUG */ 305 333 306 334 #endif /* __XFS_LINUX__ */
+8
fs/xfs/xfs_message.c
··· 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",
+1
fs/xfs/xfs_message.h
··· 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
+2 -2
fs/xfs/xfs_trans.h
··· 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 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)