diff options
Diffstat (limited to 'fs/ubifs/debug.c')
-rw-r--r-- | fs/ubifs/debug.c | 140 |
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); | |||
42 | static char dbg_key_buf0[128]; | 42 | static char dbg_key_buf0[128]; |
43 | static char dbg_key_buf1[128]; | 43 | static char dbg_key_buf1[128]; |
44 | 44 | ||
45 | unsigned int ubifs_chk_flags; | ||
46 | unsigned int ubifs_tst_flags; | ||
47 | |||
48 | module_param_named(debug_chks, ubifs_chk_flags, uint, S_IRUGO | S_IWUSR); | ||
49 | module_param_named(debug_tsts, ubifs_tst_flags, uint, S_IRUGO | S_IWUSR); | ||
50 | |||
51 | MODULE_PARM_DESC(debug_chks, "Debug check flags"); | ||
52 | MODULE_PARM_DESC(debug_tsts, "Debug special test flags"); | ||
53 | |||
54 | static const char *get_key_fmt(int fmt) | 45 | static 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 | ||
2889 | static ssize_t write_debugfs_file(struct file *file, const char __user *buf, | 2880 | static 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 | |||
2914 | static 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 | ||
2909 | static const struct file_operations dfs_fops = { | 2972 | static 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 | ||
2970 | out_remove: | 3076 | out_remove: |