Commit | Line | Data |
---|---|---|
1e51764a AB |
1 | /* |
2 | * This file is part of UBIFS. | |
3 | * | |
4 | * Copyright (C) 2006-2008 Nokia Corporation. | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify it | |
7 | * under the terms of the GNU General Public License version 2 as published by | |
8 | * the Free Software Foundation. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, but WITHOUT | |
11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
13 | * more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License along with | |
16 | * this program; if not, write to the Free Software Foundation, Inc., 51 | |
17 | * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
18 | * | |
19 | * Authors: Artem Bityutskiy (Битюцкий Артём) | |
20 | * Adrian Hunter | |
21 | */ | |
22 | ||
23 | #ifndef __UBIFS_DEBUG_H__ | |
24 | #define __UBIFS_DEBUG_H__ | |
25 | ||
1dcffad7 MR |
26 | /* Checking helper functions */ |
27 | typedef int (*dbg_leaf_callback)(struct ubifs_info *c, | |
28 | struct ubifs_zbranch *zbr, void *priv); | |
29 | typedef int (*dbg_znode_callback)(struct ubifs_info *c, | |
30 | struct ubifs_znode *znode, void *priv); | |
31 | ||
ae380ce0 AB |
32 | /* |
33 | * The UBIFS debugfs directory name pattern and maximum name length (3 for "ubi" | |
34 | * + 1 for "_" and plus 2x2 for 2 UBI numbers and 1 for the trailing zero byte. | |
35 | */ | |
36 | #define UBIFS_DFS_DIR_NAME "ubi%d_%d" | |
37 | #define UBIFS_DFS_DIR_LEN (3 + 1 + 2*2 + 1) | |
38 | ||
17c2f9f8 AB |
39 | /** |
40 | * ubifs_debug_info - per-FS debugging information. | |
17c2f9f8 AB |
41 | * @old_zroot: old index root - used by 'dbg_check_old_index()' |
42 | * @old_zroot_level: old index root level - used by 'dbg_check_old_index()' | |
43 | * @old_zroot_sqnum: old index root sqnum - used by 'dbg_check_old_index()' | |
81e79d38 | 44 | * |
d27462a5 AB |
45 | * @pc_happened: non-zero if an emulated power cut happened |
46 | * @pc_delay: 0=>don't delay, 1=>delay a time, 2=>delay a number of calls | |
47 | * @pc_timeout: time in jiffies when delay of failure mode expires | |
48 | * @pc_cnt: current number of calls to failure mode I/O functions | |
49 | * @pc_cnt_max: number of calls by which to delay failure mode | |
81e79d38 | 50 | * |
17c2f9f8 AB |
51 | * @chk_lpt_sz: used by LPT tree size checker |
52 | * @chk_lpt_sz2: used by LPT tree size checker | |
53 | * @chk_lpt_wastage: used by LPT tree size checker | |
54 | * @chk_lpt_lebs: used by LPT tree size checker | |
55 | * @new_nhead_offs: used by LPT tree size checker | |
84abf972 AB |
56 | * @new_ihead_lnum: used by debugging to check @c->ihead_lnum |
57 | * @new_ihead_offs: used by debugging to check @c->ihead_offs | |
552ff317 | 58 | * |
84abf972 | 59 | * @saved_lst: saved lprops statistics (used by 'dbg_save_space_info()') |
f1bd66af AB |
60 | * @saved_bi: saved budgeting information |
61 | * @saved_free: saved amount of free space | |
62 | * @saved_idx_gc_cnt: saved value of @c->idx_gc_cnt | |
84abf972 | 63 | * |
81e79d38 AB |
64 | * @chk_gen: if general extra checks are enabled |
65 | * @chk_index: if index xtra checks are enabled | |
66 | * @chk_orph: if orphans extra checks are enabled | |
67 | * @chk_lprops: if lprops extra checks are enabled | |
68 | * @chk_fs: if UBIFS contents extra checks are enabled | |
69 | * @tst_rcvry: if UBIFS recovery testing mode enabled | |
70 | * | |
bdc1a1b6 AB |
71 | * @dfs_dir_name: name of debugfs directory containing this file-system's files |
72 | * @dfs_dir: direntry object of the file-system debugfs directory | |
73 | * @dfs_dump_lprops: "dump lprops" debugfs knob | |
74 | * @dfs_dump_budg: "dump budgeting information" debugfs knob | |
75 | * @dfs_dump_tnc: "dump TNC" debugfs knob | |
81e79d38 AB |
76 | * @dfs_chk_gen: debugfs knob to enable UBIFS general extra checks |
77 | * @dfs_chk_index: debugfs knob to enable UBIFS index extra checks | |
78 | * @dfs_chk_orph: debugfs knob to enable UBIFS orphans extra checks | |
79 | * @dfs_chk_lprops: debugfs knob to enable UBIFS LEP properties extra checks | |
80 | * @dfs_chk_fs: debugfs knob to enable UBIFS contents extra checks | |
81 | * @dfs_tst_rcvry: debugfs knob to enable UBIFS recovery testing | |
06bef945 AB |
82 | * @dfs_ro_error: debugfs knob to switch UBIFS to R/O mode (different to |
83 | * re-mounting to R/O mode because it does not flush any buffers | |
84 | * and UBIFS just starts returning -EROFS on all write | |
85 | * operations) | |
17c2f9f8 AB |
86 | */ |
87 | struct ubifs_debug_info { | |
17c2f9f8 AB |
88 | struct ubifs_zbranch old_zroot; |
89 | int old_zroot_level; | |
90 | unsigned long long old_zroot_sqnum; | |
81e79d38 | 91 | |
d27462a5 AB |
92 | int pc_happened; |
93 | int pc_delay; | |
94 | unsigned long pc_timeout; | |
95 | unsigned int pc_cnt; | |
96 | unsigned int pc_cnt_max; | |
81e79d38 | 97 | |
17c2f9f8 AB |
98 | long long chk_lpt_sz; |
99 | long long chk_lpt_sz2; | |
100 | long long chk_lpt_wastage; | |
101 | int chk_lpt_lebs; | |
102 | int new_nhead_offs; | |
103 | int new_ihead_lnum; | |
104 | int new_ihead_offs; | |
552ff317 | 105 | |
84abf972 | 106 | struct ubifs_lp_stats saved_lst; |
f1bd66af | 107 | struct ubifs_budg_info saved_bi; |
84abf972 | 108 | long long saved_free; |
f1bd66af | 109 | int saved_idx_gc_cnt; |
84abf972 | 110 | |
81e79d38 AB |
111 | unsigned int chk_gen:1; |
112 | unsigned int chk_index:1; | |
113 | unsigned int chk_orph:1; | |
114 | unsigned int chk_lprops:1; | |
115 | unsigned int chk_fs:1; | |
116 | unsigned int tst_rcvry:1; | |
117 | ||
ae380ce0 | 118 | char dfs_dir_name[UBIFS_DFS_DIR_LEN + 1]; |
84abf972 AB |
119 | struct dentry *dfs_dir; |
120 | struct dentry *dfs_dump_lprops; | |
121 | struct dentry *dfs_dump_budg; | |
122 | struct dentry *dfs_dump_tnc; | |
81e79d38 AB |
123 | struct dentry *dfs_chk_gen; |
124 | struct dentry *dfs_chk_index; | |
125 | struct dentry *dfs_chk_orph; | |
126 | struct dentry *dfs_chk_lprops; | |
127 | struct dentry *dfs_chk_fs; | |
128 | struct dentry *dfs_tst_rcvry; | |
06bef945 | 129 | struct dentry *dfs_ro_error; |
17c2f9f8 | 130 | }; |
1e51764a | 131 | |
e7717060 AB |
132 | /** |
133 | * ubifs_global_debug_info - global (not per-FS) UBIFS debugging information. | |
134 | * | |
135 | * @chk_gen: if general extra checks are enabled | |
136 | * @chk_index: if index xtra checks are enabled | |
137 | * @chk_orph: if orphans extra checks are enabled | |
138 | * @chk_lprops: if lprops extra checks are enabled | |
139 | * @chk_fs: if UBIFS contents extra checks are enabled | |
140 | * @tst_rcvry: if UBIFS recovery testing mode enabled | |
141 | */ | |
142 | struct ubifs_global_debug_info { | |
143 | unsigned int chk_gen:1; | |
144 | unsigned int chk_index:1; | |
145 | unsigned int chk_orph:1; | |
146 | unsigned int chk_lprops:1; | |
147 | unsigned int chk_fs:1; | |
148 | unsigned int tst_rcvry:1; | |
149 | }; | |
150 | ||
840dc6b8 | 151 | #define ubifs_assert(expr) do { \ |
1e51764a | 152 | if (unlikely(!(expr))) { \ |
6b38d03f | 153 | pr_crit("UBIFS assert failed in %s at %u (pid %d)\n", \ |
1e51764a | 154 | __func__, __LINE__, current->pid); \ |
7c46d0ae | 155 | dump_stack(); \ |
1e51764a AB |
156 | } \ |
157 | } while (0) | |
158 | ||
159 | #define ubifs_assert_cmt_locked(c) do { \ | |
160 | if (unlikely(down_write_trylock(&(c)->commit_sem))) { \ | |
161 | up_write(&(c)->commit_sem); \ | |
6b38d03f | 162 | pr_crit("commit lock is not locked!\n"); \ |
1e51764a AB |
163 | ubifs_assert(0); \ |
164 | } \ | |
165 | } while (0) | |
166 | ||
1f5d78dc | 167 | #define ubifs_dbg_msg(type, fmt, ...) \ |
c45640d8 AB |
168 | pr_debug("UBIFS DBG " type " (pid %d): " fmt "\n", current->pid, \ |
169 | ##__VA_ARGS__) | |
1e51764a | 170 | |
65b455b1 | 171 | #define DBG_KEY_BUF_LEN 48 |
515315a1 AB |
172 | #define ubifs_dbg_msg_key(type, key, fmt, ...) do { \ |
173 | char __tmp_key_buf[DBG_KEY_BUF_LEN]; \ | |
c45640d8 AB |
174 | pr_debug("UBIFS DBG " type " (pid %d): " fmt "%s\n", current->pid, \ |
175 | ##__VA_ARGS__, \ | |
515315a1 AB |
176 | dbg_snprintf_key(c, key, __tmp_key_buf, DBG_KEY_BUF_LEN)); \ |
177 | } while (0) | |
178 | ||
56e46742 AB |
179 | /* General messages */ |
180 | #define dbg_gen(fmt, ...) ubifs_dbg_msg("gen", fmt, ##__VA_ARGS__) | |
1e51764a | 181 | /* Additional journal messages */ |
56e46742 | 182 | #define dbg_jnl(fmt, ...) ubifs_dbg_msg("jnl", fmt, ##__VA_ARGS__) |
515315a1 AB |
183 | #define dbg_jnlk(key, fmt, ...) \ |
184 | ubifs_dbg_msg_key("jnl", key, fmt, ##__VA_ARGS__) | |
1e51764a | 185 | /* Additional TNC messages */ |
56e46742 | 186 | #define dbg_tnc(fmt, ...) ubifs_dbg_msg("tnc", fmt, ##__VA_ARGS__) |
515315a1 AB |
187 | #define dbg_tnck(key, fmt, ...) \ |
188 | ubifs_dbg_msg_key("tnc", key, fmt, ##__VA_ARGS__) | |
1e51764a | 189 | /* Additional lprops messages */ |
56e46742 | 190 | #define dbg_lp(fmt, ...) ubifs_dbg_msg("lp", fmt, ##__VA_ARGS__) |
1e51764a | 191 | /* Additional LEB find messages */ |
56e46742 | 192 | #define dbg_find(fmt, ...) ubifs_dbg_msg("find", fmt, ##__VA_ARGS__) |
1e51764a | 193 | /* Additional mount messages */ |
56e46742 | 194 | #define dbg_mnt(fmt, ...) ubifs_dbg_msg("mnt", fmt, ##__VA_ARGS__) |
515315a1 AB |
195 | #define dbg_mntk(key, fmt, ...) \ |
196 | ubifs_dbg_msg_key("mnt", key, fmt, ##__VA_ARGS__) | |
1e51764a | 197 | /* Additional I/O messages */ |
56e46742 | 198 | #define dbg_io(fmt, ...) ubifs_dbg_msg("io", fmt, ##__VA_ARGS__) |
1e51764a | 199 | /* Additional commit messages */ |
56e46742 | 200 | #define dbg_cmt(fmt, ...) ubifs_dbg_msg("cmt", fmt, ##__VA_ARGS__) |
1e51764a | 201 | /* Additional budgeting messages */ |
56e46742 | 202 | #define dbg_budg(fmt, ...) ubifs_dbg_msg("budg", fmt, ##__VA_ARGS__) |
1e51764a | 203 | /* Additional log messages */ |
56e46742 | 204 | #define dbg_log(fmt, ...) ubifs_dbg_msg("log", fmt, ##__VA_ARGS__) |
1e51764a | 205 | /* Additional gc messages */ |
56e46742 | 206 | #define dbg_gc(fmt, ...) ubifs_dbg_msg("gc", fmt, ##__VA_ARGS__) |
1e51764a | 207 | /* Additional scan messages */ |
56e46742 | 208 | #define dbg_scan(fmt, ...) ubifs_dbg_msg("scan", fmt, ##__VA_ARGS__) |
1e51764a | 209 | /* Additional recovery messages */ |
56e46742 | 210 | #define dbg_rcvry(fmt, ...) ubifs_dbg_msg("rcvry", fmt, ##__VA_ARGS__) |
1e51764a | 211 | |
e7717060 | 212 | extern struct ubifs_global_debug_info ubifs_dbg; |
2b1844a8 | 213 | |
2b1844a8 AB |
214 | static inline int dbg_is_chk_gen(const struct ubifs_info *c) |
215 | { | |
e7717060 | 216 | return !!(ubifs_dbg.chk_gen || c->dbg->chk_gen); |
2b1844a8 | 217 | } |
8d7819b4 | 218 | static inline int dbg_is_chk_index(const struct ubifs_info *c) |
2b1844a8 | 219 | { |
e7717060 | 220 | return !!(ubifs_dbg.chk_index || c->dbg->chk_index); |
2b1844a8 AB |
221 | } |
222 | static inline int dbg_is_chk_orph(const struct ubifs_info *c) | |
223 | { | |
e7717060 | 224 | return !!(ubifs_dbg.chk_orph || c->dbg->chk_orph); |
2b1844a8 | 225 | } |
2b1844a8 AB |
226 | static inline int dbg_is_chk_lprops(const struct ubifs_info *c) |
227 | { | |
e7717060 | 228 | return !!(ubifs_dbg.chk_lprops || c->dbg->chk_lprops); |
2b1844a8 AB |
229 | } |
230 | static inline int dbg_is_chk_fs(const struct ubifs_info *c) | |
231 | { | |
e7717060 | 232 | return !!(ubifs_dbg.chk_fs || c->dbg->chk_fs); |
2b1844a8 AB |
233 | } |
234 | static inline int dbg_is_tst_rcvry(const struct ubifs_info *c) | |
235 | { | |
e7717060 | 236 | return !!(ubifs_dbg.tst_rcvry || c->dbg->tst_rcvry); |
2b1844a8 | 237 | } |
83cef708 AB |
238 | static inline int dbg_is_power_cut(const struct ubifs_info *c) |
239 | { | |
d27462a5 | 240 | return !!c->dbg->pc_happened; |
83cef708 | 241 | } |
2b1844a8 | 242 | |
17c2f9f8 AB |
243 | int ubifs_debugging_init(struct ubifs_info *c); |
244 | void ubifs_debugging_exit(struct ubifs_info *c); | |
245 | ||
1e51764a | 246 | /* Dump functions */ |
1e51764a AB |
247 | const char *dbg_ntype(int type); |
248 | const char *dbg_cstate(int cmt_state); | |
77a7ae58 | 249 | const char *dbg_jhead(int jhead); |
1e51764a AB |
250 | const char *dbg_get_key_dump(const struct ubifs_info *c, |
251 | const union ubifs_key *key); | |
515315a1 AB |
252 | const char *dbg_snprintf_key(const struct ubifs_info *c, |
253 | const union ubifs_key *key, char *buffer, int len); | |
edf6be24 AB |
254 | void ubifs_dump_inode(struct ubifs_info *c, const struct inode *inode); |
255 | void ubifs_dump_node(const struct ubifs_info *c, const void *node); | |
256 | void ubifs_dump_budget_req(const struct ubifs_budget_req *req); | |
257 | void ubifs_dump_lstats(const struct ubifs_lp_stats *lst); | |
258 | void ubifs_dump_budg(struct ubifs_info *c, const struct ubifs_budg_info *bi); | |
259 | void ubifs_dump_lprop(const struct ubifs_info *c, | |
260 | const struct ubifs_lprops *lp); | |
261 | void ubifs_dump_lprops(struct ubifs_info *c); | |
262 | void ubifs_dump_lpt_info(struct ubifs_info *c); | |
263 | void ubifs_dump_leb(const struct ubifs_info *c, int lnum); | |
264 | void ubifs_dump_sleb(const struct ubifs_info *c, | |
265 | const struct ubifs_scan_leb *sleb, int offs); | |
266 | void ubifs_dump_znode(const struct ubifs_info *c, | |
267 | const struct ubifs_znode *znode); | |
268 | void ubifs_dump_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, | |
269 | int cat); | |
270 | void ubifs_dump_pnode(struct ubifs_info *c, struct ubifs_pnode *pnode, | |
271 | struct ubifs_nnode *parent, int iip); | |
272 | void ubifs_dump_tnc(struct ubifs_info *c); | |
273 | void ubifs_dump_index(struct ubifs_info *c); | |
274 | void ubifs_dump_lpt_lebs(const struct ubifs_info *c); | |
1e51764a | 275 | |
1e51764a AB |
276 | int dbg_walk_index(struct ubifs_info *c, dbg_leaf_callback leaf_cb, |
277 | dbg_znode_callback znode_cb, void *priv); | |
278 | ||
279 | /* Checking functions */ | |
84abf972 AB |
280 | void dbg_save_space_info(struct ubifs_info *c); |
281 | int dbg_check_space_info(struct ubifs_info *c); | |
1e51764a | 282 | int dbg_check_lprops(struct ubifs_info *c); |
1e51764a AB |
283 | int dbg_old_index_check_init(struct ubifs_info *c, struct ubifs_zbranch *zroot); |
284 | int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot); | |
1e51764a | 285 | int dbg_check_cats(struct ubifs_info *c); |
1e51764a | 286 | int dbg_check_ltab(struct ubifs_info *c); |
73944a6d AH |
287 | int dbg_chk_lpt_free_spc(struct ubifs_info *c); |
288 | int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len); | |
d808efb4 | 289 | int dbg_check_synced_i_size(const struct ubifs_info *c, struct inode *inode); |
1b51e983 | 290 | int dbg_check_dir(struct ubifs_info *c, const struct inode *dir); |
1e51764a | 291 | int dbg_check_tnc(struct ubifs_info *c, int extra); |
1e51764a | 292 | int dbg_check_idx_size(struct ubifs_info *c, long long idx_size); |
1e51764a | 293 | int dbg_check_filesystem(struct ubifs_info *c); |
1e51764a AB |
294 | void dbg_check_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat, |
295 | int add_pos); | |
1e51764a AB |
296 | int dbg_check_lpt_nodes(struct ubifs_info *c, struct ubifs_cnode *cnode, |
297 | int row, int col); | |
e3c3efc2 AB |
298 | int dbg_check_inode_size(struct ubifs_info *c, const struct inode *inode, |
299 | loff_t size); | |
3bb66b47 AB |
300 | int dbg_check_data_nodes_order(struct ubifs_info *c, struct list_head *head); |
301 | int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head); | |
1e51764a | 302 | |
f57cb188 | 303 | int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs, |
b36a261e RW |
304 | int len); |
305 | int dbg_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len); | |
f57cb188 | 306 | int dbg_leb_unmap(struct ubifs_info *c, int lnum); |
b36a261e | 307 | int dbg_leb_map(struct ubifs_info *c, int lnum); |
1e51764a | 308 | |
552ff317 AB |
309 | /* Debugfs-related stuff */ |
310 | int dbg_debugfs_init(void); | |
311 | void dbg_debugfs_exit(void); | |
312 | int dbg_debugfs_init_fs(struct ubifs_info *c); | |
313 | void dbg_debugfs_exit_fs(struct ubifs_info *c); | |
314 | ||
1e51764a | 315 | #endif /* !__UBIFS_DEBUG_H__ */ |