aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ubifs
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2011-06-01 10:43:43 -0400
committerArtem Bityutskiy <dedekind1@gmail.com>2011-07-04 03:54:32 -0400
commite7717060ddd509e6c305ad7bf5a090a95e91c8cf (patch)
tree03869be56858dfc5226a94129d528714838e4dc0 /fs/ubifs
parent28488fc28aa39815b78c2cbeaaf25f33fef92ce8 (diff)
UBIFS: add global debugfs knobs
Now we have per-FS (superblock) debugfs knobs, but they have one drawback - you have to first mount the FS and only after this you can switch self-checks on/off. But often we want to have the checks enabled during the mount. Introduce global debugging knobs for this purpose. Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'fs/ubifs')
-rw-r--r--fs/ubifs/debug.c138
-rw-r--r--fs/ubifs/debug.h35
2 files changed, 157 insertions, 16 deletions
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index b98638eb0fcb..15bec635bf3e 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -3064,7 +3064,7 @@ out_remove:
3064 debugfs_remove_recursive(d->dfs_dir); 3064 debugfs_remove_recursive(d->dfs_dir);
3065out: 3065out:
3066 err = dent ? PTR_ERR(dent) : -ENODEV; 3066 err = dent ? PTR_ERR(dent) : -ENODEV;
3067 ubifs_err("cannot create \"%s\" debugfs filr or directory, error %d\n", 3067 ubifs_err("cannot create \"%s\" debugfs file or directory, error %d\n",
3068 fname, err); 3068 fname, err);
3069 return err; 3069 return err;
3070} 3070}
@@ -3078,6 +3078,74 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c)
3078 debugfs_remove_recursive(c->dbg->dfs_dir); 3078 debugfs_remove_recursive(c->dbg->dfs_dir);
3079} 3079}
3080 3080
3081struct ubifs_global_debug_info ubifs_dbg;
3082
3083static struct dentry *dfs_chk_gen;
3084static struct dentry *dfs_chk_index;
3085static struct dentry *dfs_chk_orph;
3086static struct dentry *dfs_chk_lprops;
3087static struct dentry *dfs_chk_fs;
3088static struct dentry *dfs_tst_rcvry;
3089
3090static ssize_t dfs_global_file_read(struct file *file, char __user *u,
3091 size_t count, loff_t *ppos)
3092{
3093 struct dentry *dent = file->f_path.dentry;
3094 int val;
3095
3096 if (dent == dfs_chk_gen)
3097 val = ubifs_dbg.chk_gen;
3098 else if (dent == dfs_chk_index)
3099 val = ubifs_dbg.chk_index;
3100 else if (dent == dfs_chk_orph)
3101 val = ubifs_dbg.chk_orph;
3102 else if (dent == dfs_chk_lprops)
3103 val = ubifs_dbg.chk_lprops;
3104 else if (dent == dfs_chk_fs)
3105 val = ubifs_dbg.chk_fs;
3106 else if (dent == dfs_tst_rcvry)
3107 val = ubifs_dbg.tst_rcvry;
3108 else
3109 return -EINVAL;
3110
3111 return provide_user_output(val, u, count, ppos);
3112}
3113
3114static ssize_t dfs_global_file_write(struct file *file, const char __user *u,
3115 size_t count, loff_t *ppos)
3116{
3117 struct dentry *dent = file->f_path.dentry;
3118 int val;
3119
3120 val = interpret_user_input(u, count);
3121 if (val < 0)
3122 return val;
3123
3124 if (dent == dfs_chk_gen)
3125 ubifs_dbg.chk_gen = val;
3126 else if (dent == dfs_chk_index)
3127 ubifs_dbg.chk_index = val;
3128 else if (dent == dfs_chk_orph)
3129 ubifs_dbg.chk_orph = val;
3130 else if (dent == dfs_chk_lprops)
3131 ubifs_dbg.chk_lprops = val;
3132 else if (dent == dfs_chk_fs)
3133 ubifs_dbg.chk_fs = val;
3134 else if (dent == dfs_tst_rcvry)
3135 ubifs_dbg.tst_rcvry = val;
3136 else
3137 return -EINVAL;
3138
3139 return count;
3140}
3141
3142static const struct file_operations dfs_global_fops = {
3143 .read = dfs_global_file_read,
3144 .write = dfs_global_file_write,
3145 .owner = THIS_MODULE,
3146 .llseek = no_llseek,
3147};
3148
3081/** 3149/**
3082 * dbg_debugfs_init - initialize debugfs file-system. 3150 * dbg_debugfs_init - initialize debugfs file-system.
3083 * 3151 *
@@ -3088,15 +3156,67 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c)
3088 */ 3156 */
3089int dbg_debugfs_init(void) 3157int dbg_debugfs_init(void)
3090{ 3158{
3091 dfs_rootdir = debugfs_create_dir("ubifs", NULL); 3159 int err;
3092 if (IS_ERR_OR_NULL(dfs_rootdir)) { 3160 const char *fname;
3093 int err = dfs_rootdir ? PTR_ERR(dfs_rootdir) : -ENODEV; 3161 struct dentry *dent;
3094 ubifs_err("cannot create \"ubifs\" debugfs directory, " 3162
3095 "error %d\n", err); 3163 fname = "ubifs";
3096 return err; 3164 dent = debugfs_create_dir(fname, NULL);
3097 } 3165 if (IS_ERR_OR_NULL(dent))
3166 goto out;
3167 dfs_rootdir = dent;
3168
3169 fname = "chk_general";
3170 dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL,
3171 &dfs_global_fops);
3172 if (IS_ERR_OR_NULL(dent))
3173 goto out_remove;
3174 dfs_chk_gen = dent;
3175
3176 fname = "chk_index";
3177 dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL,
3178 &dfs_global_fops);
3179 if (IS_ERR_OR_NULL(dent))
3180 goto out_remove;
3181 dfs_chk_index = dent;
3182
3183 fname = "chk_orphans";
3184 dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL,
3185 &dfs_global_fops);
3186 if (IS_ERR_OR_NULL(dent))
3187 goto out_remove;
3188 dfs_chk_orph = dent;
3189
3190 fname = "chk_lprops";
3191 dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL,
3192 &dfs_global_fops);
3193 if (IS_ERR_OR_NULL(dent))
3194 goto out_remove;
3195 dfs_chk_lprops = dent;
3196
3197 fname = "chk_fs";
3198 dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL,
3199 &dfs_global_fops);
3200 if (IS_ERR_OR_NULL(dent))
3201 goto out_remove;
3202 dfs_chk_fs = dent;
3203
3204 fname = "tst_recovery";
3205 dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL,
3206 &dfs_global_fops);
3207 if (IS_ERR_OR_NULL(dent))
3208 goto out_remove;
3209 dfs_tst_rcvry = dent;
3098 3210
3099 return 0; 3211 return 0;
3212
3213out_remove:
3214 debugfs_remove_recursive(dfs_rootdir);
3215out:
3216 err = dent ? PTR_ERR(dent) : -ENODEV;
3217 ubifs_err("cannot create \"%s\" debugfs file or directory, error %d\n",
3218 fname, err);
3219 return err;
3100} 3220}
3101 3221
3102/** 3222/**
@@ -3104,7 +3224,7 @@ int dbg_debugfs_init(void)
3104 */ 3224 */
3105void dbg_debugfs_exit(void) 3225void dbg_debugfs_exit(void)
3106{ 3226{
3107 debugfs_remove(dfs_rootdir); 3227 debugfs_remove_recursive(dfs_rootdir);
3108} 3228}
3109 3229
3110/** 3230/**
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h
index 8c3bdd378037..43ec5d120d7c 100644
--- a/fs/ubifs/debug.h
+++ b/fs/ubifs/debug.h
@@ -126,6 +126,25 @@ struct ubifs_debug_info {
126 struct dentry *dfs_tst_rcvry; 126 struct dentry *dfs_tst_rcvry;
127}; 127};
128 128
129/**
130 * ubifs_global_debug_info - global (not per-FS) UBIFS debugging information.
131 *
132 * @chk_gen: if general extra checks are enabled
133 * @chk_index: if index xtra checks are enabled
134 * @chk_orph: if orphans extra checks are enabled
135 * @chk_lprops: if lprops extra checks are enabled
136 * @chk_fs: if UBIFS contents extra checks are enabled
137 * @tst_rcvry: if UBIFS recovery testing mode enabled
138 */
139struct ubifs_global_debug_info {
140 unsigned int chk_gen:1;
141 unsigned int chk_index:1;
142 unsigned int chk_orph:1;
143 unsigned int chk_lprops:1;
144 unsigned int chk_fs:1;
145 unsigned int tst_rcvry:1;
146};
147
129#define ubifs_assert(expr) do { \ 148#define ubifs_assert(expr) do { \
130 if (unlikely(!(expr))) { \ 149 if (unlikely(!(expr))) { \
131 printk(KERN_CRIT "UBIFS assert failed in %s at %u (pid %d)\n", \ 150 printk(KERN_CRIT "UBIFS assert failed in %s at %u (pid %d)\n", \
@@ -162,6 +181,8 @@ const char *dbg_key_str1(const struct ubifs_info *c,
162#define DBGKEY(key) dbg_key_str0(c, (key)) 181#define DBGKEY(key) dbg_key_str0(c, (key))
163#define DBGKEY1(key) dbg_key_str1(c, (key)) 182#define DBGKEY1(key) dbg_key_str1(c, (key))
164 183
184extern spinlock_t dbg_lock;
185
165#define ubifs_dbg_msg(type, fmt, ...) do { \ 186#define ubifs_dbg_msg(type, fmt, ...) do { \
166 spin_lock(&dbg_lock); \ 187 spin_lock(&dbg_lock); \
167 pr_debug("UBIFS DBG " type ": " fmt "\n", ##__VA_ARGS__); \ 188 pr_debug("UBIFS DBG " type ": " fmt "\n", ##__VA_ARGS__); \
@@ -197,31 +218,31 @@ const char *dbg_key_str1(const struct ubifs_info *c,
197/* Additional recovery messages */ 218/* Additional recovery messages */
198#define dbg_rcvry(fmt, ...) ubifs_dbg_msg("rcvry", fmt, ##__VA_ARGS__) 219#define dbg_rcvry(fmt, ...) ubifs_dbg_msg("rcvry", fmt, ##__VA_ARGS__)
199 220
200extern spinlock_t dbg_lock; 221extern struct ubifs_global_debug_info ubifs_dbg;
201 222
202static inline int dbg_is_chk_gen(const struct ubifs_info *c) 223static inline int dbg_is_chk_gen(const struct ubifs_info *c)
203{ 224{
204 return c->dbg->chk_gen; 225 return !!(ubifs_dbg.chk_gen || c->dbg->chk_gen);
205} 226}
206static inline int dbg_is_chk_index(const struct ubifs_info *c) 227static inline int dbg_is_chk_index(const struct ubifs_info *c)
207{ 228{
208 return c->dbg->chk_index; 229 return !!(ubifs_dbg.chk_index || c->dbg->chk_index);
209} 230}
210static inline int dbg_is_chk_orph(const struct ubifs_info *c) 231static inline int dbg_is_chk_orph(const struct ubifs_info *c)
211{ 232{
212 return c->dbg->chk_orph; 233 return !!(ubifs_dbg.chk_orph || c->dbg->chk_orph);
213} 234}
214static inline int dbg_is_chk_lprops(const struct ubifs_info *c) 235static inline int dbg_is_chk_lprops(const struct ubifs_info *c)
215{ 236{
216 return c->dbg->chk_lprops; 237 return !!(ubifs_dbg.chk_lprops || c->dbg->chk_lprops);
217} 238}
218static inline int dbg_is_chk_fs(const struct ubifs_info *c) 239static inline int dbg_is_chk_fs(const struct ubifs_info *c)
219{ 240{
220 return c->dbg->chk_fs; 241 return !!(ubifs_dbg.chk_fs || c->dbg->chk_fs);
221} 242}
222static inline int dbg_is_tst_rcvry(const struct ubifs_info *c) 243static inline int dbg_is_tst_rcvry(const struct ubifs_info *c)
223{ 244{
224 return c->dbg->tst_rcvry; 245 return !!(ubifs_dbg.tst_rcvry || c->dbg->tst_rcvry);
225} 246}
226 247
227int ubifs_debugging_init(struct ubifs_info *c); 248int ubifs_debugging_init(struct ubifs_info *c);