aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/filesystems/ubifs.txt26
-rw-r--r--fs/ubifs/debug.c140
-rw-r--r--fs/ubifs/debug.h72
3 files changed, 159 insertions, 79 deletions
diff --git a/Documentation/filesystems/ubifs.txt b/Documentation/filesystems/ubifs.txt
index 91ef07652cd..a0a61d2f389 100644
--- a/Documentation/filesystems/ubifs.txt
+++ b/Documentation/filesystems/ubifs.txt
@@ -111,32 +111,6 @@ The following is an example of the kernel boot arguments to attach mtd0
111to UBI and mount volume "rootfs": 111to UBI and mount volume "rootfs":
112ubi.mtd=0 root=ubi0:rootfs rootfstype=ubifs 112ubi.mtd=0 root=ubi0:rootfs rootfstype=ubifs
113 113
114
115Module Parameters for Debugging
116===============================
117
118When UBIFS has been compiled with debugging enabled, there are 2 module
119parameters that are available to control aspects of testing and debugging.
120
121debug_chks Selects extra checks that UBIFS can do while running:
122
123 Check Flag value
124
125 General checks 1
126 Check the index 2
127 Check orphan area 8
128 Check LEB properties (lprops) 32
129 Check leaf nodes and inodes 64
130
131debug_tsts Selects a mode of testing, as follows:
132
133 Test mode Flag value
134
135 Failure mode for recovery testing 4
136
137For example, set debug_chks to 3 to enable general and TNC checks.
138
139
140References 114References
141========== 115==========
142 116
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index a967d6800ea..fdfa5dea5b9 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -31,9 +31,9 @@
31 31
32#include "ubifs.h" 32#include "ubifs.h"
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/moduleparam.h>
35#include <linux/debugfs.h> 34#include <linux/debugfs.h>
36#include <linux/math64.h> 35#include <linux/math64.h>
36#include <linux/uaccess.h>
37 37
38#ifdef CONFIG_UBIFS_FS_DEBUG 38#ifdef CONFIG_UBIFS_FS_DEBUG
39 39
@@ -42,15 +42,6 @@ DEFINE_SPINLOCK(dbg_lock);
42static char dbg_key_buf0[128]; 42static char dbg_key_buf0[128];
43static char dbg_key_buf1[128]; 43static char dbg_key_buf1[128];
44 44
45unsigned int ubifs_chk_flags;
46unsigned int ubifs_tst_flags;
47
48module_param_named(debug_chks, ubifs_chk_flags, uint, S_IRUGO | S_IWUSR);
49module_param_named(debug_tsts, ubifs_tst_flags, uint, S_IRUGO | S_IWUSR);
50
51MODULE_PARM_DESC(debug_chks, "Debug check flags");
52MODULE_PARM_DESC(debug_tsts, "Debug special test flags");
53
54static const char *get_key_fmt(int fmt) 45static const char *get_key_fmt(int fmt)
55{ 46{
56 switch (fmt) { 47 switch (fmt) {
@@ -2886,21 +2877,93 @@ static int open_debugfs_file(struct inode *inode, struct file *file)
2886 return nonseekable_open(inode, file); 2877 return nonseekable_open(inode, file);
2887} 2878}
2888 2879
2889static ssize_t write_debugfs_file(struct file *file, const char __user *buf, 2880static ssize_t dfs_file_read(struct file *file, char __user *u, size_t count,
2890 size_t count, loff_t *ppos) 2881 loff_t *ppos)
2882{
2883 struct dentry *dent = file->f_path.dentry;
2884 struct ubifs_info *c = file->private_data;
2885 struct ubifs_debug_info *d = c->dbg;
2886 char buf[3];
2887 int val;
2888
2889 if (dent == d->dfs_chk_gen)
2890 val = d->chk_gen;
2891 else if (dent == d->dfs_chk_index)
2892 val = d->chk_index;
2893 else if (dent == d->dfs_chk_orph)
2894 val = d->chk_orph;
2895 else if (dent == d->dfs_chk_lprops)
2896 val = d->chk_lprops;
2897 else if (dent == d->dfs_chk_fs)
2898 val = d->chk_fs;
2899 else if (dent == d->dfs_tst_rcvry)
2900 val = d->tst_rcvry;
2901 else
2902 return -EINVAL;
2903
2904 if (val)
2905 buf[0] = '1';
2906 else
2907 buf[0] = '0';
2908 buf[1] = '\n';
2909 buf[2] = 0x00;
2910
2911 return simple_read_from_buffer(u, count, ppos, buf, 2);
2912}
2913
2914static ssize_t dfs_file_write(struct file *file, const char __user *u,
2915 size_t count, loff_t *ppos)
2891{ 2916{
2892 struct ubifs_info *c = file->private_data; 2917 struct ubifs_info *c = file->private_data;
2893 struct ubifs_debug_info *d = c->dbg; 2918 struct ubifs_debug_info *d = c->dbg;
2919 struct dentry *dent = file->f_path.dentry;
2920 size_t buf_size;
2921 char buf[8];
2922 int val;
2894 2923
2895 if (file->f_path.dentry == d->dfs_dump_lprops) 2924 /*
2925 * FIXME: this is racy - the file-system might have already been
2926 * unmounted and we'd oops in this case.
2927 */
2928 if (file->f_path.dentry == d->dfs_dump_lprops) {
2896 dbg_dump_lprops(c); 2929 dbg_dump_lprops(c);
2897 else if (file->f_path.dentry == d->dfs_dump_budg) 2930 return count;
2931 }
2932 if (file->f_path.dentry == d->dfs_dump_budg) {
2898 dbg_dump_budg(c, &c->bi); 2933 dbg_dump_budg(c, &c->bi);
2899 else if (file->f_path.dentry == d->dfs_dump_tnc) { 2934 return count;
2935 }
2936 if (file->f_path.dentry == d->dfs_dump_tnc) {
2900 mutex_lock(&c->tnc_mutex); 2937 mutex_lock(&c->tnc_mutex);
2901 dbg_dump_tnc(c); 2938 dbg_dump_tnc(c);
2902 mutex_unlock(&c->tnc_mutex); 2939 mutex_unlock(&c->tnc_mutex);
2903 } else 2940 return count;
2941 }
2942
2943 buf_size = min_t(size_t, count, (sizeof(buf) - 1));
2944 if (copy_from_user(buf, u, buf_size))
2945 return -EFAULT;
2946
2947 if (buf[0] == '1')
2948 val = 1;
2949 else if (buf[0] == '0')
2950 val = 0;
2951 else
2952 return -EINVAL;
2953
2954 if (dent == d->dfs_chk_gen)
2955 d->chk_gen = val;
2956 else if (dent == d->dfs_chk_index)
2957 d->chk_index = val;
2958 else if (dent == d->dfs_chk_orph)
2959 d->chk_orph = val;
2960 else if (dent == d->dfs_chk_lprops)
2961 d->chk_lprops = val;
2962 else if (dent == d->dfs_chk_fs)
2963 d->chk_fs = val;
2964 else if (dent == d->dfs_tst_rcvry)
2965 d->tst_rcvry = val;
2966 else
2904 return -EINVAL; 2967 return -EINVAL;
2905 2968
2906 return count; 2969 return count;
@@ -2908,7 +2971,8 @@ static ssize_t write_debugfs_file(struct file *file, const char __user *buf,
2908 2971
2909static const struct file_operations dfs_fops = { 2972static const struct file_operations dfs_fops = {
2910 .open = open_debugfs_file, 2973 .open = open_debugfs_file,
2911 .write = write_debugfs_file, 2974 .read = dfs_file_read,
2975 .write = dfs_file_write,
2912 .owner = THIS_MODULE, 2976 .owner = THIS_MODULE,
2913 .llseek = no_llseek, 2977 .llseek = no_llseek,
2914}; 2978};
@@ -2965,6 +3029,48 @@ int dbg_debugfs_init_fs(struct ubifs_info *c)
2965 goto out_remove; 3029 goto out_remove;
2966 d->dfs_dump_tnc = dent; 3030 d->dfs_dump_tnc = dent;
2967 3031
3032 fname = "chk_general";
3033 dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c,
3034 &dfs_fops);
3035 if (IS_ERR_OR_NULL(dent))
3036 goto out_remove;
3037 d->dfs_chk_gen = dent;
3038
3039 fname = "chk_index";
3040 dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c,
3041 &dfs_fops);
3042 if (IS_ERR_OR_NULL(dent))
3043 goto out_remove;
3044 d->dfs_chk_index = dent;
3045
3046 fname = "chk_orphans";
3047 dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c,
3048 &dfs_fops);
3049 if (IS_ERR_OR_NULL(dent))
3050 goto out_remove;
3051 d->dfs_chk_orph = dent;
3052
3053 fname = "chk_lprops";
3054 dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c,
3055 &dfs_fops);
3056 if (IS_ERR_OR_NULL(dent))
3057 goto out_remove;
3058 d->dfs_chk_lprops = dent;
3059
3060 fname = "chk_fs";
3061 dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c,
3062 &dfs_fops);
3063 if (IS_ERR_OR_NULL(dent))
3064 goto out_remove;
3065 d->dfs_chk_fs = dent;
3066
3067 fname = "tst_recovery";
3068 dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c,
3069 &dfs_fops);
3070 if (IS_ERR_OR_NULL(dent))
3071 goto out_remove;
3072 d->dfs_tst_rcvry = dent;
3073
2968 return 0; 3074 return 0;
2969 3075
2970out_remove: 3076out_remove:
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h
index 44265a3a08c..8c3bdd37803 100644
--- a/fs/ubifs/debug.h
+++ b/fs/ubifs/debug.h
@@ -43,11 +43,13 @@ typedef int (*dbg_znode_callback)(struct ubifs_info *c,
43 * @old_zroot: old index root - used by 'dbg_check_old_index()' 43 * @old_zroot: old index root - used by 'dbg_check_old_index()'
44 * @old_zroot_level: old index root level - used by 'dbg_check_old_index()' 44 * @old_zroot_level: old index root level - used by 'dbg_check_old_index()'
45 * @old_zroot_sqnum: old index root sqnum - used by 'dbg_check_old_index()' 45 * @old_zroot_sqnum: old index root sqnum - used by 'dbg_check_old_index()'
46 *
46 * @failure_mode: failure mode for recovery testing 47 * @failure_mode: failure mode for recovery testing
47 * @fail_delay: 0=>don't delay, 1=>delay a time, 2=>delay a number of calls 48 * @fail_delay: 0=>don't delay, 1=>delay a time, 2=>delay a number of calls
48 * @fail_timeout: time in jiffies when delay of failure mode expires 49 * @fail_timeout: time in jiffies when delay of failure mode expires
49 * @fail_cnt: current number of calls to failure mode I/O functions 50 * @fail_cnt: current number of calls to failure mode I/O functions
50 * @fail_cnt_max: number of calls by which to delay failure mode 51 * @fail_cnt_max: number of calls by which to delay failure mode
52 *
51 * @chk_lpt_sz: used by LPT tree size checker 53 * @chk_lpt_sz: used by LPT tree size checker
52 * @chk_lpt_sz2: used by LPT tree size checker 54 * @chk_lpt_sz2: used by LPT tree size checker
53 * @chk_lpt_wastage: used by LPT tree size checker 55 * @chk_lpt_wastage: used by LPT tree size checker
@@ -61,21 +63,36 @@ typedef int (*dbg_znode_callback)(struct ubifs_info *c,
61 * @saved_free: saved amount of free space 63 * @saved_free: saved amount of free space
62 * @saved_idx_gc_cnt: saved value of @c->idx_gc_cnt 64 * @saved_idx_gc_cnt: saved value of @c->idx_gc_cnt
63 * 65 *
66 * @chk_gen: if general extra checks are enabled
67 * @chk_index: if index xtra checks are enabled
68 * @chk_orph: if orphans extra checks are enabled
69 * @chk_lprops: if lprops extra checks are enabled
70 * @chk_fs: if UBIFS contents extra checks are enabled
71 * @tst_rcvry: if UBIFS recovery testing mode enabled
72 *
64 * @dfs_dir_name: name of debugfs directory containing this file-system's files 73 * @dfs_dir_name: name of debugfs directory containing this file-system's files
65 * @dfs_dir: direntry object of the file-system debugfs directory 74 * @dfs_dir: direntry object of the file-system debugfs directory
66 * @dfs_dump_lprops: "dump lprops" debugfs knob 75 * @dfs_dump_lprops: "dump lprops" debugfs knob
67 * @dfs_dump_budg: "dump budgeting information" debugfs knob 76 * @dfs_dump_budg: "dump budgeting information" debugfs knob
68 * @dfs_dump_tnc: "dump TNC" debugfs knob 77 * @dfs_dump_tnc: "dump TNC" debugfs knob
78 * @dfs_chk_gen: debugfs knob to enable UBIFS general extra checks
79 * @dfs_chk_index: debugfs knob to enable UBIFS index extra checks
80 * @dfs_chk_orph: debugfs knob to enable UBIFS orphans extra checks
81 * @dfs_chk_lprops: debugfs knob to enable UBIFS LEP properties extra checks
82 * @dfs_chk_fs: debugfs knob to enable UBIFS contents extra checks
83 * @dfs_tst_rcvry: debugfs knob to enable UBIFS recovery testing
69 */ 84 */
70struct ubifs_debug_info { 85struct ubifs_debug_info {
71 struct ubifs_zbranch old_zroot; 86 struct ubifs_zbranch old_zroot;
72 int old_zroot_level; 87 int old_zroot_level;
73 unsigned long long old_zroot_sqnum; 88 unsigned long long old_zroot_sqnum;
89
74 int failure_mode; 90 int failure_mode;
75 int fail_delay; 91 int fail_delay;
76 unsigned long fail_timeout; 92 unsigned long fail_timeout;
77 unsigned int fail_cnt; 93 unsigned int fail_cnt;
78 unsigned int fail_cnt_max; 94 unsigned int fail_cnt_max;
95
79 long long chk_lpt_sz; 96 long long chk_lpt_sz;
80 long long chk_lpt_sz2; 97 long long chk_lpt_sz2;
81 long long chk_lpt_wastage; 98 long long chk_lpt_wastage;
@@ -89,11 +106,24 @@ struct ubifs_debug_info {
89 long long saved_free; 106 long long saved_free;
90 int saved_idx_gc_cnt; 107 int saved_idx_gc_cnt;
91 108
109 unsigned int chk_gen:1;
110 unsigned int chk_index:1;
111 unsigned int chk_orph:1;
112 unsigned int chk_lprops:1;
113 unsigned int chk_fs:1;
114 unsigned int tst_rcvry:1;
115
92 char dfs_dir_name[UBIFS_DFS_DIR_LEN + 1]; 116 char dfs_dir_name[UBIFS_DFS_DIR_LEN + 1];
93 struct dentry *dfs_dir; 117 struct dentry *dfs_dir;
94 struct dentry *dfs_dump_lprops; 118 struct dentry *dfs_dump_lprops;
95 struct dentry *dfs_dump_budg; 119 struct dentry *dfs_dump_budg;
96 struct dentry *dfs_dump_tnc; 120 struct dentry *dfs_dump_tnc;
121 struct dentry *dfs_chk_gen;
122 struct dentry *dfs_chk_index;
123 struct dentry *dfs_chk_orph;
124 struct dentry *dfs_chk_lprops;
125 struct dentry *dfs_chk_fs;
126 struct dentry *dfs_tst_rcvry;
97}; 127};
98 128
99#define ubifs_assert(expr) do { \ 129#define ubifs_assert(expr) do { \
@@ -169,59 +199,29 @@ const char *dbg_key_str1(const struct ubifs_info *c,
169 199
170extern spinlock_t dbg_lock; 200extern spinlock_t dbg_lock;
171 201
172/*
173 * Debugging check flags.
174 *
175 * UBIFS_CHK_GEN: general checks
176 * UBIFS_CHK_INDEX: check the index
177 * UBIFS_CHK_ORPH: check orphans
178 * UBIFS_CHK_LPROPS: check lprops
179 * UBIFS_CHK_FS: check the file-system
180 */
181enum {
182 UBIFS_CHK_GEN = 0x1,
183 UBIFS_CHK_INDEX = 0x2,
184 UBIFS_CHK_ORPH = 0x8,
185 UBIFS_CHK_LPROPS = 0x20,
186 UBIFS_CHK_FS = 0x40,
187};
188
189/*
190 * Special testing flags.
191 *
192 * UBIFS_TST_RCVRY: failure mode for recovery testing
193 */
194enum {
195 UBIFS_TST_RCVRY = 0x4,
196};
197
198extern unsigned int ubifs_msg_flags;
199extern unsigned int ubifs_chk_flags;
200extern unsigned int ubifs_tst_flags;
201
202static inline int dbg_is_chk_gen(const struct ubifs_info *c) 202static inline int dbg_is_chk_gen(const struct ubifs_info *c)
203{ 203{
204 return !!(ubifs_chk_flags & UBIFS_CHK_GEN); 204 return c->dbg->chk_gen;
205} 205}
206static inline int dbg_is_chk_index(const struct ubifs_info *c) 206static inline int dbg_is_chk_index(const struct ubifs_info *c)
207{ 207{
208 return !!(ubifs_chk_flags & UBIFS_CHK_INDEX); 208 return c->dbg->chk_index;
209} 209}
210static inline int dbg_is_chk_orph(const struct ubifs_info *c) 210static inline int dbg_is_chk_orph(const struct ubifs_info *c)
211{ 211{
212 return !!(ubifs_chk_flags & UBIFS_CHK_ORPH); 212 return c->dbg->chk_orph;
213} 213}
214static inline int dbg_is_chk_lprops(const struct ubifs_info *c) 214static inline int dbg_is_chk_lprops(const struct ubifs_info *c)
215{ 215{
216 return !!(ubifs_chk_flags & UBIFS_CHK_LPROPS); 216 return c->dbg->chk_lprops;
217} 217}
218static inline int dbg_is_chk_fs(const struct ubifs_info *c) 218static inline int dbg_is_chk_fs(const struct ubifs_info *c)
219{ 219{
220 return !!(ubifs_chk_flags & UBIFS_CHK_FS); 220 return c->dbg->chk_fs;
221} 221}
222static inline int dbg_is_tst_rcvry(const struct ubifs_info *c) 222static inline int dbg_is_tst_rcvry(const struct ubifs_info *c)
223{ 223{
224 return !!(ubifs_tst_flags & UBIFS_TST_RCVRY); 224 return c->dbg->tst_rcvry;
225} 225}
226 226
227int ubifs_debugging_init(struct ubifs_info *c); 227int ubifs_debugging_init(struct ubifs_info *c);