aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2013-04-30 07:39:34 -0400
committerBen Myers <bpm@sgi.com>2013-05-07 19:45:36 -0400
commit742ae1e35b038ed65ddd86182723441ea74db765 (patch)
tree3bc54c369e01383cab6abe1426ed9d50f4016d78
parentcab09a81fbefcb21db5213a84461d421946f6eb8 (diff)
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>
-rw-r--r--fs/xfs/Kconfig13
-rw-r--r--fs/xfs/mrlock.h12
-rw-r--r--fs/xfs/xfs.h5
-rw-r--r--fs/xfs/xfs_alloc_btree.c4
-rw-r--r--fs/xfs/xfs_bmap_btree.c4
-rw-r--r--fs/xfs/xfs_btree.h2
-rw-r--r--fs/xfs/xfs_dir2_node.c4
-rw-r--r--fs/xfs/xfs_ialloc_btree.c4
-rw-r--r--fs/xfs/xfs_inode.c2
-rw-r--r--fs/xfs/xfs_linux.h24
-rw-r--r--fs/xfs/xfs_message.c8
-rw-r--r--fs/xfs/xfs_message.h1
-rw-r--r--fs/xfs/xfs_trans.h4
13 files changed, 63 insertions, 24 deletions
diff --git a/fs/xfs/Kconfig b/fs/xfs/Kconfig
index cc33aaf219f1..399e8cec6e60 100644
--- a/fs/xfs/Kconfig
+++ b/fs/xfs/Kconfig
@@ -69,6 +69,19 @@ config XFS_RT
69 69
70 If unsure, say N. 70 If unsure, say N.
71 71
72config 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
72config XFS_DEBUG 85config XFS_DEBUG
73 bool "XFS Debugging support" 86 bool "XFS Debugging support"
74 depends on XFS_FS 87 depends on XFS_FS
diff --git a/fs/xfs/mrlock.h b/fs/xfs/mrlock.h
index ff6a19873e5c..e3c92d19e540 100644
--- a/fs/xfs/mrlock.h
+++ b/fs/xfs/mrlock.h
@@ -22,12 +22,12 @@
22 22
23typedef struct { 23typedef struct {
24 struct rw_semaphore mr_lock; 24 struct rw_semaphore mr_lock;
25#ifdef DEBUG 25#if defined(DEBUG) || defined(XFS_WARN)
26 int mr_writer; 26 int mr_writer;
27#endif 27#endif
28} mrlock_t; 28} mrlock_t;
29 29
30#ifdef DEBUG 30#if defined(DEBUG) || defined(XFS_WARN)
31#define mrinit(mrp, name) \ 31#define mrinit(mrp, name) \
32 do { (mrp)->mr_writer = 0; init_rwsem(&(mrp)->mr_lock); } while (0) 32 do { (mrp)->mr_writer = 0; init_rwsem(&(mrp)->mr_lock); } while (0)
33#else 33#else
@@ -46,7 +46,7 @@ static inline void mraccess_nested(mrlock_t *mrp, int subclass)
46static inline void mrupdate_nested(mrlock_t *mrp, int subclass) 46static inline void mrupdate_nested(mrlock_t *mrp, int subclass)
47{ 47{
48 down_write_nested(&mrp->mr_lock, subclass); 48 down_write_nested(&mrp->mr_lock, subclass);
49#ifdef DEBUG 49#if defined(DEBUG) || defined(XFS_WARN)
50 mrp->mr_writer = 1; 50 mrp->mr_writer = 1;
51#endif 51#endif
52} 52}
@@ -60,7 +60,7 @@ static inline int mrtryupdate(mrlock_t *mrp)
60{ 60{
61 if (!down_write_trylock(&mrp->mr_lock)) 61 if (!down_write_trylock(&mrp->mr_lock))
62 return 0; 62 return 0;
63#ifdef DEBUG 63#if defined(DEBUG) || defined(XFS_WARN)
64 mrp->mr_writer = 1; 64 mrp->mr_writer = 1;
65#endif 65#endif
66 return 1; 66 return 1;
@@ -68,7 +68,7 @@ static inline int mrtryupdate(mrlock_t *mrp)
68 68
69static inline void mrunlock_excl(mrlock_t *mrp) 69static inline void mrunlock_excl(mrlock_t *mrp)
70{ 70{
71#ifdef DEBUG 71#if defined(DEBUG) || defined(XFS_WARN)
72 mrp->mr_writer = 0; 72 mrp->mr_writer = 0;
73#endif 73#endif
74 up_write(&mrp->mr_lock); 74 up_write(&mrp->mr_lock);
@@ -81,7 +81,7 @@ static inline void mrunlock_shared(mrlock_t *mrp)
81 81
82static inline void mrdemote(mrlock_t *mrp) 82static inline void mrdemote(mrlock_t *mrp)
83{ 83{
84#ifdef DEBUG 84#if defined(DEBUG) || defined(XFS_WARN)
85 mrp->mr_writer = 0; 85 mrp->mr_writer = 0;
86#endif 86#endif
87 downgrade_write(&mrp->mr_lock); 87 downgrade_write(&mrp->mr_lock);
diff --git a/fs/xfs/xfs.h b/fs/xfs/xfs.h
index d8b11b7f94aa..a742c47f7d5a 100644
--- a/fs/xfs/xfs.h
+++ b/fs/xfs/xfs.h
@@ -24,6 +24,11 @@
24#define XFS_BUF_LOCK_TRACKING 1 24#define XFS_BUF_LOCK_TRACKING 1
25#endif 25#endif
26 26
27#ifdef CONFIG_XFS_WARN
28#define XFS_WARN 1
29#endif
30
31
27#include "xfs_linux.h" 32#include "xfs_linux.h"
28 33
29#endif /* __XFS_H__ */ 34#endif /* __XFS_H__ */
diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c
index 30c4c1434faf..cafc90251d19 100644
--- a/fs/xfs/xfs_alloc_btree.c
+++ b/fs/xfs/xfs_alloc_btree.c
@@ -386,7 +386,7 @@ const struct xfs_buf_ops xfs_allocbt_buf_ops = {
386}; 386};
387 387
388 388
389#ifdef DEBUG 389#if defined(DEBUG) || defined(XFS_WARN)
390STATIC int 390STATIC int
391xfs_allocbt_keys_inorder( 391xfs_allocbt_keys_inorder(
392 struct xfs_btree_cur *cur, 392 struct xfs_btree_cur *cur,
@@ -442,7 +442,7 @@ static const struct xfs_btree_ops xfs_allocbt_ops = {
442 .init_ptr_from_cur = xfs_allocbt_init_ptr_from_cur, 442 .init_ptr_from_cur = xfs_allocbt_init_ptr_from_cur,
443 .key_diff = xfs_allocbt_key_diff, 443 .key_diff = xfs_allocbt_key_diff,
444 .buf_ops = &xfs_allocbt_buf_ops, 444 .buf_ops = &xfs_allocbt_buf_ops,
445#ifdef DEBUG 445#if defined(DEBUG) || defined(XFS_WARN)
446 .keys_inorder = xfs_allocbt_keys_inorder, 446 .keys_inorder = xfs_allocbt_keys_inorder,
447 .recs_inorder = xfs_allocbt_recs_inorder, 447 .recs_inorder = xfs_allocbt_recs_inorder,
448#endif 448#endif
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c
index 3a86c3fa6de1..0c61a22be6fd 100644
--- a/fs/xfs/xfs_bmap_btree.c
+++ b/fs/xfs/xfs_bmap_btree.c
@@ -813,7 +813,7 @@ const struct xfs_buf_ops xfs_bmbt_buf_ops = {
813}; 813};
814 814
815 815
816#ifdef DEBUG 816#if defined(DEBUG) || defined(XFS_WARN)
817STATIC int 817STATIC int
818xfs_bmbt_keys_inorder( 818xfs_bmbt_keys_inorder(
819 struct xfs_btree_cur *cur, 819 struct xfs_btree_cur *cur,
@@ -853,7 +853,7 @@ static const struct xfs_btree_ops xfs_bmbt_ops = {
853 .init_ptr_from_cur = xfs_bmbt_init_ptr_from_cur, 853 .init_ptr_from_cur = xfs_bmbt_init_ptr_from_cur,
854 .key_diff = xfs_bmbt_key_diff, 854 .key_diff = xfs_bmbt_key_diff,
855 .buf_ops = &xfs_bmbt_buf_ops, 855 .buf_ops = &xfs_bmbt_buf_ops,
856#ifdef DEBUG 856#if defined(DEBUG) || defined(XFS_WARN)
857 .keys_inorder = xfs_bmbt_keys_inorder, 857 .keys_inorder = xfs_bmbt_keys_inorder,
858 .recs_inorder = xfs_bmbt_recs_inorder, 858 .recs_inorder = xfs_bmbt_recs_inorder,
859#endif 859#endif
diff --git a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h
index 6e6c915673fe..55e3c7cc3c3d 100644
--- a/fs/xfs/xfs_btree.h
+++ b/fs/xfs/xfs_btree.h
@@ -215,7 +215,7 @@ struct xfs_btree_ops {
215 215
216 const struct xfs_buf_ops *buf_ops; 216 const struct xfs_buf_ops *buf_ops;
217 217
218#ifdef DEBUG 218#if defined(DEBUG) || defined(XFS_WARN)
219 /* check that k1 is lower than k2 */ 219 /* check that k1 is lower than k2 */
220 int (*keys_inorder)(struct xfs_btree_cur *cur, 220 int (*keys_inorder)(struct xfs_btree_cur *cur,
221 union xfs_btree_key *k1, 221 union xfs_btree_key *k1,
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c
index ecc6c661064c..5246de4912d4 100644
--- a/fs/xfs/xfs_dir2_node.c
+++ b/fs/xfs/xfs_dir2_node.c
@@ -993,7 +993,7 @@ xfs_dir2_leafn_rebalance(
993 xfs_dir2_leaf_t *leaf1; /* first leaf structure */ 993 xfs_dir2_leaf_t *leaf1; /* first leaf structure */
994 xfs_dir2_leaf_t *leaf2; /* second leaf structure */ 994 xfs_dir2_leaf_t *leaf2; /* second leaf structure */
995 int mid; /* midpoint leaf index */ 995 int mid; /* midpoint leaf index */
996#ifdef DEBUG 996#if defined(DEBUG) || defined(XFS_WARN)
997 int oldstale; /* old count of stale leaves */ 997 int oldstale; /* old count of stale leaves */
998#endif 998#endif
999 int oldsum; /* old total leaf count */ 999 int oldsum; /* old total leaf count */
@@ -1022,7 +1022,7 @@ xfs_dir2_leafn_rebalance(
1022 ents2 = xfs_dir3_leaf_ents_p(leaf2); 1022 ents2 = xfs_dir3_leaf_ents_p(leaf2);
1023 1023
1024 oldsum = hdr1.count + hdr2.count; 1024 oldsum = hdr1.count + hdr2.count;
1025#ifdef DEBUG 1025#if defined(DEBUG) || defined(XFS_WARN)
1026 oldstale = hdr1.stale + hdr2.stale; 1026 oldstale = hdr1.stale + hdr2.stale;
1027#endif 1027#endif
1028 mid = oldsum >> 1; 1028 mid = oldsum >> 1;
diff --git a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c
index c82ac8867421..5448eb6b8c12 100644
--- a/fs/xfs/xfs_ialloc_btree.c
+++ b/fs/xfs/xfs_ialloc_btree.c
@@ -272,7 +272,7 @@ const struct xfs_buf_ops xfs_inobt_buf_ops = {
272 .verify_write = xfs_inobt_write_verify, 272 .verify_write = xfs_inobt_write_verify,
273}; 273};
274 274
275#ifdef DEBUG 275#if defined(DEBUG) || defined(XFS_WARN)
276STATIC int 276STATIC int
277xfs_inobt_keys_inorder( 277xfs_inobt_keys_inorder(
278 struct xfs_btree_cur *cur, 278 struct xfs_btree_cur *cur,
@@ -310,7 +310,7 @@ static const struct xfs_btree_ops xfs_inobt_ops = {
310 .init_ptr_from_cur = xfs_inobt_init_ptr_from_cur, 310 .init_ptr_from_cur = xfs_inobt_init_ptr_from_cur,
311 .key_diff = xfs_inobt_key_diff, 311 .key_diff = xfs_inobt_key_diff,
312 .buf_ops = &xfs_inobt_buf_ops, 312 .buf_ops = &xfs_inobt_buf_ops,
313#ifdef DEBUG 313#if defined(DEBUG) || defined(XFS_WARN)
314 .keys_inorder = xfs_inobt_keys_inorder, 314 .keys_inorder = xfs_inobt_keys_inorder,
315 .recs_inorder = xfs_inobt_recs_inorder, 315 .recs_inorder = xfs_inobt_recs_inorder,
316#endif 316#endif
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 558ef4947206..efbe1accb6ca 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -287,7 +287,7 @@ xfs_ilock_demote(
287 trace_xfs_ilock_demote(ip, lock_flags, _RET_IP_); 287 trace_xfs_ilock_demote(ip, lock_flags, _RET_IP_);
288} 288}
289 289
290#ifdef DEBUG 290#if defined(DEBUG) || defined(XFS_WARN)
291int 291int
292xfs_isilocked( 292xfs_isilocked(
293 xfs_inode_t *ip, 293 xfs_inode_t *ip,
diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h
index 14e59d953b7b..800f896a6cc4 100644
--- a/fs/xfs/xfs_linux.h
+++ b/fs/xfs/xfs_linux.h
@@ -293,22 +293,34 @@ static inline __uint64_t howmany_64(__uint64_t x, __uint32_t y)
293#define ASSERT_ALWAYS(expr) \ 293#define ASSERT_ALWAYS(expr) \
294 (unlikely(expr) ? (void)0 : assfail(#expr, __FILE__, __LINE__)) 294 (unlikely(expr) ? (void)0 : assfail(#expr, __FILE__, __LINE__))
295 295
296#ifndef DEBUG 296#ifdef DEBUG
297#define ASSERT(expr) ((void)0) 297#define ASSERT(expr) \
298 (unlikely(expr) ? (void)0 : assfail(#expr, __FILE__, __LINE__))
298 299
299#ifndef STATIC 300#ifndef STATIC
300# define STATIC static noinline 301# define STATIC noinline
301#endif 302#endif
302 303
303#else /* DEBUG */ 304#else /* !DEBUG */
305
306#ifdef XFS_WARN
304 307
305#define ASSERT(expr) \ 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#ifndef STATIC 311#ifndef STATIC
309# define STATIC noinline 312# define STATIC static noinline
313#endif
314
315#else /* !DEBUG && !XFS_WARN */
316
317#define ASSERT(expr) ((void)0)
318
319#ifndef STATIC
320# define STATIC static noinline
310#endif 321#endif
311 322
323#endif /* XFS_WARN */
312#endif /* DEBUG */ 324#endif /* DEBUG */
313 325
314#endif /* __XFS_LINUX__ */ 326#endif /* __XFS_LINUX__ */
diff --git a/fs/xfs/xfs_message.c b/fs/xfs/xfs_message.c
index 331cd9f83a7f..9163dc140532 100644
--- a/fs/xfs/xfs_message.c
+++ b/fs/xfs/xfs_message.c
@@ -93,6 +93,14 @@ xfs_alert_tag(
93} 93}
94 94
95void 95void
96asswarn(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
103void
96assfail(char *expr, char *file, int line) 104assfail(char *expr, char *file, int line)
97{ 105{
98 xfs_emerg(NULL, "Assertion failed: %s, file: %s, line: %d", 106 xfs_emerg(NULL, "Assertion failed: %s, file: %s, line: %d",
diff --git a/fs/xfs/xfs_message.h b/fs/xfs/xfs_message.h
index 76c81982f964..85401155750e 100644
--- a/fs/xfs/xfs_message.h
+++ b/fs/xfs/xfs_message.h
@@ -57,6 +57,7 @@ do { \
57 xfs_printk_ratelimited(xfs_debug, dev, fmt, ##__VA_ARGS__) 57 xfs_printk_ratelimited(xfs_debug, dev, fmt, ##__VA_ARGS__)
58 58
59extern void assfail(char *expr, char *f, int l); 59extern void assfail(char *expr, char *f, int l);
60extern void asswarn(char *expr, char *f, int l);
60 61
61extern void xfs_hex_dump(void *p, int length); 62extern void xfs_hex_dump(void *p, int length);
62 63
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index cd29f6171021..a44dba5b2cdb 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -405,7 +405,7 @@ typedef struct xfs_trans {
405 int64_t t_res_fdblocks_delta; /* on-disk only chg */ 405 int64_t t_res_fdblocks_delta; /* on-disk only chg */
406 int64_t t_frextents_delta;/* superblock freextents chg*/ 406 int64_t t_frextents_delta;/* superblock freextents chg*/
407 int64_t t_res_frextents_delta; /* on-disk only chg */ 407 int64_t t_res_frextents_delta; /* on-disk only chg */
408#ifdef DEBUG 408#if defined(DEBUG) || defined(XFS_WARN)
409 int64_t t_ag_freeblks_delta; /* debugging counter */ 409 int64_t t_ag_freeblks_delta; /* debugging counter */
410 int64_t t_ag_flist_delta; /* debugging counter */ 410 int64_t t_ag_flist_delta; /* debugging counter */
411 int64_t t_ag_btree_delta; /* debugging counter */ 411 int64_t t_ag_btree_delta; /* debugging counter */
@@ -433,7 +433,7 @@ typedef struct xfs_trans {
433#define xfs_trans_get_block_res(tp) ((tp)->t_blk_res) 433#define xfs_trans_get_block_res(tp) ((tp)->t_blk_res)
434#define xfs_trans_set_sync(tp) ((tp)->t_flags |= XFS_TRANS_SYNC) 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#define xfs_trans_agblocks_delta(tp, d) ((tp)->t_ag_freeblks_delta += (int64_t)d) 437#define xfs_trans_agblocks_delta(tp, d) ((tp)->t_ag_freeblks_delta += (int64_t)d)
438#define xfs_trans_agflist_delta(tp, d) ((tp)->t_ag_flist_delta += (int64_t)d) 438#define xfs_trans_agflist_delta(tp, d) ((tp)->t_ag_flist_delta += (int64_t)d)
439#define xfs_trans_agbtree_delta(tp, d) ((tp)->t_ag_btree_delta += (int64_t)d) 439#define xfs_trans_agbtree_delta(tp, d) ((tp)->t_ag_btree_delta += (int64_t)d)