aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ubifs/debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ubifs/debug.c')
-rw-r--r--fs/ubifs/debug.c140
1 files changed, 123 insertions, 17 deletions
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index a967d6800ead..fdfa5dea5b95 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: