aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ubifs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ubifs')
-rw-r--r--fs/ubifs/commit.c8
-rw-r--r--fs/ubifs/debug.c762
-rw-r--r--fs/ubifs/debug.h241
-rw-r--r--fs/ubifs/dir.c16
-rw-r--r--fs/ubifs/file.c2
-rw-r--r--fs/ubifs/io.c168
-rw-r--r--fs/ubifs/log.c6
-rw-r--r--fs/ubifs/lprops.c8
-rw-r--r--fs/ubifs/lpt.c37
-rw-r--r--fs/ubifs/lpt_commit.c40
-rw-r--r--fs/ubifs/misc.h103
-rw-r--r--fs/ubifs/orphan.c2
-rw-r--r--fs/ubifs/recovery.c43
-rw-r--r--fs/ubifs/replay.c3
-rw-r--r--fs/ubifs/sb.c6
-rw-r--r--fs/ubifs/scan.c4
-rw-r--r--fs/ubifs/super.c6
-rw-r--r--fs/ubifs/tnc.c26
-rw-r--r--fs/ubifs/tnc_commit.c145
-rw-r--r--fs/ubifs/ubifs.h21
20 files changed, 976 insertions, 671 deletions
diff --git a/fs/ubifs/commit.c b/fs/ubifs/commit.c
index 87cd0ead8633..fb3b5c813a30 100644
--- a/fs/ubifs/commit.c
+++ b/fs/ubifs/commit.c
@@ -78,7 +78,7 @@ static int nothing_to_commit(struct ubifs_info *c)
78 * If the root TNC node is dirty, we definitely have something to 78 * If the root TNC node is dirty, we definitely have something to
79 * commit. 79 * commit.
80 */ 80 */
81 if (c->zroot.znode && test_bit(DIRTY_ZNODE, &c->zroot.znode->flags)) 81 if (c->zroot.znode && ubifs_zn_dirty(c->zroot.znode))
82 return 0; 82 return 0;
83 83
84 /* 84 /*
@@ -418,7 +418,7 @@ int ubifs_run_commit(struct ubifs_info *c)
418 418
419 spin_lock(&c->cs_lock); 419 spin_lock(&c->cs_lock);
420 if (c->cmt_state == COMMIT_BROKEN) { 420 if (c->cmt_state == COMMIT_BROKEN) {
421 err = -EINVAL; 421 err = -EROFS;
422 goto out; 422 goto out;
423 } 423 }
424 424
@@ -444,7 +444,7 @@ int ubifs_run_commit(struct ubifs_info *c)
444 * re-check it. 444 * re-check it.
445 */ 445 */
446 if (c->cmt_state == COMMIT_BROKEN) { 446 if (c->cmt_state == COMMIT_BROKEN) {
447 err = -EINVAL; 447 err = -EROFS;
448 goto out_cmt_unlock; 448 goto out_cmt_unlock;
449 } 449 }
450 450
@@ -576,7 +576,7 @@ int dbg_check_old_index(struct ubifs_info *c, struct ubifs_zbranch *zroot)
576 struct idx_node *i; 576 struct idx_node *i;
577 size_t sz; 577 size_t sz;
578 578
579 if (!(ubifs_chk_flags & UBIFS_CHK_OLD_IDX)) 579 if (!dbg_is_chk_index(c))
580 return 0; 580 return 0;
581 581
582 INIT_LIST_HEAD(&list); 582 INIT_LIST_HEAD(&list);
diff --git a/fs/ubifs/debug.c b/fs/ubifs/debug.c
index 0bb2bcef0de9..eef109a1a927 100644
--- a/fs/ubifs/debug.c
+++ b/fs/ubifs/debug.c
@@ -27,13 +27,12 @@
27 * various local functions of those subsystems. 27 * various local functions of those subsystems.
28 */ 28 */
29 29
30#define UBIFS_DBG_PRESERVE_UBI
31
32#include "ubifs.h"
33#include <linux/module.h> 30#include <linux/module.h>
34#include <linux/moduleparam.h>
35#include <linux/debugfs.h> 31#include <linux/debugfs.h>
36#include <linux/math64.h> 32#include <linux/math64.h>
33#include <linux/uaccess.h>
34#include <linux/random.h>
35#include "ubifs.h"
37 36
38#ifdef CONFIG_UBIFS_FS_DEBUG 37#ifdef CONFIG_UBIFS_FS_DEBUG
39 38
@@ -42,15 +41,6 @@ DEFINE_SPINLOCK(dbg_lock);
42static char dbg_key_buf0[128]; 41static char dbg_key_buf0[128];
43static char dbg_key_buf1[128]; 42static char dbg_key_buf1[128];
44 43
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) 44static const char *get_key_fmt(int fmt)
55{ 45{
56 switch (fmt) { 46 switch (fmt) {
@@ -91,6 +81,28 @@ static const char *get_key_type(int type)
91 } 81 }
92} 82}
93 83
84static const char *get_dent_type(int type)
85{
86 switch (type) {
87 case UBIFS_ITYPE_REG:
88 return "file";
89 case UBIFS_ITYPE_DIR:
90 return "dir";
91 case UBIFS_ITYPE_LNK:
92 return "symlink";
93 case UBIFS_ITYPE_BLK:
94 return "blkdev";
95 case UBIFS_ITYPE_CHR:
96 return "char dev";
97 case UBIFS_ITYPE_FIFO:
98 return "fifo";
99 case UBIFS_ITYPE_SOCK:
100 return "socket";
101 default:
102 return "unknown/invalid type";
103 }
104}
105
94static void sprintf_key(const struct ubifs_info *c, const union ubifs_key *key, 106static void sprintf_key(const struct ubifs_info *c, const union ubifs_key *key,
95 char *buffer) 107 char *buffer)
96{ 108{
@@ -234,9 +246,13 @@ static void dump_ch(const struct ubifs_ch *ch)
234 printk(KERN_DEBUG "\tlen %u\n", le32_to_cpu(ch->len)); 246 printk(KERN_DEBUG "\tlen %u\n", le32_to_cpu(ch->len));
235} 247}
236 248
237void dbg_dump_inode(const struct ubifs_info *c, const struct inode *inode) 249void dbg_dump_inode(struct ubifs_info *c, const struct inode *inode)
238{ 250{
239 const struct ubifs_inode *ui = ubifs_inode(inode); 251 const struct ubifs_inode *ui = ubifs_inode(inode);
252 struct qstr nm = { .name = NULL };
253 union ubifs_key key;
254 struct ubifs_dent_node *dent, *pdent = NULL;
255 int count = 2;
240 256
241 printk(KERN_DEBUG "Dump in-memory inode:"); 257 printk(KERN_DEBUG "Dump in-memory inode:");
242 printk(KERN_DEBUG "\tinode %lu\n", inode->i_ino); 258 printk(KERN_DEBUG "\tinode %lu\n", inode->i_ino);
@@ -270,6 +286,32 @@ void dbg_dump_inode(const struct ubifs_info *c, const struct inode *inode)
270 printk(KERN_DEBUG "\tlast_page_read %lu\n", ui->last_page_read); 286 printk(KERN_DEBUG "\tlast_page_read %lu\n", ui->last_page_read);
271 printk(KERN_DEBUG "\tread_in_a_row %lu\n", ui->read_in_a_row); 287 printk(KERN_DEBUG "\tread_in_a_row %lu\n", ui->read_in_a_row);
272 printk(KERN_DEBUG "\tdata_len %d\n", ui->data_len); 288 printk(KERN_DEBUG "\tdata_len %d\n", ui->data_len);
289
290 if (!S_ISDIR(inode->i_mode))
291 return;
292
293 printk(KERN_DEBUG "List of directory entries:\n");
294 ubifs_assert(!mutex_is_locked(&c->tnc_mutex));
295
296 lowest_dent_key(c, &key, inode->i_ino);
297 while (1) {
298 dent = ubifs_tnc_next_ent(c, &key, &nm);
299 if (IS_ERR(dent)) {
300 if (PTR_ERR(dent) != -ENOENT)
301 printk(KERN_DEBUG "error %ld\n", PTR_ERR(dent));
302 break;
303 }
304
305 printk(KERN_DEBUG "\t%d: %s (%s)\n",
306 count++, dent->name, get_dent_type(dent->type));
307
308 nm.name = dent->name;
309 nm.len = le16_to_cpu(dent->nlen);
310 kfree(pdent);
311 pdent = dent;
312 key_read(c, &dent->key, &key);
313 }
314 kfree(pdent);
273} 315}
274 316
275void dbg_dump_node(const struct ubifs_info *c, const void *node) 317void dbg_dump_node(const struct ubifs_info *c, const void *node)
@@ -278,7 +320,7 @@ void dbg_dump_node(const struct ubifs_info *c, const void *node)
278 union ubifs_key key; 320 union ubifs_key key;
279 const struct ubifs_ch *ch = node; 321 const struct ubifs_ch *ch = node;
280 322
281 if (dbg_failure_mode) 323 if (dbg_is_tst_rcvry(c))
282 return; 324 return;
283 325
284 /* If the magic is incorrect, just hexdump the first bytes */ 326 /* If the magic is incorrect, just hexdump the first bytes */
@@ -834,7 +876,7 @@ void dbg_dump_leb(const struct ubifs_info *c, int lnum)
834 struct ubifs_scan_node *snod; 876 struct ubifs_scan_node *snod;
835 void *buf; 877 void *buf;
836 878
837 if (dbg_failure_mode) 879 if (dbg_is_tst_rcvry(c))
838 return; 880 return;
839 881
840 printk(KERN_DEBUG "(pid %d) start dumping LEB %d\n", 882 printk(KERN_DEBUG "(pid %d) start dumping LEB %d\n",
@@ -1080,6 +1122,7 @@ out:
1080 1122
1081/** 1123/**
1082 * dbg_check_synced_i_size - check synchronized inode size. 1124 * dbg_check_synced_i_size - check synchronized inode size.
1125 * @c: UBIFS file-system description object
1083 * @inode: inode to check 1126 * @inode: inode to check
1084 * 1127 *
1085 * If inode is clean, synchronized inode size has to be equivalent to current 1128 * If inode is clean, synchronized inode size has to be equivalent to current
@@ -1087,12 +1130,12 @@ out:
1087 * has to be locked). Returns %0 if synchronized inode size if correct, and 1130 * has to be locked). Returns %0 if synchronized inode size if correct, and
1088 * %-EINVAL if not. 1131 * %-EINVAL if not.
1089 */ 1132 */
1090int dbg_check_synced_i_size(struct inode *inode) 1133int dbg_check_synced_i_size(const struct ubifs_info *c, struct inode *inode)
1091{ 1134{
1092 int err = 0; 1135 int err = 0;
1093 struct ubifs_inode *ui = ubifs_inode(inode); 1136 struct ubifs_inode *ui = ubifs_inode(inode);
1094 1137
1095 if (!(ubifs_chk_flags & UBIFS_CHK_GEN)) 1138 if (!dbg_is_chk_gen(c))
1096 return 0; 1139 return 0;
1097 if (!S_ISREG(inode->i_mode)) 1140 if (!S_ISREG(inode->i_mode))
1098 return 0; 1141 return 0;
@@ -1125,7 +1168,7 @@ int dbg_check_synced_i_size(struct inode *inode)
1125 * Note, it is good idea to make sure the @dir->i_mutex is locked before 1168 * Note, it is good idea to make sure the @dir->i_mutex is locked before
1126 * calling this function. 1169 * calling this function.
1127 */ 1170 */
1128int dbg_check_dir_size(struct ubifs_info *c, const struct inode *dir) 1171int dbg_check_dir(struct ubifs_info *c, const struct inode *dir)
1129{ 1172{
1130 unsigned int nlink = 2; 1173 unsigned int nlink = 2;
1131 union ubifs_key key; 1174 union ubifs_key key;
@@ -1133,7 +1176,7 @@ int dbg_check_dir_size(struct ubifs_info *c, const struct inode *dir)
1133 struct qstr nm = { .name = NULL }; 1176 struct qstr nm = { .name = NULL };
1134 loff_t size = UBIFS_INO_NODE_SZ; 1177 loff_t size = UBIFS_INO_NODE_SZ;
1135 1178
1136 if (!(ubifs_chk_flags & UBIFS_CHK_GEN)) 1179 if (!dbg_is_chk_gen(c))
1137 return 0; 1180 return 0;
1138 1181
1139 if (!S_ISDIR(dir->i_mode)) 1182 if (!S_ISDIR(dir->i_mode))
@@ -1167,12 +1210,14 @@ int dbg_check_dir_size(struct ubifs_info *c, const struct inode *dir)
1167 "but calculated size is %llu", dir->i_ino, 1210 "but calculated size is %llu", dir->i_ino,
1168 (unsigned long long)i_size_read(dir), 1211 (unsigned long long)i_size_read(dir),
1169 (unsigned long long)size); 1212 (unsigned long long)size);
1213 dbg_dump_inode(c, dir);
1170 dump_stack(); 1214 dump_stack();
1171 return -EINVAL; 1215 return -EINVAL;
1172 } 1216 }
1173 if (dir->i_nlink != nlink) { 1217 if (dir->i_nlink != nlink) {
1174 ubifs_err("directory inode %lu has nlink %u, but calculated " 1218 ubifs_err("directory inode %lu has nlink %u, but calculated "
1175 "nlink is %u", dir->i_ino, dir->i_nlink, nlink); 1219 "nlink is %u", dir->i_ino, dir->i_nlink, nlink);
1220 dbg_dump_inode(c, dir);
1176 dump_stack(); 1221 dump_stack();
1177 return -EINVAL; 1222 return -EINVAL;
1178 } 1223 }
@@ -1489,7 +1534,7 @@ int dbg_check_tnc(struct ubifs_info *c, int extra)
1489 long clean_cnt = 0, dirty_cnt = 0; 1534 long clean_cnt = 0, dirty_cnt = 0;
1490 int err, last; 1535 int err, last;
1491 1536
1492 if (!(ubifs_chk_flags & UBIFS_CHK_TNC)) 1537 if (!dbg_is_chk_index(c))
1493 return 0; 1538 return 0;
1494 1539
1495 ubifs_assert(mutex_is_locked(&c->tnc_mutex)); 1540 ubifs_assert(mutex_is_locked(&c->tnc_mutex));
@@ -1736,7 +1781,7 @@ int dbg_check_idx_size(struct ubifs_info *c, long long idx_size)
1736 int err; 1781 int err;
1737 long long calc = 0; 1782 long long calc = 0;
1738 1783
1739 if (!(ubifs_chk_flags & UBIFS_CHK_IDX_SZ)) 1784 if (!dbg_is_chk_index(c))
1740 return 0; 1785 return 0;
1741 1786
1742 err = dbg_walk_index(c, NULL, add_size, &calc); 1787 err = dbg_walk_index(c, NULL, add_size, &calc);
@@ -2312,7 +2357,7 @@ int dbg_check_filesystem(struct ubifs_info *c)
2312 int err; 2357 int err;
2313 struct fsck_data fsckd; 2358 struct fsck_data fsckd;
2314 2359
2315 if (!(ubifs_chk_flags & UBIFS_CHK_FS)) 2360 if (!dbg_is_chk_fs(c))
2316 return 0; 2361 return 0;
2317 2362
2318 fsckd.inodes = RB_ROOT; 2363 fsckd.inodes = RB_ROOT;
@@ -2347,7 +2392,7 @@ int dbg_check_data_nodes_order(struct ubifs_info *c, struct list_head *head)
2347 struct list_head *cur; 2392 struct list_head *cur;
2348 struct ubifs_scan_node *sa, *sb; 2393 struct ubifs_scan_node *sa, *sb;
2349 2394
2350 if (!(ubifs_chk_flags & UBIFS_CHK_GEN)) 2395 if (!dbg_is_chk_gen(c))
2351 return 0; 2396 return 0;
2352 2397
2353 for (cur = head->next; cur->next != head; cur = cur->next) { 2398 for (cur = head->next; cur->next != head; cur = cur->next) {
@@ -2414,7 +2459,7 @@ int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head)
2414 struct list_head *cur; 2459 struct list_head *cur;
2415 struct ubifs_scan_node *sa, *sb; 2460 struct ubifs_scan_node *sa, *sb;
2416 2461
2417 if (!(ubifs_chk_flags & UBIFS_CHK_GEN)) 2462 if (!dbg_is_chk_gen(c))
2418 return 0; 2463 return 0;
2419 2464
2420 for (cur = head->next; cur->next != head; cur = cur->next) { 2465 for (cur = head->next; cur->next != head; cur = cur->next) {
@@ -2491,214 +2536,141 @@ error_dump:
2491 return 0; 2536 return 0;
2492} 2537}
2493 2538
2494int dbg_force_in_the_gaps(void) 2539static inline int chance(unsigned int n, unsigned int out_of)
2495{ 2540{
2496 if (!(ubifs_chk_flags & UBIFS_CHK_GEN)) 2541 return !!((random32() % out_of) + 1 <= n);
2497 return 0;
2498 2542
2499 return !(random32() & 7);
2500} 2543}
2501 2544
2502/* Failure mode for recovery testing */ 2545static int power_cut_emulated(struct ubifs_info *c, int lnum, int write)
2503
2504#define chance(n, d) (simple_rand() <= (n) * 32768LL / (d))
2505
2506struct failure_mode_info {
2507 struct list_head list;
2508 struct ubifs_info *c;
2509};
2510
2511static LIST_HEAD(fmi_list);
2512static DEFINE_SPINLOCK(fmi_lock);
2513
2514static unsigned int next;
2515
2516static int simple_rand(void)
2517{
2518 if (next == 0)
2519 next = current->pid;
2520 next = next * 1103515245 + 12345;
2521 return (next >> 16) & 32767;
2522}
2523
2524static void failure_mode_init(struct ubifs_info *c)
2525{
2526 struct failure_mode_info *fmi;
2527
2528 fmi = kmalloc(sizeof(struct failure_mode_info), GFP_NOFS);
2529 if (!fmi) {
2530 ubifs_err("Failed to register failure mode - no memory");
2531 return;
2532 }
2533 fmi->c = c;
2534 spin_lock(&fmi_lock);
2535 list_add_tail(&fmi->list, &fmi_list);
2536 spin_unlock(&fmi_lock);
2537}
2538
2539static void failure_mode_exit(struct ubifs_info *c)
2540{ 2546{
2541 struct failure_mode_info *fmi, *tmp; 2547 struct ubifs_debug_info *d = c->dbg;
2542
2543 spin_lock(&fmi_lock);
2544 list_for_each_entry_safe(fmi, tmp, &fmi_list, list)
2545 if (fmi->c == c) {
2546 list_del(&fmi->list);
2547 kfree(fmi);
2548 }
2549 spin_unlock(&fmi_lock);
2550}
2551
2552static struct ubifs_info *dbg_find_info(struct ubi_volume_desc *desc)
2553{
2554 struct failure_mode_info *fmi;
2555
2556 spin_lock(&fmi_lock);
2557 list_for_each_entry(fmi, &fmi_list, list)
2558 if (fmi->c->ubi == desc) {
2559 struct ubifs_info *c = fmi->c;
2560
2561 spin_unlock(&fmi_lock);
2562 return c;
2563 }
2564 spin_unlock(&fmi_lock);
2565 return NULL;
2566}
2567
2568static int in_failure_mode(struct ubi_volume_desc *desc)
2569{
2570 struct ubifs_info *c = dbg_find_info(desc);
2571
2572 if (c && dbg_failure_mode)
2573 return c->dbg->failure_mode;
2574 return 0;
2575}
2576 2548
2577static int do_fail(struct ubi_volume_desc *desc, int lnum, int write) 2549 ubifs_assert(dbg_is_tst_rcvry(c));
2578{
2579 struct ubifs_info *c = dbg_find_info(desc);
2580 struct ubifs_debug_info *d;
2581 2550
2582 if (!c || !dbg_failure_mode) 2551 if (!d->pc_cnt) {
2583 return 0; 2552 /* First call - decide delay to the power cut */
2584 d = c->dbg;
2585 if (d->failure_mode)
2586 return 1;
2587 if (!d->fail_cnt) {
2588 /* First call - decide delay to failure */
2589 if (chance(1, 2)) { 2553 if (chance(1, 2)) {
2590 unsigned int delay = 1 << (simple_rand() >> 11); 2554 unsigned long delay;
2591 2555
2592 if (chance(1, 2)) { 2556 if (chance(1, 2)) {
2593 d->fail_delay = 1; 2557 d->pc_delay = 1;
2594 d->fail_timeout = jiffies + 2558 /* Fail withing 1 minute */
2595 msecs_to_jiffies(delay); 2559 delay = random32() % 60000;
2596 dbg_rcvry("failing after %ums", delay); 2560 d->pc_timeout = jiffies;
2561 d->pc_timeout += msecs_to_jiffies(delay);
2562 ubifs_warn("failing after %lums", delay);
2597 } else { 2563 } else {
2598 d->fail_delay = 2; 2564 d->pc_delay = 2;
2599 d->fail_cnt_max = delay; 2565 delay = random32() % 10000;
2600 dbg_rcvry("failing after %u calls", delay); 2566 /* Fail within 10000 operations */
2567 d->pc_cnt_max = delay;
2568 ubifs_warn("failing after %lu calls", delay);
2601 } 2569 }
2602 } 2570 }
2603 d->fail_cnt += 1; 2571
2572 d->pc_cnt += 1;
2604 } 2573 }
2574
2605 /* Determine if failure delay has expired */ 2575 /* Determine if failure delay has expired */
2606 if (d->fail_delay == 1) { 2576 if (d->pc_delay == 1 && time_before(jiffies, d->pc_timeout))
2607 if (time_before(jiffies, d->fail_timeout))
2608 return 0; 2577 return 0;
2609 } else if (d->fail_delay == 2) 2578 if (d->pc_delay == 2 && d->pc_cnt++ < d->pc_cnt_max)
2610 if (d->fail_cnt++ < d->fail_cnt_max)
2611 return 0; 2579 return 0;
2580
2612 if (lnum == UBIFS_SB_LNUM) { 2581 if (lnum == UBIFS_SB_LNUM) {
2613 if (write) { 2582 if (write && chance(1, 2))
2614 if (chance(1, 2)) 2583 return 0;
2615 return 0; 2584 if (chance(19, 20))
2616 } else if (chance(19, 20))
2617 return 0; 2585 return 0;
2618 dbg_rcvry("failing in super block LEB %d", lnum); 2586 ubifs_warn("failing in super block LEB %d", lnum);
2619 } else if (lnum == UBIFS_MST_LNUM || lnum == UBIFS_MST_LNUM + 1) { 2587 } else if (lnum == UBIFS_MST_LNUM || lnum == UBIFS_MST_LNUM + 1) {
2620 if (chance(19, 20)) 2588 if (chance(19, 20))
2621 return 0; 2589 return 0;
2622 dbg_rcvry("failing in master LEB %d", lnum); 2590 ubifs_warn("failing in master LEB %d", lnum);
2623 } else if (lnum >= UBIFS_LOG_LNUM && lnum <= c->log_last) { 2591 } else if (lnum >= UBIFS_LOG_LNUM && lnum <= c->log_last) {
2624 if (write) { 2592 if (write && chance(99, 100))
2625 if (chance(99, 100))
2626 return 0;
2627 } else if (chance(399, 400))
2628 return 0; 2593 return 0;
2629 dbg_rcvry("failing in log LEB %d", lnum); 2594 if (chance(399, 400))
2595 return 0;
2596 ubifs_warn("failing in log LEB %d", lnum);
2630 } else if (lnum >= c->lpt_first && lnum <= c->lpt_last) { 2597 } else if (lnum >= c->lpt_first && lnum <= c->lpt_last) {
2631 if (write) { 2598 if (write && chance(7, 8))
2632 if (chance(7, 8))
2633 return 0;
2634 } else if (chance(19, 20))
2635 return 0; 2599 return 0;
2636 dbg_rcvry("failing in LPT LEB %d", lnum); 2600 if (chance(19, 20))
2601 return 0;
2602 ubifs_warn("failing in LPT LEB %d", lnum);
2637 } else if (lnum >= c->orph_first && lnum <= c->orph_last) { 2603 } else if (lnum >= c->orph_first && lnum <= c->orph_last) {
2638 if (write) { 2604 if (write && chance(1, 2))
2639 if (chance(1, 2)) 2605 return 0;
2640 return 0; 2606 if (chance(9, 10))
2641 } else if (chance(9, 10))
2642 return 0; 2607 return 0;
2643 dbg_rcvry("failing in orphan LEB %d", lnum); 2608 ubifs_warn("failing in orphan LEB %d", lnum);
2644 } else if (lnum == c->ihead_lnum) { 2609 } else if (lnum == c->ihead_lnum) {
2645 if (chance(99, 100)) 2610 if (chance(99, 100))
2646 return 0; 2611 return 0;
2647 dbg_rcvry("failing in index head LEB %d", lnum); 2612 ubifs_warn("failing in index head LEB %d", lnum);
2648 } else if (c->jheads && lnum == c->jheads[GCHD].wbuf.lnum) { 2613 } else if (c->jheads && lnum == c->jheads[GCHD].wbuf.lnum) {
2649 if (chance(9, 10)) 2614 if (chance(9, 10))
2650 return 0; 2615 return 0;
2651 dbg_rcvry("failing in GC head LEB %d", lnum); 2616 ubifs_warn("failing in GC head LEB %d", lnum);
2652 } else if (write && !RB_EMPTY_ROOT(&c->buds) && 2617 } else if (write && !RB_EMPTY_ROOT(&c->buds) &&
2653 !ubifs_search_bud(c, lnum)) { 2618 !ubifs_search_bud(c, lnum)) {
2654 if (chance(19, 20)) 2619 if (chance(19, 20))
2655 return 0; 2620 return 0;
2656 dbg_rcvry("failing in non-bud LEB %d", lnum); 2621 ubifs_warn("failing in non-bud LEB %d", lnum);
2657 } else if (c->cmt_state == COMMIT_RUNNING_BACKGROUND || 2622 } else if (c->cmt_state == COMMIT_RUNNING_BACKGROUND ||
2658 c->cmt_state == COMMIT_RUNNING_REQUIRED) { 2623 c->cmt_state == COMMIT_RUNNING_REQUIRED) {
2659 if (chance(999, 1000)) 2624 if (chance(999, 1000))
2660 return 0; 2625 return 0;
2661 dbg_rcvry("failing in bud LEB %d commit running", lnum); 2626 ubifs_warn("failing in bud LEB %d commit running", lnum);
2662 } else { 2627 } else {
2663 if (chance(9999, 10000)) 2628 if (chance(9999, 10000))
2664 return 0; 2629 return 0;
2665 dbg_rcvry("failing in bud LEB %d commit not running", lnum); 2630 ubifs_warn("failing in bud LEB %d commit not running", lnum);
2666 } 2631 }
2667 ubifs_err("*** SETTING FAILURE MODE ON (LEB %d) ***", lnum); 2632
2668 d->failure_mode = 1; 2633 d->pc_happened = 1;
2634 ubifs_warn("========== Power cut emulated ==========");
2669 dump_stack(); 2635 dump_stack();
2670 return 1; 2636 return 1;
2671} 2637}
2672 2638
2673static void cut_data(const void *buf, int len) 2639static void cut_data(const void *buf, unsigned int len)
2674{ 2640{
2675 int flen, i; 2641 unsigned int from, to, i, ffs = chance(1, 2);
2676 unsigned char *p = (void *)buf; 2642 unsigned char *p = (void *)buf;
2677 2643
2678 flen = (len * (long long)simple_rand()) >> 15; 2644 from = random32() % (len + 1);
2679 for (i = flen; i < len; i++) 2645 if (chance(1, 2))
2680 p[i] = 0xff; 2646 to = random32() % (len - from + 1);
2681} 2647 else
2648 to = len;
2682 2649
2683int dbg_leb_read(struct ubi_volume_desc *desc, int lnum, char *buf, int offset, 2650 if (from < to)
2684 int len, int check) 2651 ubifs_warn("filled bytes %u-%u with %s", from, to - 1,
2685{ 2652 ffs ? "0xFFs" : "random data");
2686 if (in_failure_mode(desc)) 2653
2687 return -EROFS; 2654 if (ffs)
2688 return ubi_leb_read(desc, lnum, buf, offset, len, check); 2655 for (i = from; i < to; i++)
2656 p[i] = 0xFF;
2657 else
2658 for (i = from; i < to; i++)
2659 p[i] = random32() % 0x100;
2689} 2660}
2690 2661
2691int dbg_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf, 2662int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf,
2692 int offset, int len, int dtype) 2663 int offs, int len, int dtype)
2693{ 2664{
2694 int err, failing; 2665 int err, failing;
2695 2666
2696 if (in_failure_mode(desc)) 2667 if (c->dbg->pc_happened)
2697 return -EROFS; 2668 return -EROFS;
2698 failing = do_fail(desc, lnum, 1); 2669
2670 failing = power_cut_emulated(c, lnum, 1);
2699 if (failing) 2671 if (failing)
2700 cut_data(buf, len); 2672 cut_data(buf, len);
2701 err = ubi_leb_write(desc, lnum, buf, offset, len, dtype); 2673 err = ubi_leb_write(c->ubi, lnum, buf, offs, len, dtype);
2702 if (err) 2674 if (err)
2703 return err; 2675 return err;
2704 if (failing) 2676 if (failing)
@@ -2706,162 +2678,207 @@ int dbg_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf,
2706 return 0; 2678 return 0;
2707} 2679}
2708 2680
2709int dbg_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf, 2681int dbg_leb_change(struct ubifs_info *c, int lnum, const void *buf,
2710 int len, int dtype) 2682 int len, int dtype)
2711{ 2683{
2712 int err; 2684 int err;
2713 2685
2714 if (do_fail(desc, lnum, 1)) 2686 if (c->dbg->pc_happened)
2715 return -EROFS; 2687 return -EROFS;
2716 err = ubi_leb_change(desc, lnum, buf, len, dtype); 2688 if (power_cut_emulated(c, lnum, 1))
2689 return -EROFS;
2690 err = ubi_leb_change(c->ubi, lnum, buf, len, dtype);
2717 if (err) 2691 if (err)
2718 return err; 2692 return err;
2719 if (do_fail(desc, lnum, 1)) 2693 if (power_cut_emulated(c, lnum, 1))
2720 return -EROFS; 2694 return -EROFS;
2721 return 0; 2695 return 0;
2722} 2696}
2723 2697
2724int dbg_leb_erase(struct ubi_volume_desc *desc, int lnum) 2698int dbg_leb_unmap(struct ubifs_info *c, int lnum)
2725{ 2699{
2726 int err; 2700 int err;
2727 2701
2728 if (do_fail(desc, lnum, 0)) 2702 if (c->dbg->pc_happened)
2703 return -EROFS;
2704 if (power_cut_emulated(c, lnum, 0))
2729 return -EROFS; 2705 return -EROFS;
2730 err = ubi_leb_erase(desc, lnum); 2706 err = ubi_leb_unmap(c->ubi, lnum);
2731 if (err) 2707 if (err)
2732 return err; 2708 return err;
2733 if (do_fail(desc, lnum, 0)) 2709 if (power_cut_emulated(c, lnum, 0))
2734 return -EROFS; 2710 return -EROFS;
2735 return 0; 2711 return 0;
2736} 2712}
2737 2713
2738int dbg_leb_unmap(struct ubi_volume_desc *desc, int lnum) 2714int dbg_leb_map(struct ubifs_info *c, int lnum, int dtype)
2739{ 2715{
2740 int err; 2716 int err;
2741 2717
2742 if (do_fail(desc, lnum, 0)) 2718 if (c->dbg->pc_happened)
2743 return -EROFS; 2719 return -EROFS;
2744 err = ubi_leb_unmap(desc, lnum); 2720 if (power_cut_emulated(c, lnum, 0))
2721 return -EROFS;
2722 err = ubi_leb_map(c->ubi, lnum, dtype);
2745 if (err) 2723 if (err)
2746 return err; 2724 return err;
2747 if (do_fail(desc, lnum, 0)) 2725 if (power_cut_emulated(c, lnum, 0))
2748 return -EROFS; 2726 return -EROFS;
2749 return 0; 2727 return 0;
2750} 2728}
2751 2729
2752int dbg_is_mapped(struct ubi_volume_desc *desc, int lnum) 2730/*
2753{ 2731 * Root directory for UBIFS stuff in debugfs. Contains sub-directories which
2754 if (in_failure_mode(desc)) 2732 * contain the stuff specific to particular file-system mounts.
2755 return -EROFS; 2733 */
2756 return ubi_is_mapped(desc, lnum); 2734static struct dentry *dfs_rootdir;
2757}
2758 2735
2759int dbg_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype) 2736static int dfs_file_open(struct inode *inode, struct file *file)
2760{ 2737{
2761 int err; 2738 file->private_data = inode->i_private;
2762 2739 return nonseekable_open(inode, file);
2763 if (do_fail(desc, lnum, 0))
2764 return -EROFS;
2765 err = ubi_leb_map(desc, lnum, dtype);
2766 if (err)
2767 return err;
2768 if (do_fail(desc, lnum, 0))
2769 return -EROFS;
2770 return 0;
2771} 2740}
2772 2741
2773/** 2742/**
2774 * ubifs_debugging_init - initialize UBIFS debugging. 2743 * provide_user_output - provide output to the user reading a debugfs file.
2775 * @c: UBIFS file-system description object 2744 * @val: boolean value for the answer
2745 * @u: the buffer to store the answer at
2746 * @count: size of the buffer
2747 * @ppos: position in the @u output buffer
2776 * 2748 *
2777 * This function initializes debugging-related data for the file system. 2749 * This is a simple helper function which stores @val boolean value in the user
2778 * Returns zero in case of success and a negative error code in case of 2750 * buffer when the user reads one of UBIFS debugfs files. Returns amount of
2751 * bytes written to @u in case of success and a negative error code in case of
2779 * failure. 2752 * failure.
2780 */ 2753 */
2781int ubifs_debugging_init(struct ubifs_info *c) 2754static int provide_user_output(int val, char __user *u, size_t count,
2755 loff_t *ppos)
2782{ 2756{
2783 c->dbg = kzalloc(sizeof(struct ubifs_debug_info), GFP_KERNEL); 2757 char buf[3];
2784 if (!c->dbg)
2785 return -ENOMEM;
2786 2758
2787 failure_mode_init(c); 2759 if (val)
2788 return 0; 2760 buf[0] = '1';
2761 else
2762 buf[0] = '0';
2763 buf[1] = '\n';
2764 buf[2] = 0x00;
2765
2766 return simple_read_from_buffer(u, count, ppos, buf, 2);
2789} 2767}
2790 2768
2791/** 2769static ssize_t dfs_file_read(struct file *file, char __user *u, size_t count,
2792 * ubifs_debugging_exit - free debugging data. 2770 loff_t *ppos)
2793 * @c: UBIFS file-system description object
2794 */
2795void ubifs_debugging_exit(struct ubifs_info *c)
2796{ 2771{
2797 failure_mode_exit(c); 2772 struct dentry *dent = file->f_path.dentry;
2798 kfree(c->dbg); 2773 struct ubifs_info *c = file->private_data;
2799} 2774 struct ubifs_debug_info *d = c->dbg;
2775 int val;
2776
2777 if (dent == d->dfs_chk_gen)
2778 val = d->chk_gen;
2779 else if (dent == d->dfs_chk_index)
2780 val = d->chk_index;
2781 else if (dent == d->dfs_chk_orph)
2782 val = d->chk_orph;
2783 else if (dent == d->dfs_chk_lprops)
2784 val = d->chk_lprops;
2785 else if (dent == d->dfs_chk_fs)
2786 val = d->chk_fs;
2787 else if (dent == d->dfs_tst_rcvry)
2788 val = d->tst_rcvry;
2789 else
2790 return -EINVAL;
2800 2791
2801/* 2792 return provide_user_output(val, u, count, ppos);
2802 * Root directory for UBIFS stuff in debugfs. Contains sub-directories which 2793}
2803 * contain the stuff specific to particular file-system mounts.
2804 */
2805static struct dentry *dfs_rootdir;
2806 2794
2807/** 2795/**
2808 * dbg_debugfs_init - initialize debugfs file-system. 2796 * interpret_user_input - interpret user debugfs file input.
2797 * @u: user-provided buffer with the input
2798 * @count: buffer size
2809 * 2799 *
2810 * UBIFS uses debugfs file-system to expose various debugging knobs to 2800 * This is a helper function which interpret user input to a boolean UBIFS
2811 * user-space. This function creates "ubifs" directory in the debugfs 2801 * debugfs file. Returns %0 or %1 in case of success and a negative error code
2812 * file-system. Returns zero in case of success and a negative error code in 2802 * in case of failure.
2813 * case of failure.
2814 */ 2803 */
2815int dbg_debugfs_init(void) 2804static int interpret_user_input(const char __user *u, size_t count)
2816{ 2805{
2817 dfs_rootdir = debugfs_create_dir("ubifs", NULL); 2806 size_t buf_size;
2818 if (IS_ERR(dfs_rootdir)) { 2807 char buf[8];
2819 int err = PTR_ERR(dfs_rootdir);
2820 ubifs_err("cannot create \"ubifs\" debugfs directory, "
2821 "error %d\n", err);
2822 return err;
2823 }
2824 2808
2825 return 0; 2809 buf_size = min_t(size_t, count, (sizeof(buf) - 1));
2826} 2810 if (copy_from_user(buf, u, buf_size))
2811 return -EFAULT;
2827 2812
2828/** 2813 if (buf[0] == '1')
2829 * dbg_debugfs_exit - remove the "ubifs" directory from debugfs file-system. 2814 return 1;
2830 */ 2815 else if (buf[0] == '0')
2831void dbg_debugfs_exit(void) 2816 return 0;
2832{
2833 debugfs_remove(dfs_rootdir);
2834}
2835 2817
2836static int open_debugfs_file(struct inode *inode, struct file *file) 2818 return -EINVAL;
2837{
2838 file->private_data = inode->i_private;
2839 return nonseekable_open(inode, file);
2840} 2819}
2841 2820
2842static ssize_t write_debugfs_file(struct file *file, const char __user *buf, 2821static ssize_t dfs_file_write(struct file *file, const char __user *u,
2843 size_t count, loff_t *ppos) 2822 size_t count, loff_t *ppos)
2844{ 2823{
2845 struct ubifs_info *c = file->private_data; 2824 struct ubifs_info *c = file->private_data;
2846 struct ubifs_debug_info *d = c->dbg; 2825 struct ubifs_debug_info *d = c->dbg;
2826 struct dentry *dent = file->f_path.dentry;
2827 int val;
2847 2828
2848 if (file->f_path.dentry == d->dfs_dump_lprops) 2829 /*
2830 * TODO: this is racy - the file-system might have already been
2831 * unmounted and we'd oops in this case. The plan is to fix it with
2832 * help of 'iterate_supers_type()' which we should have in v3.0: when
2833 * a debugfs opened, we rember FS's UUID in file->private_data. Then
2834 * whenever we access the FS via a debugfs file, we iterate all UBIFS
2835 * superblocks and fine the one with the same UUID, and take the
2836 * locking right.
2837 *
2838 * The other way to go suggested by Al Viro is to create a separate
2839 * 'ubifs-debug' file-system instead.
2840 */
2841 if (file->f_path.dentry == d->dfs_dump_lprops) {
2849 dbg_dump_lprops(c); 2842 dbg_dump_lprops(c);
2850 else if (file->f_path.dentry == d->dfs_dump_budg) 2843 return count;
2844 }
2845 if (file->f_path.dentry == d->dfs_dump_budg) {
2851 dbg_dump_budg(c, &c->bi); 2846 dbg_dump_budg(c, &c->bi);
2852 else if (file->f_path.dentry == d->dfs_dump_tnc) { 2847 return count;
2848 }
2849 if (file->f_path.dentry == d->dfs_dump_tnc) {
2853 mutex_lock(&c->tnc_mutex); 2850 mutex_lock(&c->tnc_mutex);
2854 dbg_dump_tnc(c); 2851 dbg_dump_tnc(c);
2855 mutex_unlock(&c->tnc_mutex); 2852 mutex_unlock(&c->tnc_mutex);
2856 } else 2853 return count;
2854 }
2855
2856 val = interpret_user_input(u, count);
2857 if (val < 0)
2858 return val;
2859
2860 if (dent == d->dfs_chk_gen)
2861 d->chk_gen = val;
2862 else if (dent == d->dfs_chk_index)
2863 d->chk_index = val;
2864 else if (dent == d->dfs_chk_orph)
2865 d->chk_orph = val;
2866 else if (dent == d->dfs_chk_lprops)
2867 d->chk_lprops = val;
2868 else if (dent == d->dfs_chk_fs)
2869 d->chk_fs = val;
2870 else if (dent == d->dfs_tst_rcvry)
2871 d->tst_rcvry = val;
2872 else
2857 return -EINVAL; 2873 return -EINVAL;
2858 2874
2859 return count; 2875 return count;
2860} 2876}
2861 2877
2862static const struct file_operations dfs_fops = { 2878static const struct file_operations dfs_fops = {
2863 .open = open_debugfs_file, 2879 .open = dfs_file_open,
2864 .write = write_debugfs_file, 2880 .read = dfs_file_read,
2881 .write = dfs_file_write,
2865 .owner = THIS_MODULE, 2882 .owner = THIS_MODULE,
2866 .llseek = no_llseek, 2883 .llseek = no_llseek,
2867}; 2884};
@@ -2880,12 +2897,20 @@ static const struct file_operations dfs_fops = {
2880 */ 2897 */
2881int dbg_debugfs_init_fs(struct ubifs_info *c) 2898int dbg_debugfs_init_fs(struct ubifs_info *c)
2882{ 2899{
2883 int err; 2900 int err, n;
2884 const char *fname; 2901 const char *fname;
2885 struct dentry *dent; 2902 struct dentry *dent;
2886 struct ubifs_debug_info *d = c->dbg; 2903 struct ubifs_debug_info *d = c->dbg;
2887 2904
2888 sprintf(d->dfs_dir_name, "ubi%d_%d", c->vi.ubi_num, c->vi.vol_id); 2905 n = snprintf(d->dfs_dir_name, UBIFS_DFS_DIR_LEN + 1, UBIFS_DFS_DIR_NAME,
2906 c->vi.ubi_num, c->vi.vol_id);
2907 if (n == UBIFS_DFS_DIR_LEN) {
2908 /* The array size is too small */
2909 fname = UBIFS_DFS_DIR_NAME;
2910 dent = ERR_PTR(-EINVAL);
2911 goto out;
2912 }
2913
2889 fname = d->dfs_dir_name; 2914 fname = d->dfs_dir_name;
2890 dent = debugfs_create_dir(fname, dfs_rootdir); 2915 dent = debugfs_create_dir(fname, dfs_rootdir);
2891 if (IS_ERR_OR_NULL(dent)) 2916 if (IS_ERR_OR_NULL(dent))
@@ -2910,13 +2935,55 @@ int dbg_debugfs_init_fs(struct ubifs_info *c)
2910 goto out_remove; 2935 goto out_remove;
2911 d->dfs_dump_tnc = dent; 2936 d->dfs_dump_tnc = dent;
2912 2937
2938 fname = "chk_general";
2939 dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c,
2940 &dfs_fops);
2941 if (IS_ERR_OR_NULL(dent))
2942 goto out_remove;
2943 d->dfs_chk_gen = dent;
2944
2945 fname = "chk_index";
2946 dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c,
2947 &dfs_fops);
2948 if (IS_ERR_OR_NULL(dent))
2949 goto out_remove;
2950 d->dfs_chk_index = dent;
2951
2952 fname = "chk_orphans";
2953 dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c,
2954 &dfs_fops);
2955 if (IS_ERR_OR_NULL(dent))
2956 goto out_remove;
2957 d->dfs_chk_orph = dent;
2958
2959 fname = "chk_lprops";
2960 dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c,
2961 &dfs_fops);
2962 if (IS_ERR_OR_NULL(dent))
2963 goto out_remove;
2964 d->dfs_chk_lprops = dent;
2965
2966 fname = "chk_fs";
2967 dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c,
2968 &dfs_fops);
2969 if (IS_ERR_OR_NULL(dent))
2970 goto out_remove;
2971 d->dfs_chk_fs = dent;
2972
2973 fname = "tst_recovery";
2974 dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, d->dfs_dir, c,
2975 &dfs_fops);
2976 if (IS_ERR_OR_NULL(dent))
2977 goto out_remove;
2978 d->dfs_tst_rcvry = dent;
2979
2913 return 0; 2980 return 0;
2914 2981
2915out_remove: 2982out_remove:
2916 debugfs_remove_recursive(d->dfs_dir); 2983 debugfs_remove_recursive(d->dfs_dir);
2917out: 2984out:
2918 err = dent ? PTR_ERR(dent) : -ENODEV; 2985 err = dent ? PTR_ERR(dent) : -ENODEV;
2919 ubifs_err("cannot create \"%s\" debugfs directory, error %d\n", 2986 ubifs_err("cannot create \"%s\" debugfs file or directory, error %d\n",
2920 fname, err); 2987 fname, err);
2921 return err; 2988 return err;
2922} 2989}
@@ -2930,4 +2997,179 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c)
2930 debugfs_remove_recursive(c->dbg->dfs_dir); 2997 debugfs_remove_recursive(c->dbg->dfs_dir);
2931} 2998}
2932 2999
3000struct ubifs_global_debug_info ubifs_dbg;
3001
3002static struct dentry *dfs_chk_gen;
3003static struct dentry *dfs_chk_index;
3004static struct dentry *dfs_chk_orph;
3005static struct dentry *dfs_chk_lprops;
3006static struct dentry *dfs_chk_fs;
3007static struct dentry *dfs_tst_rcvry;
3008
3009static ssize_t dfs_global_file_read(struct file *file, char __user *u,
3010 size_t count, loff_t *ppos)
3011{
3012 struct dentry *dent = file->f_path.dentry;
3013 int val;
3014
3015 if (dent == dfs_chk_gen)
3016 val = ubifs_dbg.chk_gen;
3017 else if (dent == dfs_chk_index)
3018 val = ubifs_dbg.chk_index;
3019 else if (dent == dfs_chk_orph)
3020 val = ubifs_dbg.chk_orph;
3021 else if (dent == dfs_chk_lprops)
3022 val = ubifs_dbg.chk_lprops;
3023 else if (dent == dfs_chk_fs)
3024 val = ubifs_dbg.chk_fs;
3025 else if (dent == dfs_tst_rcvry)
3026 val = ubifs_dbg.tst_rcvry;
3027 else
3028 return -EINVAL;
3029
3030 return provide_user_output(val, u, count, ppos);
3031}
3032
3033static ssize_t dfs_global_file_write(struct file *file, const char __user *u,
3034 size_t count, loff_t *ppos)
3035{
3036 struct dentry *dent = file->f_path.dentry;
3037 int val;
3038
3039 val = interpret_user_input(u, count);
3040 if (val < 0)
3041 return val;
3042
3043 if (dent == dfs_chk_gen)
3044 ubifs_dbg.chk_gen = val;
3045 else if (dent == dfs_chk_index)
3046 ubifs_dbg.chk_index = val;
3047 else if (dent == dfs_chk_orph)
3048 ubifs_dbg.chk_orph = val;
3049 else if (dent == dfs_chk_lprops)
3050 ubifs_dbg.chk_lprops = val;
3051 else if (dent == dfs_chk_fs)
3052 ubifs_dbg.chk_fs = val;
3053 else if (dent == dfs_tst_rcvry)
3054 ubifs_dbg.tst_rcvry = val;
3055 else
3056 return -EINVAL;
3057
3058 return count;
3059}
3060
3061static const struct file_operations dfs_global_fops = {
3062 .read = dfs_global_file_read,
3063 .write = dfs_global_file_write,
3064 .owner = THIS_MODULE,
3065 .llseek = no_llseek,
3066};
3067
3068/**
3069 * dbg_debugfs_init - initialize debugfs file-system.
3070 *
3071 * UBIFS uses debugfs file-system to expose various debugging knobs to
3072 * user-space. This function creates "ubifs" directory in the debugfs
3073 * file-system. Returns zero in case of success and a negative error code in
3074 * case of failure.
3075 */
3076int dbg_debugfs_init(void)
3077{
3078 int err;
3079 const char *fname;
3080 struct dentry *dent;
3081
3082 fname = "ubifs";
3083 dent = debugfs_create_dir(fname, NULL);
3084 if (IS_ERR_OR_NULL(dent))
3085 goto out;
3086 dfs_rootdir = dent;
3087
3088 fname = "chk_general";
3089 dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL,
3090 &dfs_global_fops);
3091 if (IS_ERR_OR_NULL(dent))
3092 goto out_remove;
3093 dfs_chk_gen = dent;
3094
3095 fname = "chk_index";
3096 dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL,
3097 &dfs_global_fops);
3098 if (IS_ERR_OR_NULL(dent))
3099 goto out_remove;
3100 dfs_chk_index = dent;
3101
3102 fname = "chk_orphans";
3103 dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL,
3104 &dfs_global_fops);
3105 if (IS_ERR_OR_NULL(dent))
3106 goto out_remove;
3107 dfs_chk_orph = dent;
3108
3109 fname = "chk_lprops";
3110 dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL,
3111 &dfs_global_fops);
3112 if (IS_ERR_OR_NULL(dent))
3113 goto out_remove;
3114 dfs_chk_lprops = dent;
3115
3116 fname = "chk_fs";
3117 dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL,
3118 &dfs_global_fops);
3119 if (IS_ERR_OR_NULL(dent))
3120 goto out_remove;
3121 dfs_chk_fs = dent;
3122
3123 fname = "tst_recovery";
3124 dent = debugfs_create_file(fname, S_IRUSR | S_IWUSR, dfs_rootdir, NULL,
3125 &dfs_global_fops);
3126 if (IS_ERR_OR_NULL(dent))
3127 goto out_remove;
3128 dfs_tst_rcvry = dent;
3129
3130 return 0;
3131
3132out_remove:
3133 debugfs_remove_recursive(dfs_rootdir);
3134out:
3135 err = dent ? PTR_ERR(dent) : -ENODEV;
3136 ubifs_err("cannot create \"%s\" debugfs file or directory, error %d\n",
3137 fname, err);
3138 return err;
3139}
3140
3141/**
3142 * dbg_debugfs_exit - remove the "ubifs" directory from debugfs file-system.
3143 */
3144void dbg_debugfs_exit(void)
3145{
3146 debugfs_remove_recursive(dfs_rootdir);
3147}
3148
3149/**
3150 * ubifs_debugging_init - initialize UBIFS debugging.
3151 * @c: UBIFS file-system description object
3152 *
3153 * This function initializes debugging-related data for the file system.
3154 * Returns zero in case of success and a negative error code in case of
3155 * failure.
3156 */
3157int ubifs_debugging_init(struct ubifs_info *c)
3158{
3159 c->dbg = kzalloc(sizeof(struct ubifs_debug_info), GFP_KERNEL);
3160 if (!c->dbg)
3161 return -ENOMEM;
3162
3163 return 0;
3164}
3165
3166/**
3167 * ubifs_debugging_exit - free debugging data.
3168 * @c: UBIFS file-system description object
3169 */
3170void ubifs_debugging_exit(struct ubifs_info *c)
3171{
3172 kfree(c->dbg);
3173}
3174
2933#endif /* CONFIG_UBIFS_FS_DEBUG */ 3175#endif /* CONFIG_UBIFS_FS_DEBUG */
diff --git a/fs/ubifs/debug.h b/fs/ubifs/debug.h
index a811ac4a26bb..45174b534377 100644
--- a/fs/ubifs/debug.h
+++ b/fs/ubifs/debug.h
@@ -31,18 +31,25 @@ typedef int (*dbg_znode_callback)(struct ubifs_info *c,
31 31
32#ifdef CONFIG_UBIFS_FS_DEBUG 32#ifdef CONFIG_UBIFS_FS_DEBUG
33 33
34#include <linux/random.h> 34/*
35 * The UBIFS debugfs directory name pattern and maximum name length (3 for "ubi"
36 * + 1 for "_" and plus 2x2 for 2 UBI numbers and 1 for the trailing zero byte.
37 */
38#define UBIFS_DFS_DIR_NAME "ubi%d_%d"
39#define UBIFS_DFS_DIR_LEN (3 + 1 + 2*2 + 1)
35 40
36/** 41/**
37 * ubifs_debug_info - per-FS debugging information. 42 * ubifs_debug_info - per-FS debugging information.
38 * @old_zroot: old index root - used by 'dbg_check_old_index()' 43 * @old_zroot: old index root - used by 'dbg_check_old_index()'
39 * @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()'
40 * @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()'
41 * @failure_mode: failure mode for recovery testing 46 *
42 * @fail_delay: 0=>don't delay, 1=>delay a time, 2=>delay a number of calls 47 * @pc_happened: non-zero if an emulated power cut happened
43 * @fail_timeout: time in jiffies when delay of failure mode expires 48 * @pc_delay: 0=>don't delay, 1=>delay a time, 2=>delay a number of calls
44 * @fail_cnt: current number of calls to failure mode I/O functions 49 * @pc_timeout: time in jiffies when delay of failure mode expires
45 * @fail_cnt_max: number of calls by which to delay failure mode 50 * @pc_cnt: current number of calls to failure mode I/O functions
51 * @pc_cnt_max: number of calls by which to delay failure mode
52 *
46 * @chk_lpt_sz: used by LPT tree size checker 53 * @chk_lpt_sz: used by LPT tree size checker
47 * @chk_lpt_sz2: used by LPT tree size checker 54 * @chk_lpt_sz2: used by LPT tree size checker
48 * @chk_lpt_wastage: used by LPT tree size checker 55 * @chk_lpt_wastage: used by LPT tree size checker
@@ -56,21 +63,36 @@ typedef int (*dbg_znode_callback)(struct ubifs_info *c,
56 * @saved_free: saved amount of free space 63 * @saved_free: saved amount of free space
57 * @saved_idx_gc_cnt: saved value of @c->idx_gc_cnt 64 * @saved_idx_gc_cnt: saved value of @c->idx_gc_cnt
58 * 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 *
59 * @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
60 * @dfs_dir: direntry object of the file-system debugfs directory 74 * @dfs_dir: direntry object of the file-system debugfs directory
61 * @dfs_dump_lprops: "dump lprops" debugfs knob 75 * @dfs_dump_lprops: "dump lprops" debugfs knob
62 * @dfs_dump_budg: "dump budgeting information" debugfs knob 76 * @dfs_dump_budg: "dump budgeting information" debugfs knob
63 * @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
64 */ 84 */
65struct ubifs_debug_info { 85struct ubifs_debug_info {
66 struct ubifs_zbranch old_zroot; 86 struct ubifs_zbranch old_zroot;
67 int old_zroot_level; 87 int old_zroot_level;
68 unsigned long long old_zroot_sqnum; 88 unsigned long long old_zroot_sqnum;
69 int failure_mode; 89
70 int fail_delay; 90 int pc_happened;
71 unsigned long fail_timeout; 91 int pc_delay;
72 unsigned int fail_cnt; 92 unsigned long pc_timeout;
73 unsigned int fail_cnt_max; 93 unsigned int pc_cnt;
94 unsigned int pc_cnt_max;
95
74 long long chk_lpt_sz; 96 long long chk_lpt_sz;
75 long long chk_lpt_sz2; 97 long long chk_lpt_sz2;
76 long long chk_lpt_wastage; 98 long long chk_lpt_wastage;
@@ -84,11 +106,43 @@ struct ubifs_debug_info {
84 long long saved_free; 106 long long saved_free;
85 int saved_idx_gc_cnt; 107 int saved_idx_gc_cnt;
86 108
87 char dfs_dir_name[100]; 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
116 char dfs_dir_name[UBIFS_DFS_DIR_LEN + 1];
88 struct dentry *dfs_dir; 117 struct dentry *dfs_dir;
89 struct dentry *dfs_dump_lprops; 118 struct dentry *dfs_dump_lprops;
90 struct dentry *dfs_dump_budg; 119 struct dentry *dfs_dump_budg;
91 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;
127};
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;
92}; 146};
93 147
94#define ubifs_assert(expr) do { \ 148#define ubifs_assert(expr) do { \
@@ -127,6 +181,8 @@ const char *dbg_key_str1(const struct ubifs_info *c,
127#define DBGKEY(key) dbg_key_str0(c, (key)) 181#define DBGKEY(key) dbg_key_str0(c, (key))
128#define DBGKEY1(key) dbg_key_str1(c, (key)) 182#define DBGKEY1(key) dbg_key_str1(c, (key))
129 183
184extern spinlock_t dbg_lock;
185
130#define ubifs_dbg_msg(type, fmt, ...) do { \ 186#define ubifs_dbg_msg(type, fmt, ...) do { \
131 spin_lock(&dbg_lock); \ 187 spin_lock(&dbg_lock); \
132 pr_debug("UBIFS DBG " type ": " fmt "\n", ##__VA_ARGS__); \ 188 pr_debug("UBIFS DBG " type ": " fmt "\n", ##__VA_ARGS__); \
@@ -162,41 +218,36 @@ const char *dbg_key_str1(const struct ubifs_info *c,
162/* Additional recovery messages */ 218/* Additional recovery messages */
163#define dbg_rcvry(fmt, ...) ubifs_dbg_msg("rcvry", fmt, ##__VA_ARGS__) 219#define dbg_rcvry(fmt, ...) ubifs_dbg_msg("rcvry", fmt, ##__VA_ARGS__)
164 220
165/* 221extern struct ubifs_global_debug_info ubifs_dbg;
166 * Debugging check flags.
167 *
168 * UBIFS_CHK_GEN: general checks
169 * UBIFS_CHK_TNC: check TNC
170 * UBIFS_CHK_IDX_SZ: check index size
171 * UBIFS_CHK_ORPH: check orphans
172 * UBIFS_CHK_OLD_IDX: check the old index
173 * UBIFS_CHK_LPROPS: check lprops
174 * UBIFS_CHK_FS: check the file-system
175 */
176enum {
177 UBIFS_CHK_GEN = 0x1,
178 UBIFS_CHK_TNC = 0x2,
179 UBIFS_CHK_IDX_SZ = 0x4,
180 UBIFS_CHK_ORPH = 0x8,
181 UBIFS_CHK_OLD_IDX = 0x10,
182 UBIFS_CHK_LPROPS = 0x20,
183 UBIFS_CHK_FS = 0x40,
184};
185
186/*
187 * Special testing flags.
188 *
189 * UBIFS_TST_RCVRY: failure mode for recovery testing
190 */
191enum {
192 UBIFS_TST_RCVRY = 0x4,
193};
194
195extern spinlock_t dbg_lock;
196 222
197extern unsigned int ubifs_msg_flags; 223static inline int dbg_is_chk_gen(const struct ubifs_info *c)
198extern unsigned int ubifs_chk_flags; 224{
199extern unsigned int ubifs_tst_flags; 225 return !!(ubifs_dbg.chk_gen || c->dbg->chk_gen);
226}
227static inline int dbg_is_chk_index(const struct ubifs_info *c)
228{
229 return !!(ubifs_dbg.chk_index || c->dbg->chk_index);
230}
231static inline int dbg_is_chk_orph(const struct ubifs_info *c)
232{
233 return !!(ubifs_dbg.chk_orph || c->dbg->chk_orph);
234}
235static inline int dbg_is_chk_lprops(const struct ubifs_info *c)
236{
237 return !!(ubifs_dbg.chk_lprops || c->dbg->chk_lprops);
238}
239static inline int dbg_is_chk_fs(const struct ubifs_info *c)
240{
241 return !!(ubifs_dbg.chk_fs || c->dbg->chk_fs);
242}
243static inline int dbg_is_tst_rcvry(const struct ubifs_info *c)
244{
245 return !!(ubifs_dbg.tst_rcvry || c->dbg->tst_rcvry);
246}
247static inline int dbg_is_power_cut(const struct ubifs_info *c)
248{
249 return !!c->dbg->pc_happened;
250}
200 251
201int ubifs_debugging_init(struct ubifs_info *c); 252int ubifs_debugging_init(struct ubifs_info *c);
202void ubifs_debugging_exit(struct ubifs_info *c); 253void ubifs_debugging_exit(struct ubifs_info *c);
@@ -207,7 +258,7 @@ const char *dbg_cstate(int cmt_state);
207const char *dbg_jhead(int jhead); 258const char *dbg_jhead(int jhead);
208const char *dbg_get_key_dump(const struct ubifs_info *c, 259const char *dbg_get_key_dump(const struct ubifs_info *c,
209 const union ubifs_key *key); 260 const union ubifs_key *key);
210void dbg_dump_inode(const struct ubifs_info *c, const struct inode *inode); 261void dbg_dump_inode(struct ubifs_info *c, const struct inode *inode);
211void dbg_dump_node(const struct ubifs_info *c, const void *node); 262void dbg_dump_node(const struct ubifs_info *c, const void *node);
212void dbg_dump_lpt_node(const struct ubifs_info *c, void *node, int lnum, 263void dbg_dump_lpt_node(const struct ubifs_info *c, void *node, int lnum,
213 int offs); 264 int offs);
@@ -240,8 +291,8 @@ int dbg_check_cats(struct ubifs_info *c);
240int dbg_check_ltab(struct ubifs_info *c); 291int dbg_check_ltab(struct ubifs_info *c);
241int dbg_chk_lpt_free_spc(struct ubifs_info *c); 292int dbg_chk_lpt_free_spc(struct ubifs_info *c);
242int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len); 293int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len);
243int dbg_check_synced_i_size(struct inode *inode); 294int dbg_check_synced_i_size(const struct ubifs_info *c, struct inode *inode);
244int dbg_check_dir_size(struct ubifs_info *c, const struct inode *dir); 295int dbg_check_dir(struct ubifs_info *c, const struct inode *dir);
245int dbg_check_tnc(struct ubifs_info *c, int extra); 296int dbg_check_tnc(struct ubifs_info *c, int extra);
246int dbg_check_idx_size(struct ubifs_info *c, long long idx_size); 297int dbg_check_idx_size(struct ubifs_info *c, long long idx_size);
247int dbg_check_filesystem(struct ubifs_info *c); 298int dbg_check_filesystem(struct ubifs_info *c);
@@ -254,54 +305,12 @@ int dbg_check_inode_size(struct ubifs_info *c, const struct inode *inode,
254int dbg_check_data_nodes_order(struct ubifs_info *c, struct list_head *head); 305int dbg_check_data_nodes_order(struct ubifs_info *c, struct list_head *head);
255int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head); 306int dbg_check_nondata_nodes_order(struct ubifs_info *c, struct list_head *head);
256 307
257/* Force the use of in-the-gaps method for testing */ 308int dbg_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs,
258static inline int dbg_force_in_the_gaps_enabled(void) 309 int len, int dtype);
259{ 310int dbg_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len,
260 return ubifs_chk_flags & UBIFS_CHK_GEN; 311 int dtype);
261} 312int dbg_leb_unmap(struct ubifs_info *c, int lnum);
262int dbg_force_in_the_gaps(void); 313int dbg_leb_map(struct ubifs_info *c, int lnum, int dtype);
263
264/* Failure mode for recovery testing */
265#define dbg_failure_mode (ubifs_tst_flags & UBIFS_TST_RCVRY)
266
267#ifndef UBIFS_DBG_PRESERVE_UBI
268#define ubi_leb_read dbg_leb_read
269#define ubi_leb_write dbg_leb_write
270#define ubi_leb_change dbg_leb_change
271#define ubi_leb_erase dbg_leb_erase
272#define ubi_leb_unmap dbg_leb_unmap
273#define ubi_is_mapped dbg_is_mapped
274#define ubi_leb_map dbg_leb_map
275#endif
276
277int dbg_leb_read(struct ubi_volume_desc *desc, int lnum, char *buf, int offset,
278 int len, int check);
279int dbg_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf,
280 int offset, int len, int dtype);
281int dbg_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf,
282 int len, int dtype);
283int dbg_leb_erase(struct ubi_volume_desc *desc, int lnum);
284int dbg_leb_unmap(struct ubi_volume_desc *desc, int lnum);
285int dbg_is_mapped(struct ubi_volume_desc *desc, int lnum);
286int dbg_leb_map(struct ubi_volume_desc *desc, int lnum, int dtype);
287
288static inline int dbg_read(struct ubi_volume_desc *desc, int lnum, char *buf,
289 int offset, int len)
290{
291 return dbg_leb_read(desc, lnum, buf, offset, len, 0);
292}
293
294static inline int dbg_write(struct ubi_volume_desc *desc, int lnum,
295 const void *buf, int offset, int len)
296{
297 return dbg_leb_write(desc, lnum, buf, offset, len, UBI_UNKNOWN);
298}
299
300static inline int dbg_change(struct ubi_volume_desc *desc, int lnum,
301 const void *buf, int len)
302{
303 return dbg_leb_change(desc, lnum, buf, len, UBI_UNKNOWN);
304}
305 314
306/* Debugfs-related stuff */ 315/* Debugfs-related stuff */
307int dbg_debugfs_init(void); 316int dbg_debugfs_init(void);
@@ -313,7 +322,7 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c);
313 322
314/* Use "if (0)" to make compiler check arguments even if debugging is off */ 323/* Use "if (0)" to make compiler check arguments even if debugging is off */
315#define ubifs_assert(expr) do { \ 324#define ubifs_assert(expr) do { \
316 if (0 && (expr)) \ 325 if (0) \
317 printk(KERN_CRIT "UBIFS assert failed in %s at %u (pid %d)\n", \ 326 printk(KERN_CRIT "UBIFS assert failed in %s at %u (pid %d)\n", \
318 __func__, __LINE__, current->pid); \ 327 __func__, __LINE__, current->pid); \
319} while (0) 328} while (0)
@@ -323,6 +332,9 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c);
323 ubifs_err(fmt, ##__VA_ARGS__); \ 332 ubifs_err(fmt, ##__VA_ARGS__); \
324} while (0) 333} while (0)
325 334
335#define DBGKEY(key) ((char *)(key))
336#define DBGKEY1(key) ((char *)(key))
337
326#define ubifs_dbg_msg(fmt, ...) do { \ 338#define ubifs_dbg_msg(fmt, ...) do { \
327 if (0) \ 339 if (0) \
328 pr_debug(fmt "\n", ##__VA_ARGS__); \ 340 pr_debug(fmt "\n", ##__VA_ARGS__); \
@@ -346,9 +358,6 @@ void dbg_debugfs_exit_fs(struct ubifs_info *c);
346#define dbg_scan(fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__) 358#define dbg_scan(fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__)
347#define dbg_rcvry(fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__) 359#define dbg_rcvry(fmt, ...) ubifs_dbg_msg(fmt, ##__VA_ARGS__)
348 360
349#define DBGKEY(key) ((char *)(key))
350#define DBGKEY1(key) ((char *)(key))
351
352static inline int ubifs_debugging_init(struct ubifs_info *c) { return 0; } 361static inline int ubifs_debugging_init(struct ubifs_info *c) { return 0; }
353static inline void ubifs_debugging_exit(struct ubifs_info *c) { return; } 362static inline void ubifs_debugging_exit(struct ubifs_info *c) { return; }
354static inline const char *dbg_ntype(int type) { return ""; } 363static inline const char *dbg_ntype(int type) { return ""; }
@@ -357,7 +366,7 @@ static inline const char *dbg_jhead(int jhead) { return ""; }
357static inline const char * 366static inline const char *
358dbg_get_key_dump(const struct ubifs_info *c, 367dbg_get_key_dump(const struct ubifs_info *c,
359 const union ubifs_key *key) { return ""; } 368 const union ubifs_key *key) { return ""; }
360static inline void dbg_dump_inode(const struct ubifs_info *c, 369static inline void dbg_dump_inode(struct ubifs_info *c,
361 const struct inode *inode) { return; } 370 const struct inode *inode) { return; }
362static inline void dbg_dump_node(const struct ubifs_info *c, 371static inline void dbg_dump_node(const struct ubifs_info *c,
363 const void *node) { return; } 372 const void *node) { return; }
@@ -409,9 +418,11 @@ static inline int dbg_check_ltab(struct ubifs_info *c) { return 0; }
409static inline int dbg_chk_lpt_free_spc(struct ubifs_info *c) { return 0; } 418static inline int dbg_chk_lpt_free_spc(struct ubifs_info *c) { return 0; }
410static inline int dbg_chk_lpt_sz(struct ubifs_info *c, 419static inline int dbg_chk_lpt_sz(struct ubifs_info *c,
411 int action, int len) { return 0; } 420 int action, int len) { return 0; }
412static inline int dbg_check_synced_i_size(struct inode *inode) { return 0; } 421static inline int
413static inline int dbg_check_dir_size(struct ubifs_info *c, 422dbg_check_synced_i_size(const struct ubifs_info *c,
414 const struct inode *dir) { return 0; } 423 struct inode *inode) { return 0; }
424static inline int dbg_check_dir(struct ubifs_info *c,
425 const struct inode *dir) { return 0; }
415static inline int dbg_check_tnc(struct ubifs_info *c, int extra) { return 0; } 426static inline int dbg_check_tnc(struct ubifs_info *c, int extra) { return 0; }
416static inline int dbg_check_idx_size(struct ubifs_info *c, 427static inline int dbg_check_idx_size(struct ubifs_info *c,
417 long long idx_size) { return 0; } 428 long long idx_size) { return 0; }
@@ -431,9 +442,23 @@ static inline int
431dbg_check_nondata_nodes_order(struct ubifs_info *c, 442dbg_check_nondata_nodes_order(struct ubifs_info *c,
432 struct list_head *head) { return 0; } 443 struct list_head *head) { return 0; }
433 444
434static inline int dbg_force_in_the_gaps(void) { return 0; } 445static inline int dbg_leb_write(struct ubifs_info *c, int lnum,
435#define dbg_force_in_the_gaps_enabled() 0 446 const void *buf, int offset,
436#define dbg_failure_mode 0 447 int len, int dtype) { return 0; }
448static inline int dbg_leb_change(struct ubifs_info *c, int lnum,
449 const void *buf, int len,
450 int dtype) { return 0; }
451static inline int dbg_leb_unmap(struct ubifs_info *c, int lnum) { return 0; }
452static inline int dbg_leb_map(struct ubifs_info *c, int lnum,
453 int dtype) { return 0; }
454
455static inline int dbg_is_chk_gen(const struct ubifs_info *c) { return 0; }
456static inline int dbg_is_chk_index(const struct ubifs_info *c) { return 0; }
457static inline int dbg_is_chk_orph(const struct ubifs_info *c) { return 0; }
458static inline int dbg_is_chk_lprops(const struct ubifs_info *c) { return 0; }
459static inline int dbg_is_chk_fs(const struct ubifs_info *c) { return 0; }
460static inline int dbg_is_tst_rcvry(const struct ubifs_info *c) { return 0; }
461static inline int dbg_is_power_cut(const struct ubifs_info *c) { return 0; }
437 462
438static inline int dbg_debugfs_init(void) { return 0; } 463static inline int dbg_debugfs_init(void) { return 0; }
439static inline void dbg_debugfs_exit(void) { return; } 464static inline void dbg_debugfs_exit(void) { return; }
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index ef5abd38f0bf..683492043317 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -102,7 +102,7 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
102 * UBIFS has to fully control "clean <-> dirty" transitions of inodes 102 * UBIFS has to fully control "clean <-> dirty" transitions of inodes
103 * to make budgeting work. 103 * to make budgeting work.
104 */ 104 */
105 inode->i_flags |= (S_NOCMTIME); 105 inode->i_flags |= S_NOCMTIME;
106 106
107 inode_init_owner(inode, dir, mode); 107 inode_init_owner(inode, dir, mode);
108 inode->i_mtime = inode->i_atime = inode->i_ctime = 108 inode->i_mtime = inode->i_atime = inode->i_ctime =
@@ -172,9 +172,11 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
172 172
173#ifdef CONFIG_UBIFS_FS_DEBUG 173#ifdef CONFIG_UBIFS_FS_DEBUG
174 174
175static int dbg_check_name(struct ubifs_dent_node *dent, struct qstr *nm) 175static int dbg_check_name(const struct ubifs_info *c,
176 const struct ubifs_dent_node *dent,
177 const struct qstr *nm)
176{ 178{
177 if (!(ubifs_chk_flags & UBIFS_CHK_GEN)) 179 if (!dbg_is_chk_gen(c))
178 return 0; 180 return 0;
179 if (le16_to_cpu(dent->nlen) != nm->len) 181 if (le16_to_cpu(dent->nlen) != nm->len)
180 return -EINVAL; 182 return -EINVAL;
@@ -185,7 +187,7 @@ static int dbg_check_name(struct ubifs_dent_node *dent, struct qstr *nm)
185 187
186#else 188#else
187 189
188#define dbg_check_name(dent, nm) 0 190#define dbg_check_name(c, dent, nm) 0
189 191
190#endif 192#endif
191 193
@@ -219,7 +221,7 @@ static struct dentry *ubifs_lookup(struct inode *dir, struct dentry *dentry,
219 goto out; 221 goto out;
220 } 222 }
221 223
222 if (dbg_check_name(dent, &dentry->d_name)) { 224 if (dbg_check_name(c, dent, &dentry->d_name)) {
223 err = -EINVAL; 225 err = -EINVAL;
224 goto out; 226 goto out;
225 } 227 }
@@ -522,7 +524,7 @@ static int ubifs_link(struct dentry *old_dentry, struct inode *dir,
522 ubifs_assert(mutex_is_locked(&dir->i_mutex)); 524 ubifs_assert(mutex_is_locked(&dir->i_mutex));
523 ubifs_assert(mutex_is_locked(&inode->i_mutex)); 525 ubifs_assert(mutex_is_locked(&inode->i_mutex));
524 526
525 err = dbg_check_synced_i_size(inode); 527 err = dbg_check_synced_i_size(c, inode);
526 if (err) 528 if (err)
527 return err; 529 return err;
528 530
@@ -577,7 +579,7 @@ static int ubifs_unlink(struct inode *dir, struct dentry *dentry)
577 inode->i_nlink, dir->i_ino); 579 inode->i_nlink, dir->i_ino);
578 ubifs_assert(mutex_is_locked(&dir->i_mutex)); 580 ubifs_assert(mutex_is_locked(&dir->i_mutex));
579 ubifs_assert(mutex_is_locked(&inode->i_mutex)); 581 ubifs_assert(mutex_is_locked(&inode->i_mutex));
580 err = dbg_check_synced_i_size(inode); 582 err = dbg_check_synced_i_size(c, inode);
581 if (err) 583 if (err)
582 return err; 584 return err;
583 585
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 89ef9a2f7837..f9c234bf33d3 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1263,7 +1263,7 @@ int ubifs_setattr(struct dentry *dentry, struct iattr *attr)
1263 if (err) 1263 if (err)
1264 return err; 1264 return err;
1265 1265
1266 err = dbg_check_synced_i_size(inode); 1266 err = dbg_check_synced_i_size(c, inode);
1267 if (err) 1267 if (err)
1268 return err; 1268 return err;
1269 1269
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c
index 3be645e012c9..9228950a658f 100644
--- a/fs/ubifs/io.c
+++ b/fs/ubifs/io.c
@@ -86,8 +86,125 @@ void ubifs_ro_mode(struct ubifs_info *c, int err)
86 c->no_chk_data_crc = 0; 86 c->no_chk_data_crc = 0;
87 c->vfs_sb->s_flags |= MS_RDONLY; 87 c->vfs_sb->s_flags |= MS_RDONLY;
88 ubifs_warn("switched to read-only mode, error %d", err); 88 ubifs_warn("switched to read-only mode, error %d", err);
89 dump_stack();
90 }
91}
92
93/*
94 * Below are simple wrappers over UBI I/O functions which include some
95 * additional checks and UBIFS debugging stuff. See corresponding UBI function
96 * for more information.
97 */
98
99int ubifs_leb_read(const struct ubifs_info *c, int lnum, void *buf, int offs,
100 int len, int even_ebadmsg)
101{
102 int err;
103
104 err = ubi_read(c->ubi, lnum, buf, offs, len);
105 /*
106 * In case of %-EBADMSG print the error message only if the
107 * @even_ebadmsg is true.
108 */
109 if (err && (err != -EBADMSG || even_ebadmsg)) {
110 ubifs_err("reading %d bytes from LEB %d:%d failed, error %d",
111 len, lnum, offs, err);
112 dbg_dump_stack();
113 }
114 return err;
115}
116
117int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs,
118 int len, int dtype)
119{
120 int err;
121
122 ubifs_assert(!c->ro_media && !c->ro_mount);
123 if (c->ro_error)
124 return -EROFS;
125 if (!dbg_is_tst_rcvry(c))
126 err = ubi_leb_write(c->ubi, lnum, buf, offs, len, dtype);
127 else
128 err = dbg_leb_write(c, lnum, buf, offs, len, dtype);
129 if (err) {
130 ubifs_err("writing %d bytes to LEB %d:%d failed, error %d",
131 len, lnum, offs, err);
132 ubifs_ro_mode(c, err);
133 dbg_dump_stack();
134 }
135 return err;
136}
137
138int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len,
139 int dtype)
140{
141 int err;
142
143 ubifs_assert(!c->ro_media && !c->ro_mount);
144 if (c->ro_error)
145 return -EROFS;
146 if (!dbg_is_tst_rcvry(c))
147 err = ubi_leb_change(c->ubi, lnum, buf, len, dtype);
148 else
149 err = dbg_leb_change(c, lnum, buf, len, dtype);
150 if (err) {
151 ubifs_err("changing %d bytes in LEB %d failed, error %d",
152 len, lnum, err);
153 ubifs_ro_mode(c, err);
154 dbg_dump_stack();
155 }
156 return err;
157}
158
159int ubifs_leb_unmap(struct ubifs_info *c, int lnum)
160{
161 int err;
162
163 ubifs_assert(!c->ro_media && !c->ro_mount);
164 if (c->ro_error)
165 return -EROFS;
166 if (!dbg_is_tst_rcvry(c))
167 err = ubi_leb_unmap(c->ubi, lnum);
168 else
169 err = dbg_leb_unmap(c, lnum);
170 if (err) {
171 ubifs_err("unmap LEB %d failed, error %d", lnum, err);
172 ubifs_ro_mode(c, err);
173 dbg_dump_stack();
174 }
175 return err;
176}
177
178int ubifs_leb_map(struct ubifs_info *c, int lnum, int dtype)
179{
180 int err;
181
182 ubifs_assert(!c->ro_media && !c->ro_mount);
183 if (c->ro_error)
184 return -EROFS;
185 if (!dbg_is_tst_rcvry(c))
186 err = ubi_leb_map(c->ubi, lnum, dtype);
187 else
188 err = dbg_leb_map(c, lnum, dtype);
189 if (err) {
190 ubifs_err("mapping LEB %d failed, error %d", lnum, err);
191 ubifs_ro_mode(c, err);
192 dbg_dump_stack();
193 }
194 return err;
195}
196
197int ubifs_is_mapped(const struct ubifs_info *c, int lnum)
198{
199 int err;
200
201 err = ubi_is_mapped(c->ubi, lnum);
202 if (err < 0) {
203 ubifs_err("ubi_is_mapped failed for LEB %d, error %d",
204 lnum, err);
89 dbg_dump_stack(); 205 dbg_dump_stack();
90 } 206 }
207 return err;
91} 208}
92 209
93/** 210/**
@@ -406,14 +523,10 @@ int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf)
406 dirt = sync_len - wbuf->used; 523 dirt = sync_len - wbuf->used;
407 if (dirt) 524 if (dirt)
408 ubifs_pad(c, wbuf->buf + wbuf->used, dirt); 525 ubifs_pad(c, wbuf->buf + wbuf->used, dirt);
409 err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, wbuf->offs, 526 err = ubifs_leb_write(c, wbuf->lnum, wbuf->buf, wbuf->offs, sync_len,
410 sync_len, wbuf->dtype); 527 wbuf->dtype);
411 if (err) { 528 if (err)
412 ubifs_err("cannot write %d bytes to LEB %d:%d",
413 sync_len, wbuf->lnum, wbuf->offs);
414 dbg_dump_stack();
415 return err; 529 return err;
416 }
417 530
418 spin_lock(&wbuf->lock); 531 spin_lock(&wbuf->lock);
419 wbuf->offs += sync_len; 532 wbuf->offs += sync_len;
@@ -605,9 +718,9 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
605 if (aligned_len == wbuf->avail) { 718 if (aligned_len == wbuf->avail) {
606 dbg_io("flush jhead %s wbuf to LEB %d:%d", 719 dbg_io("flush jhead %s wbuf to LEB %d:%d",
607 dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs); 720 dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs);
608 err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, 721 err = ubifs_leb_write(c, wbuf->lnum, wbuf->buf,
609 wbuf->offs, wbuf->size, 722 wbuf->offs, wbuf->size,
610 wbuf->dtype); 723 wbuf->dtype);
611 if (err) 724 if (err)
612 goto out; 725 goto out;
613 726
@@ -642,8 +755,8 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
642 dbg_io("flush jhead %s wbuf to LEB %d:%d", 755 dbg_io("flush jhead %s wbuf to LEB %d:%d",
643 dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs); 756 dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs);
644 memcpy(wbuf->buf + wbuf->used, buf, wbuf->avail); 757 memcpy(wbuf->buf + wbuf->used, buf, wbuf->avail);
645 err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, wbuf->offs, 758 err = ubifs_leb_write(c, wbuf->lnum, wbuf->buf, wbuf->offs,
646 wbuf->size, wbuf->dtype); 759 wbuf->size, wbuf->dtype);
647 if (err) 760 if (err)
648 goto out; 761 goto out;
649 762
@@ -661,8 +774,8 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
661 */ 774 */
662 dbg_io("write %d bytes to LEB %d:%d", 775 dbg_io("write %d bytes to LEB %d:%d",
663 wbuf->size, wbuf->lnum, wbuf->offs); 776 wbuf->size, wbuf->lnum, wbuf->offs);
664 err = ubi_leb_write(c->ubi, wbuf->lnum, buf, wbuf->offs, 777 err = ubifs_leb_write(c, wbuf->lnum, buf, wbuf->offs,
665 wbuf->size, wbuf->dtype); 778 wbuf->size, wbuf->dtype);
666 if (err) 779 if (err)
667 goto out; 780 goto out;
668 781
@@ -683,8 +796,8 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len)
683 n <<= c->max_write_shift; 796 n <<= c->max_write_shift;
684 dbg_io("write %d bytes to LEB %d:%d", n, wbuf->lnum, 797 dbg_io("write %d bytes to LEB %d:%d", n, wbuf->lnum,
685 wbuf->offs); 798 wbuf->offs);
686 err = ubi_leb_write(c->ubi, wbuf->lnum, buf + written, 799 err = ubifs_leb_write(c, wbuf->lnum, buf + written,
687 wbuf->offs, n, wbuf->dtype); 800 wbuf->offs, n, wbuf->dtype);
688 if (err) 801 if (err)
689 goto out; 802 goto out;
690 wbuf->offs += n; 803 wbuf->offs += n;
@@ -766,13 +879,9 @@ int ubifs_write_node(struct ubifs_info *c, void *buf, int len, int lnum,
766 return -EROFS; 879 return -EROFS;
767 880
768 ubifs_prepare_node(c, buf, len, 1); 881 ubifs_prepare_node(c, buf, len, 1);
769 err = ubi_leb_write(c->ubi, lnum, buf, offs, buf_len, dtype); 882 err = ubifs_leb_write(c, lnum, buf, offs, buf_len, dtype);
770 if (err) { 883 if (err)
771 ubifs_err("cannot write %d bytes to LEB %d:%d, error %d",
772 buf_len, lnum, offs, err);
773 dbg_dump_node(c, buf); 884 dbg_dump_node(c, buf);
774 dbg_dump_stack();
775 }
776 885
777 return err; 886 return err;
778} 887}
@@ -824,13 +933,9 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len,
824 933
825 if (rlen > 0) { 934 if (rlen > 0) {
826 /* Read everything that goes before write-buffer */ 935 /* Read everything that goes before write-buffer */
827 err = ubi_read(c->ubi, lnum, buf, offs, rlen); 936 err = ubifs_leb_read(c, lnum, buf, offs, rlen, 0);
828 if (err && err != -EBADMSG) { 937 if (err && err != -EBADMSG)
829 ubifs_err("failed to read node %d from LEB %d:%d, "
830 "error %d", type, lnum, offs, err);
831 dbg_dump_stack();
832 return err; 938 return err;
833 }
834 } 939 }
835 940
836 if (type != ch->node_type) { 941 if (type != ch->node_type) {
@@ -885,12 +990,9 @@ int ubifs_read_node(const struct ubifs_info *c, void *buf, int type, int len,
885 ubifs_assert(!(offs & 7) && offs < c->leb_size); 990 ubifs_assert(!(offs & 7) && offs < c->leb_size);
886 ubifs_assert(type >= 0 && type < UBIFS_NODE_TYPES_CNT); 991 ubifs_assert(type >= 0 && type < UBIFS_NODE_TYPES_CNT);
887 992
888 err = ubi_read(c->ubi, lnum, buf, offs, len); 993 err = ubifs_leb_read(c, lnum, buf, offs, len, 0);
889 if (err && err != -EBADMSG) { 994 if (err && err != -EBADMSG)
890 ubifs_err("cannot read node %d from LEB %d:%d, error %d",
891 type, lnum, offs, err);
892 return err; 995 return err;
893 }
894 996
895 if (type != ch->node_type) { 997 if (type != ch->node_type) {
896 ubifs_err("bad node type (%d but expected %d)", 998 ubifs_err("bad node type (%d but expected %d)",
diff --git a/fs/ubifs/log.c b/fs/ubifs/log.c
index affea9494ae2..f9fd068d1ae0 100644
--- a/fs/ubifs/log.c
+++ b/fs/ubifs/log.c
@@ -262,7 +262,7 @@ int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs)
262 * an unclean reboot, because the target LEB might have been 262 * an unclean reboot, because the target LEB might have been
263 * unmapped, but not yet physically erased. 263 * unmapped, but not yet physically erased.
264 */ 264 */
265 err = ubi_leb_map(c->ubi, bud->lnum, UBI_SHORTTERM); 265 err = ubifs_leb_map(c, bud->lnum, UBI_SHORTTERM);
266 if (err) 266 if (err)
267 goto out_unlock; 267 goto out_unlock;
268 } 268 }
@@ -283,8 +283,6 @@ int ubifs_add_bud_to_log(struct ubifs_info *c, int jhead, int lnum, int offs)
283 return 0; 283 return 0;
284 284
285out_unlock: 285out_unlock:
286 if (err != -EAGAIN)
287 ubifs_ro_mode(c, err);
288 mutex_unlock(&c->log_mutex); 286 mutex_unlock(&c->log_mutex);
289 kfree(ref); 287 kfree(ref);
290 kfree(bud); 288 kfree(bud);
@@ -752,7 +750,7 @@ static int dbg_check_bud_bytes(struct ubifs_info *c)
752 struct ubifs_bud *bud; 750 struct ubifs_bud *bud;
753 long long bud_bytes = 0; 751 long long bud_bytes = 0;
754 752
755 if (!(ubifs_chk_flags & UBIFS_CHK_GEN)) 753 if (!dbg_is_chk_gen(c))
756 return 0; 754 return 0;
757 755
758 spin_lock(&c->buds_lock); 756 spin_lock(&c->buds_lock);
diff --git a/fs/ubifs/lprops.c b/fs/ubifs/lprops.c
index 667884f4a615..f8a181e647cc 100644
--- a/fs/ubifs/lprops.c
+++ b/fs/ubifs/lprops.c
@@ -504,7 +504,7 @@ static int is_lprops_dirty(struct ubifs_info *c, struct ubifs_lprops *lprops)
504 pnode = (struct ubifs_pnode *)container_of(lprops - pos, 504 pnode = (struct ubifs_pnode *)container_of(lprops - pos,
505 struct ubifs_pnode, 505 struct ubifs_pnode,
506 lprops[0]); 506 lprops[0]);
507 return !test_bit(COW_ZNODE, &pnode->flags) && 507 return !test_bit(COW_CNODE, &pnode->flags) &&
508 test_bit(DIRTY_CNODE, &pnode->flags); 508 test_bit(DIRTY_CNODE, &pnode->flags);
509} 509}
510 510
@@ -860,7 +860,7 @@ int dbg_check_cats(struct ubifs_info *c)
860 struct list_head *pos; 860 struct list_head *pos;
861 int i, cat; 861 int i, cat;
862 862
863 if (!(ubifs_chk_flags & (UBIFS_CHK_GEN | UBIFS_CHK_LPROPS))) 863 if (!dbg_is_chk_gen(c) && !dbg_is_chk_lprops(c))
864 return 0; 864 return 0;
865 865
866 list_for_each_entry(lprops, &c->empty_list, list) { 866 list_for_each_entry(lprops, &c->empty_list, list) {
@@ -958,7 +958,7 @@ void dbg_check_heap(struct ubifs_info *c, struct ubifs_lpt_heap *heap, int cat,
958{ 958{
959 int i = 0, j, err = 0; 959 int i = 0, j, err = 0;
960 960
961 if (!(ubifs_chk_flags & (UBIFS_CHK_GEN | UBIFS_CHK_LPROPS))) 961 if (!dbg_is_chk_gen(c) && !dbg_is_chk_lprops(c))
962 return; 962 return;
963 963
964 for (i = 0; i < heap->cnt; i++) { 964 for (i = 0; i < heap->cnt; i++) {
@@ -1262,7 +1262,7 @@ int dbg_check_lprops(struct ubifs_info *c)
1262 int i, err; 1262 int i, err;
1263 struct ubifs_lp_stats lst; 1263 struct ubifs_lp_stats lst;
1264 1264
1265 if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS)) 1265 if (!dbg_is_chk_lprops(c))
1266 return 0; 1266 return 0;
1267 1267
1268 /* 1268 /*
diff --git a/fs/ubifs/lpt.c b/fs/ubifs/lpt.c
index ef5155e109a2..6189c74d97f0 100644
--- a/fs/ubifs/lpt.c
+++ b/fs/ubifs/lpt.c
@@ -701,8 +701,8 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first,
701 alen = ALIGN(len, c->min_io_size); 701 alen = ALIGN(len, c->min_io_size);
702 set_ltab(c, lnum, c->leb_size - alen, alen - len); 702 set_ltab(c, lnum, c->leb_size - alen, alen - len);
703 memset(p, 0xff, alen - len); 703 memset(p, 0xff, alen - len);
704 err = ubi_leb_change(c->ubi, lnum++, buf, alen, 704 err = ubifs_leb_change(c, lnum++, buf, alen,
705 UBI_SHORTTERM); 705 UBI_SHORTTERM);
706 if (err) 706 if (err)
707 goto out; 707 goto out;
708 p = buf; 708 p = buf;
@@ -732,8 +732,8 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first,
732 set_ltab(c, lnum, c->leb_size - alen, 732 set_ltab(c, lnum, c->leb_size - alen,
733 alen - len); 733 alen - len);
734 memset(p, 0xff, alen - len); 734 memset(p, 0xff, alen - len);
735 err = ubi_leb_change(c->ubi, lnum++, buf, alen, 735 err = ubifs_leb_change(c, lnum++, buf, alen,
736 UBI_SHORTTERM); 736 UBI_SHORTTERM);
737 if (err) 737 if (err)
738 goto out; 738 goto out;
739 p = buf; 739 p = buf;
@@ -780,8 +780,8 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first,
780 alen = ALIGN(len, c->min_io_size); 780 alen = ALIGN(len, c->min_io_size);
781 set_ltab(c, lnum, c->leb_size - alen, alen - len); 781 set_ltab(c, lnum, c->leb_size - alen, alen - len);
782 memset(p, 0xff, alen - len); 782 memset(p, 0xff, alen - len);
783 err = ubi_leb_change(c->ubi, lnum++, buf, alen, 783 err = ubifs_leb_change(c, lnum++, buf, alen,
784 UBI_SHORTTERM); 784 UBI_SHORTTERM);
785 if (err) 785 if (err)
786 goto out; 786 goto out;
787 p = buf; 787 p = buf;
@@ -806,7 +806,7 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first,
806 alen = ALIGN(len, c->min_io_size); 806 alen = ALIGN(len, c->min_io_size);
807 set_ltab(c, lnum, c->leb_size - alen, alen - len); 807 set_ltab(c, lnum, c->leb_size - alen, alen - len);
808 memset(p, 0xff, alen - len); 808 memset(p, 0xff, alen - len);
809 err = ubi_leb_change(c->ubi, lnum++, buf, alen, UBI_SHORTTERM); 809 err = ubifs_leb_change(c, lnum++, buf, alen, UBI_SHORTTERM);
810 if (err) 810 if (err)
811 goto out; 811 goto out;
812 p = buf; 812 p = buf;
@@ -826,7 +826,7 @@ int ubifs_create_dflt_lpt(struct ubifs_info *c, int *main_lebs, int lpt_first,
826 826
827 /* Write remaining buffer */ 827 /* Write remaining buffer */
828 memset(p, 0xff, alen - len); 828 memset(p, 0xff, alen - len);
829 err = ubi_leb_change(c->ubi, lnum, buf, alen, UBI_SHORTTERM); 829 err = ubifs_leb_change(c, lnum, buf, alen, UBI_SHORTTERM);
830 if (err) 830 if (err)
831 goto out; 831 goto out;
832 832
@@ -1222,7 +1222,7 @@ int ubifs_read_nnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip)
1222 if (c->big_lpt) 1222 if (c->big_lpt)
1223 nnode->num = calc_nnode_num_from_parent(c, parent, iip); 1223 nnode->num = calc_nnode_num_from_parent(c, parent, iip);
1224 } else { 1224 } else {
1225 err = ubi_read(c->ubi, lnum, buf, offs, c->nnode_sz); 1225 err = ubifs_leb_read(c, lnum, buf, offs, c->nnode_sz, 1);
1226 if (err) 1226 if (err)
1227 goto out; 1227 goto out;
1228 err = ubifs_unpack_nnode(c, buf, nnode); 1228 err = ubifs_unpack_nnode(c, buf, nnode);
@@ -1247,6 +1247,7 @@ int ubifs_read_nnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip)
1247 1247
1248out: 1248out:
1249 ubifs_err("error %d reading nnode at %d:%d", err, lnum, offs); 1249 ubifs_err("error %d reading nnode at %d:%d", err, lnum, offs);
1250 dbg_dump_stack();
1250 kfree(nnode); 1251 kfree(nnode);
1251 return err; 1252 return err;
1252} 1253}
@@ -1290,7 +1291,7 @@ static int read_pnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip)
1290 lprops->flags = ubifs_categorize_lprops(c, lprops); 1291 lprops->flags = ubifs_categorize_lprops(c, lprops);
1291 } 1292 }
1292 } else { 1293 } else {
1293 err = ubi_read(c->ubi, lnum, buf, offs, c->pnode_sz); 1294 err = ubifs_leb_read(c, lnum, buf, offs, c->pnode_sz, 1);
1294 if (err) 1295 if (err)
1295 goto out; 1296 goto out;
1296 err = unpack_pnode(c, buf, pnode); 1297 err = unpack_pnode(c, buf, pnode);
@@ -1312,6 +1313,7 @@ static int read_pnode(struct ubifs_info *c, struct ubifs_nnode *parent, int iip)
1312out: 1313out:
1313 ubifs_err("error %d reading pnode at %d:%d", err, lnum, offs); 1314 ubifs_err("error %d reading pnode at %d:%d", err, lnum, offs);
1314 dbg_dump_pnode(c, pnode, parent, iip); 1315 dbg_dump_pnode(c, pnode, parent, iip);
1316 dbg_dump_stack();
1315 dbg_msg("calc num: %d", calc_pnode_num_from_parent(c, parent, iip)); 1317 dbg_msg("calc num: %d", calc_pnode_num_from_parent(c, parent, iip));
1316 kfree(pnode); 1318 kfree(pnode);
1317 return err; 1319 return err;
@@ -1331,7 +1333,7 @@ static int read_ltab(struct ubifs_info *c)
1331 buf = vmalloc(c->ltab_sz); 1333 buf = vmalloc(c->ltab_sz);
1332 if (!buf) 1334 if (!buf)
1333 return -ENOMEM; 1335 return -ENOMEM;
1334 err = ubi_read(c->ubi, c->ltab_lnum, buf, c->ltab_offs, c->ltab_sz); 1336 err = ubifs_leb_read(c, c->ltab_lnum, buf, c->ltab_offs, c->ltab_sz, 1);
1335 if (err) 1337 if (err)
1336 goto out; 1338 goto out;
1337 err = unpack_ltab(c, buf); 1339 err = unpack_ltab(c, buf);
@@ -1354,7 +1356,8 @@ static int read_lsave(struct ubifs_info *c)
1354 buf = vmalloc(c->lsave_sz); 1356 buf = vmalloc(c->lsave_sz);
1355 if (!buf) 1357 if (!buf)
1356 return -ENOMEM; 1358 return -ENOMEM;
1357 err = ubi_read(c->ubi, c->lsave_lnum, buf, c->lsave_offs, c->lsave_sz); 1359 err = ubifs_leb_read(c, c->lsave_lnum, buf, c->lsave_offs,
1360 c->lsave_sz, 1);
1358 if (err) 1361 if (err)
1359 goto out; 1362 goto out;
1360 err = unpack_lsave(c, buf); 1363 err = unpack_lsave(c, buf);
@@ -1814,8 +1817,8 @@ static struct ubifs_nnode *scan_get_nnode(struct ubifs_info *c,
1814 if (c->big_lpt) 1817 if (c->big_lpt)
1815 nnode->num = calc_nnode_num_from_parent(c, parent, iip); 1818 nnode->num = calc_nnode_num_from_parent(c, parent, iip);
1816 } else { 1819 } else {
1817 err = ubi_read(c->ubi, branch->lnum, buf, branch->offs, 1820 err = ubifs_leb_read(c, branch->lnum, buf, branch->offs,
1818 c->nnode_sz); 1821 c->nnode_sz, 1);
1819 if (err) 1822 if (err)
1820 return ERR_PTR(err); 1823 return ERR_PTR(err);
1821 err = ubifs_unpack_nnode(c, buf, nnode); 1824 err = ubifs_unpack_nnode(c, buf, nnode);
@@ -1883,8 +1886,8 @@ static struct ubifs_pnode *scan_get_pnode(struct ubifs_info *c,
1883 ubifs_assert(branch->lnum >= c->lpt_first && 1886 ubifs_assert(branch->lnum >= c->lpt_first &&
1884 branch->lnum <= c->lpt_last); 1887 branch->lnum <= c->lpt_last);
1885 ubifs_assert(branch->offs >= 0 && branch->offs < c->leb_size); 1888 ubifs_assert(branch->offs >= 0 && branch->offs < c->leb_size);
1886 err = ubi_read(c->ubi, branch->lnum, buf, branch->offs, 1889 err = ubifs_leb_read(c, branch->lnum, buf, branch->offs,
1887 c->pnode_sz); 1890 c->pnode_sz, 1);
1888 if (err) 1891 if (err)
1889 return ERR_PTR(err); 1892 return ERR_PTR(err);
1890 err = unpack_pnode(c, buf, pnode); 1893 err = unpack_pnode(c, buf, pnode);
@@ -2224,7 +2227,7 @@ int dbg_check_lpt_nodes(struct ubifs_info *c, struct ubifs_cnode *cnode,
2224 struct ubifs_cnode *cn; 2227 struct ubifs_cnode *cn;
2225 int num, iip = 0, err; 2228 int num, iip = 0, err;
2226 2229
2227 if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS)) 2230 if (!dbg_is_chk_lprops(c))
2228 return 0; 2231 return 0;
2229 2232
2230 while (cnode) { 2233 while (cnode) {
diff --git a/fs/ubifs/lpt_commit.c b/fs/ubifs/lpt_commit.c
index dfcb5748a7dc..cddd6bd214f4 100644
--- a/fs/ubifs/lpt_commit.c
+++ b/fs/ubifs/lpt_commit.c
@@ -27,6 +27,7 @@
27 27
28#include <linux/crc16.h> 28#include <linux/crc16.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/random.h>
30#include "ubifs.h" 31#include "ubifs.h"
31 32
32#ifdef CONFIG_UBIFS_FS_DEBUG 33#ifdef CONFIG_UBIFS_FS_DEBUG
@@ -116,8 +117,8 @@ static int get_cnodes_to_commit(struct ubifs_info *c)
116 return 0; 117 return 0;
117 cnt += 1; 118 cnt += 1;
118 while (1) { 119 while (1) {
119 ubifs_assert(!test_bit(COW_ZNODE, &cnode->flags)); 120 ubifs_assert(!test_bit(COW_CNODE, &cnode->flags));
120 __set_bit(COW_ZNODE, &cnode->flags); 121 __set_bit(COW_CNODE, &cnode->flags);
121 cnext = next_dirty_cnode(cnode); 122 cnext = next_dirty_cnode(cnode);
122 if (!cnext) { 123 if (!cnext) {
123 cnode->cnext = c->lpt_cnext; 124 cnode->cnext = c->lpt_cnext;
@@ -465,7 +466,7 @@ static int write_cnodes(struct ubifs_info *c)
465 */ 466 */
466 clear_bit(DIRTY_CNODE, &cnode->flags); 467 clear_bit(DIRTY_CNODE, &cnode->flags);
467 smp_mb__before_clear_bit(); 468 smp_mb__before_clear_bit();
468 clear_bit(COW_ZNODE, &cnode->flags); 469 clear_bit(COW_CNODE, &cnode->flags);
469 smp_mb__after_clear_bit(); 470 smp_mb__after_clear_bit();
470 offs += len; 471 offs += len;
471 dbg_chk_lpt_sz(c, 1, len); 472 dbg_chk_lpt_sz(c, 1, len);
@@ -1160,11 +1161,11 @@ static int lpt_gc_lnum(struct ubifs_info *c, int lnum)
1160 void *buf = c->lpt_buf; 1161 void *buf = c->lpt_buf;
1161 1162
1162 dbg_lp("LEB %d", lnum); 1163 dbg_lp("LEB %d", lnum);
1163 err = ubi_read(c->ubi, lnum, buf, 0, c->leb_size); 1164
1164 if (err) { 1165 err = ubifs_leb_read(c, lnum, buf, 0, c->leb_size, 1);
1165 ubifs_err("cannot read LEB %d, error %d", lnum, err); 1166 if (err)
1166 return err; 1167 return err;
1167 } 1168
1168 while (1) { 1169 while (1) {
1169 if (!is_a_node(c, buf, len)) { 1170 if (!is_a_node(c, buf, len)) {
1170 int pad_len; 1171 int pad_len;
@@ -1640,7 +1641,7 @@ static int dbg_check_ltab_lnum(struct ubifs_info *c, int lnum)
1640 int ret; 1641 int ret;
1641 void *buf, *p; 1642 void *buf, *p;
1642 1643
1643 if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS)) 1644 if (!dbg_is_chk_lprops(c))
1644 return 0; 1645 return 0;
1645 1646
1646 buf = p = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL); 1647 buf = p = __vmalloc(c->leb_size, GFP_NOFS, PAGE_KERNEL);
@@ -1650,11 +1651,11 @@ static int dbg_check_ltab_lnum(struct ubifs_info *c, int lnum)
1650 } 1651 }
1651 1652
1652 dbg_lp("LEB %d", lnum); 1653 dbg_lp("LEB %d", lnum);
1653 err = ubi_read(c->ubi, lnum, buf, 0, c->leb_size); 1654
1654 if (err) { 1655 err = ubifs_leb_read(c, lnum, buf, 0, c->leb_size, 1);
1655 dbg_msg("ubi_read failed, LEB %d, error %d", lnum, err); 1656 if (err)
1656 goto out; 1657 goto out;
1657 } 1658
1658 while (1) { 1659 while (1) {
1659 if (!is_a_node(c, p, len)) { 1660 if (!is_a_node(c, p, len)) {
1660 int i, pad_len; 1661 int i, pad_len;
@@ -1711,7 +1712,7 @@ int dbg_check_ltab(struct ubifs_info *c)
1711{ 1712{
1712 int lnum, err, i, cnt; 1713 int lnum, err, i, cnt;
1713 1714
1714 if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS)) 1715 if (!dbg_is_chk_lprops(c))
1715 return 0; 1716 return 0;
1716 1717
1717 /* Bring the entire tree into memory */ 1718 /* Bring the entire tree into memory */
@@ -1754,7 +1755,7 @@ int dbg_chk_lpt_free_spc(struct ubifs_info *c)
1754 long long free = 0; 1755 long long free = 0;
1755 int i; 1756 int i;
1756 1757
1757 if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS)) 1758 if (!dbg_is_chk_lprops(c))
1758 return 0; 1759 return 0;
1759 1760
1760 for (i = 0; i < c->lpt_lebs; i++) { 1761 for (i = 0; i < c->lpt_lebs; i++) {
@@ -1796,7 +1797,7 @@ int dbg_chk_lpt_sz(struct ubifs_info *c, int action, int len)
1796 long long chk_lpt_sz, lpt_sz; 1797 long long chk_lpt_sz, lpt_sz;
1797 int err = 0; 1798 int err = 0;
1798 1799
1799 if (!(ubifs_chk_flags & UBIFS_CHK_LPROPS)) 1800 if (!dbg_is_chk_lprops(c))
1800 return 0; 1801 return 0;
1801 1802
1802 switch (action) { 1803 switch (action) {
@@ -1901,11 +1902,10 @@ static void dump_lpt_leb(const struct ubifs_info *c, int lnum)
1901 return; 1902 return;
1902 } 1903 }
1903 1904
1904 err = ubi_read(c->ubi, lnum, buf, 0, c->leb_size); 1905 err = ubifs_leb_read(c, lnum, buf, 0, c->leb_size, 1);
1905 if (err) { 1906 if (err)
1906 ubifs_err("cannot read LEB %d, error %d", lnum, err);
1907 goto out; 1907 goto out;
1908 } 1908
1909 while (1) { 1909 while (1) {
1910 offs = c->leb_size - len; 1910 offs = c->leb_size - len;
1911 if (!is_a_node(c, p, len)) { 1911 if (!is_a_node(c, p, len)) {
@@ -2019,7 +2019,7 @@ static int dbg_populate_lsave(struct ubifs_info *c)
2019 struct ubifs_lpt_heap *heap; 2019 struct ubifs_lpt_heap *heap;
2020 int i; 2020 int i;
2021 2021
2022 if (!(ubifs_chk_flags & UBIFS_CHK_GEN)) 2022 if (!dbg_is_chk_gen(c))
2023 return 0; 2023 return 0;
2024 if (random32() & 3) 2024 if (random32() & 3)
2025 return 0; 2025 return 0;
diff --git a/fs/ubifs/misc.h b/fs/ubifs/misc.h
index 0b5296a9a4c5..ee7cb5ebb6e8 100644
--- a/fs/ubifs/misc.h
+++ b/fs/ubifs/misc.h
@@ -39,6 +39,29 @@ static inline int ubifs_zn_dirty(const struct ubifs_znode *znode)
39} 39}
40 40
41/** 41/**
42 * ubifs_zn_obsolete - check if znode is obsolete.
43 * @znode: znode to check
44 *
45 * This helper function returns %1 if @znode is obsolete and %0 otherwise.
46 */
47static inline int ubifs_zn_obsolete(const struct ubifs_znode *znode)
48{
49 return !!test_bit(OBSOLETE_ZNODE, &znode->flags);
50}
51
52/**
53 * ubifs_zn_cow - check if znode has to be copied on write.
54 * @znode: znode to check
55 *
56 * This helper function returns %1 if @znode is has COW flag set and %0
57 * otherwise.
58 */
59static inline int ubifs_zn_cow(const struct ubifs_znode *znode)
60{
61 return !!test_bit(COW_ZNODE, &znode->flags);
62}
63
64/**
42 * ubifs_wake_up_bgt - wake up background thread. 65 * ubifs_wake_up_bgt - wake up background thread.
43 * @c: UBIFS file-system description object 66 * @c: UBIFS file-system description object
44 */ 67 */
@@ -122,86 +145,6 @@ static inline int ubifs_wbuf_sync(struct ubifs_wbuf *wbuf)
122} 145}
123 146
124/** 147/**
125 * ubifs_leb_unmap - unmap an LEB.
126 * @c: UBIFS file-system description object
127 * @lnum: LEB number to unmap
128 *
129 * This function returns %0 on success and a negative error code on failure.
130 */
131static inline int ubifs_leb_unmap(const struct ubifs_info *c, int lnum)
132{
133 int err;
134
135 ubifs_assert(!c->ro_media && !c->ro_mount);
136 if (c->ro_error)
137 return -EROFS;
138 err = ubi_leb_unmap(c->ubi, lnum);
139 if (err) {
140 ubifs_err("unmap LEB %d failed, error %d", lnum, err);
141 return err;
142 }
143
144 return 0;
145}
146
147/**
148 * ubifs_leb_write - write to a LEB.
149 * @c: UBIFS file-system description object
150 * @lnum: LEB number to write
151 * @buf: buffer to write from
152 * @offs: offset within LEB to write to
153 * @len: length to write
154 * @dtype: data type
155 *
156 * This function returns %0 on success and a negative error code on failure.
157 */
158static inline int ubifs_leb_write(const struct ubifs_info *c, int lnum,
159 const void *buf, int offs, int len, int dtype)
160{
161 int err;
162
163 ubifs_assert(!c->ro_media && !c->ro_mount);
164 if (c->ro_error)
165 return -EROFS;
166 err = ubi_leb_write(c->ubi, lnum, buf, offs, len, dtype);
167 if (err) {
168 ubifs_err("writing %d bytes at %d:%d, error %d",
169 len, lnum, offs, err);
170 return err;
171 }
172
173 return 0;
174}
175
176/**
177 * ubifs_leb_change - atomic LEB change.
178 * @c: UBIFS file-system description object
179 * @lnum: LEB number to write
180 * @buf: buffer to write from
181 * @len: length to write
182 * @dtype: data type
183 *
184 * This function returns %0 on success and a negative error code on failure.
185 */
186static inline int ubifs_leb_change(const struct ubifs_info *c, int lnum,
187 const void *buf, int len, int dtype)
188{
189 int err;
190
191 ubifs_assert(!c->ro_media && !c->ro_mount);
192 if (c->ro_error)
193 return -EROFS;
194 err = ubi_leb_change(c->ubi, lnum, buf, len, dtype);
195 if (err) {
196 ubifs_err("changing %d bytes in LEB %d, error %d",
197 len, lnum, err);
198 return err;
199 }
200
201 return 0;
202}
203
204/**
205 * ubifs_encode_dev - encode device node IDs. 148 * ubifs_encode_dev - encode device node IDs.
206 * @dev: UBIFS device node information 149 * @dev: UBIFS device node information
207 * @rdev: device IDs to encode 150 * @rdev: device IDs to encode
diff --git a/fs/ubifs/orphan.c b/fs/ubifs/orphan.c
index a5422fffbd69..c542c73cfa3c 100644
--- a/fs/ubifs/orphan.c
+++ b/fs/ubifs/orphan.c
@@ -929,7 +929,7 @@ static int dbg_check_orphans(struct ubifs_info *c)
929 struct check_info ci; 929 struct check_info ci;
930 int err; 930 int err;
931 931
932 if (!(ubifs_chk_flags & UBIFS_CHK_ORPH)) 932 if (!dbg_is_chk_orph(c))
933 return 0; 933 return 0;
934 934
935 ci.last_ino = 0; 935 ci.last_ino = 0;
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c
index 783d8e0beb76..af02790d9328 100644
--- a/fs/ubifs/recovery.c
+++ b/fs/ubifs/recovery.c
@@ -117,7 +117,7 @@ static int get_master_node(const struct ubifs_info *c, int lnum, void **pbuf,
117 if (!sbuf) 117 if (!sbuf)
118 return -ENOMEM; 118 return -ENOMEM;
119 119
120 err = ubi_read(c->ubi, lnum, sbuf, 0, c->leb_size); 120 err = ubifs_leb_read(c, lnum, sbuf, 0, c->leb_size, 0);
121 if (err && err != -EBADMSG) 121 if (err && err != -EBADMSG)
122 goto out_free; 122 goto out_free;
123 123
@@ -213,10 +213,10 @@ static int write_rcvrd_mst_node(struct ubifs_info *c,
213 mst->flags |= cpu_to_le32(UBIFS_MST_RCVRY); 213 mst->flags |= cpu_to_le32(UBIFS_MST_RCVRY);
214 214
215 ubifs_prepare_node(c, mst, UBIFS_MST_NODE_SZ, 1); 215 ubifs_prepare_node(c, mst, UBIFS_MST_NODE_SZ, 1);
216 err = ubi_leb_change(c->ubi, lnum, mst, sz, UBI_SHORTTERM); 216 err = ubifs_leb_change(c, lnum, mst, sz, UBI_SHORTTERM);
217 if (err) 217 if (err)
218 goto out; 218 goto out;
219 err = ubi_leb_change(c->ubi, lnum + 1, mst, sz, UBI_SHORTTERM); 219 err = ubifs_leb_change(c, lnum + 1, mst, sz, UBI_SHORTTERM);
220 if (err) 220 if (err)
221 goto out; 221 goto out;
222out: 222out:
@@ -274,7 +274,8 @@ int ubifs_recover_master_node(struct ubifs_info *c)
274 if (cor1) 274 if (cor1)
275 goto out_err; 275 goto out_err;
276 mst = mst1; 276 mst = mst1;
277 } else if (offs1 == 0 && offs2 + sz >= c->leb_size) { 277 } else if (offs1 == 0 &&
278 c->leb_size - offs2 - sz < sz) {
278 /* 1st LEB was unmapped and written, 2nd not */ 279 /* 1st LEB was unmapped and written, 2nd not */
279 if (cor1) 280 if (cor1)
280 goto out_err; 281 goto out_err;
@@ -539,8 +540,8 @@ static int fix_unclean_leb(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
539 int len = ALIGN(endpt, c->min_io_size); 540 int len = ALIGN(endpt, c->min_io_size);
540 541
541 if (start) { 542 if (start) {
542 err = ubi_read(c->ubi, lnum, sleb->buf, 0, 543 err = ubifs_leb_read(c, lnum, sleb->buf, 0,
543 start); 544 start, 1);
544 if (err) 545 if (err)
545 return err; 546 return err;
546 } 547 }
@@ -554,8 +555,8 @@ static int fix_unclean_leb(struct ubifs_info *c, struct ubifs_scan_leb *sleb,
554 ubifs_pad(c, buf, pad_len); 555 ubifs_pad(c, buf, pad_len);
555 } 556 }
556 } 557 }
557 err = ubi_leb_change(c->ubi, lnum, sleb->buf, len, 558 err = ubifs_leb_change(c, lnum, sleb->buf, len,
558 UBI_UNKNOWN); 559 UBI_UNKNOWN);
559 if (err) 560 if (err)
560 return err; 561 return err;
561 } 562 }
@@ -819,7 +820,8 @@ static int get_cs_sqnum(struct ubifs_info *c, int lnum, int offs,
819 return -ENOMEM; 820 return -ENOMEM;
820 if (c->leb_size - offs < UBIFS_CS_NODE_SZ) 821 if (c->leb_size - offs < UBIFS_CS_NODE_SZ)
821 goto out_err; 822 goto out_err;
822 err = ubi_read(c->ubi, lnum, (void *)cs_node, offs, UBIFS_CS_NODE_SZ); 823 err = ubifs_leb_read(c, lnum, (void *)cs_node, offs,
824 UBIFS_CS_NODE_SZ, 0);
823 if (err && err != -EBADMSG) 825 if (err && err != -EBADMSG)
824 goto out_free; 826 goto out_free;
825 ret = ubifs_scan_a_node(c, cs_node, UBIFS_CS_NODE_SZ, lnum, offs, 0); 827 ret = ubifs_scan_a_node(c, cs_node, UBIFS_CS_NODE_SZ, lnum, offs, 0);
@@ -919,8 +921,7 @@ struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum,
919 * 921 *
920 * This function returns %0 on success and a negative error code on failure. 922 * This function returns %0 on success and a negative error code on failure.
921 */ 923 */
922static int recover_head(const struct ubifs_info *c, int lnum, int offs, 924static int recover_head(struct ubifs_info *c, int lnum, int offs, void *sbuf)
923 void *sbuf)
924{ 925{
925 int len = c->max_write_size, err; 926 int len = c->max_write_size, err;
926 927
@@ -931,15 +932,15 @@ static int recover_head(const struct ubifs_info *c, int lnum, int offs,
931 return 0; 932 return 0;
932 933
933 /* Read at the head location and check it is empty flash */ 934 /* Read at the head location and check it is empty flash */
934 err = ubi_read(c->ubi, lnum, sbuf, offs, len); 935 err = ubifs_leb_read(c, lnum, sbuf, offs, len, 1);
935 if (err || !is_empty(sbuf, len)) { 936 if (err || !is_empty(sbuf, len)) {
936 dbg_rcvry("cleaning head at %d:%d", lnum, offs); 937 dbg_rcvry("cleaning head at %d:%d", lnum, offs);
937 if (offs == 0) 938 if (offs == 0)
938 return ubifs_leb_unmap(c, lnum); 939 return ubifs_leb_unmap(c, lnum);
939 err = ubi_read(c->ubi, lnum, sbuf, 0, offs); 940 err = ubifs_leb_read(c, lnum, sbuf, 0, offs, 1);
940 if (err) 941 if (err)
941 return err; 942 return err;
942 return ubi_leb_change(c->ubi, lnum, sbuf, offs, UBI_UNKNOWN); 943 return ubifs_leb_change(c, lnum, sbuf, offs, UBI_UNKNOWN);
943 } 944 }
944 945
945 return 0; 946 return 0;
@@ -962,7 +963,7 @@ static int recover_head(const struct ubifs_info *c, int lnum, int offs,
962 * 963 *
963 * This function returns %0 on success and a negative error code on failure. 964 * This function returns %0 on success and a negative error code on failure.
964 */ 965 */
965int ubifs_recover_inl_heads(const struct ubifs_info *c, void *sbuf) 966int ubifs_recover_inl_heads(struct ubifs_info *c, void *sbuf)
966{ 967{
967 int err; 968 int err;
968 969
@@ -993,7 +994,7 @@ int ubifs_recover_inl_heads(const struct ubifs_info *c, void *sbuf)
993 * 994 *
994 * This function returns %0 on success and a negative error code on failure. 995 * This function returns %0 on success and a negative error code on failure.
995 */ 996 */
996static int clean_an_unclean_leb(const struct ubifs_info *c, 997static int clean_an_unclean_leb(struct ubifs_info *c,
997 struct ubifs_unclean_leb *ucleb, void *sbuf) 998 struct ubifs_unclean_leb *ucleb, void *sbuf)
998{ 999{
999 int err, lnum = ucleb->lnum, offs = 0, len = ucleb->endpt, quiet = 1; 1000 int err, lnum = ucleb->lnum, offs = 0, len = ucleb->endpt, quiet = 1;
@@ -1009,7 +1010,7 @@ static int clean_an_unclean_leb(const struct ubifs_info *c,
1009 return 0; 1010 return 0;
1010 } 1011 }
1011 1012
1012 err = ubi_read(c->ubi, lnum, buf, offs, len); 1013 err = ubifs_leb_read(c, lnum, buf, offs, len, 0);
1013 if (err && err != -EBADMSG) 1014 if (err && err != -EBADMSG)
1014 return err; 1015 return err;
1015 1016
@@ -1069,7 +1070,7 @@ static int clean_an_unclean_leb(const struct ubifs_info *c,
1069 } 1070 }
1070 1071
1071 /* Write back the LEB atomically */ 1072 /* Write back the LEB atomically */
1072 err = ubi_leb_change(c->ubi, lnum, sbuf, len, UBI_UNKNOWN); 1073 err = ubifs_leb_change(c, lnum, sbuf, len, UBI_UNKNOWN);
1073 if (err) 1074 if (err)
1074 return err; 1075 return err;
1075 1076
@@ -1089,7 +1090,7 @@ static int clean_an_unclean_leb(const struct ubifs_info *c,
1089 * 1090 *
1090 * This function returns %0 on success and a negative error code on failure. 1091 * This function returns %0 on success and a negative error code on failure.
1091 */ 1092 */
1092int ubifs_clean_lebs(const struct ubifs_info *c, void *sbuf) 1093int ubifs_clean_lebs(struct ubifs_info *c, void *sbuf)
1093{ 1094{
1094 dbg_rcvry("recovery"); 1095 dbg_rcvry("recovery");
1095 while (!list_empty(&c->unclean_leb_list)) { 1096 while (!list_empty(&c->unclean_leb_list)) {
@@ -1454,7 +1455,7 @@ static int fix_size_in_place(struct ubifs_info *c, struct size_entry *e)
1454 if (i_size >= e->d_size) 1455 if (i_size >= e->d_size)
1455 return 0; 1456 return 0;
1456 /* Read the LEB */ 1457 /* Read the LEB */
1457 err = ubi_read(c->ubi, lnum, c->sbuf, 0, c->leb_size); 1458 err = ubifs_leb_read(c, lnum, c->sbuf, 0, c->leb_size, 1);
1458 if (err) 1459 if (err)
1459 goto out; 1460 goto out;
1460 /* Change the size field and recalculate the CRC */ 1461 /* Change the size field and recalculate the CRC */
@@ -1470,7 +1471,7 @@ static int fix_size_in_place(struct ubifs_info *c, struct size_entry *e)
1470 len -= 1; 1471 len -= 1;
1471 len = ALIGN(len + 1, c->min_io_size); 1472 len = ALIGN(len + 1, c->min_io_size);
1472 /* Atomically write the fixed LEB back again */ 1473 /* Atomically write the fixed LEB back again */
1473 err = ubi_leb_change(c->ubi, lnum, c->sbuf, len, UBI_UNKNOWN); 1474 err = ubifs_leb_change(c, lnum, c->sbuf, len, UBI_UNKNOWN);
1474 if (err) 1475 if (err)
1475 goto out; 1476 goto out;
1476 dbg_rcvry("inode %lu at %d:%d size %lld -> %lld", 1477 dbg_rcvry("inode %lu at %d:%d size %lld -> %lld",
diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c
index 5e97161ce4d3..ccabaf1164b3 100644
--- a/fs/ubifs/replay.c
+++ b/fs/ubifs/replay.c
@@ -523,8 +523,7 @@ static int is_last_bud(struct ubifs_info *c, struct ubifs_bud *bud)
523 if (!list_is_last(&next->list, &jh->buds_list)) 523 if (!list_is_last(&next->list, &jh->buds_list))
524 return 0; 524 return 0;
525 525
526 err = ubi_read(c->ubi, next->lnum, (char *)&data, 526 err = ubifs_leb_read(c, next->lnum, (char *)&data, next->start, 4, 1);
527 next->start, 4);
528 if (err) 527 if (err)
529 return 0; 528 return 0;
530 529
diff --git a/fs/ubifs/sb.c b/fs/ubifs/sb.c
index c606f010e8df..93d938ad3d2a 100644
--- a/fs/ubifs/sb.c
+++ b/fs/ubifs/sb.c
@@ -674,15 +674,15 @@ static int fixup_leb(struct ubifs_info *c, int lnum, int len)
674 674
675 if (len == 0) { 675 if (len == 0) {
676 dbg_mnt("unmap empty LEB %d", lnum); 676 dbg_mnt("unmap empty LEB %d", lnum);
677 return ubi_leb_unmap(c->ubi, lnum); 677 return ubifs_leb_unmap(c, lnum);
678 } 678 }
679 679
680 dbg_mnt("fixup LEB %d, data len %d", lnum, len); 680 dbg_mnt("fixup LEB %d, data len %d", lnum, len);
681 err = ubi_read(c->ubi, lnum, c->sbuf, 0, len); 681 err = ubifs_leb_read(c, lnum, c->sbuf, 0, len, 1);
682 if (err) 682 if (err)
683 return err; 683 return err;
684 684
685 return ubi_leb_change(c->ubi, lnum, c->sbuf, len, UBI_UNKNOWN); 685 return ubifs_leb_change(c, lnum, c->sbuf, len, UBI_UNKNOWN);
686} 686}
687 687
688/** 688/**
diff --git a/fs/ubifs/scan.c b/fs/ubifs/scan.c
index 36216b46f772..37383e8011b1 100644
--- a/fs/ubifs/scan.c
+++ b/fs/ubifs/scan.c
@@ -148,7 +148,7 @@ struct ubifs_scan_leb *ubifs_start_scan(const struct ubifs_info *c, int lnum,
148 INIT_LIST_HEAD(&sleb->nodes); 148 INIT_LIST_HEAD(&sleb->nodes);
149 sleb->buf = sbuf; 149 sleb->buf = sbuf;
150 150
151 err = ubi_read(c->ubi, lnum, sbuf + offs, offs, c->leb_size - offs); 151 err = ubifs_leb_read(c, lnum, sbuf + offs, offs, c->leb_size - offs, 0);
152 if (err && err != -EBADMSG) { 152 if (err && err != -EBADMSG) {
153 ubifs_err("cannot read %d bytes from LEB %d:%d," 153 ubifs_err("cannot read %d bytes from LEB %d:%d,"
154 " error %d", c->leb_size - offs, lnum, offs, err); 154 " error %d", c->leb_size - offs, lnum, offs, err);
@@ -240,7 +240,7 @@ void ubifs_scanned_corruption(const struct ubifs_info *c, int lnum, int offs,
240 int len; 240 int len;
241 241
242 ubifs_err("corruption at LEB %d:%d", lnum, offs); 242 ubifs_err("corruption at LEB %d:%d", lnum, offs);
243 if (dbg_failure_mode) 243 if (dbg_is_tst_rcvry(c))
244 return; 244 return;
245 len = c->leb_size - offs; 245 len = c->leb_size - offs;
246 if (len > 8192) 246 if (len > 8192)
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 529be0582029..b28121278d46 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -85,7 +85,7 @@ static int validate_inode(struct ubifs_info *c, const struct inode *inode)
85 if (ui->data_len < 0 || ui->data_len > UBIFS_MAX_INO_DATA) 85 if (ui->data_len < 0 || ui->data_len > UBIFS_MAX_INO_DATA)
86 return 4; 86 return 4;
87 87
88 if (ui->xattr && (inode->i_mode & S_IFMT) != S_IFREG) 88 if (ui->xattr && !S_ISREG(inode->i_mode))
89 return 5; 89 return 5;
90 90
91 if (!ubifs_compr_present(ui->compr_type)) { 91 if (!ubifs_compr_present(ui->compr_type)) {
@@ -94,7 +94,7 @@ static int validate_inode(struct ubifs_info *c, const struct inode *inode)
94 ubifs_compr_name(ui->compr_type)); 94 ubifs_compr_name(ui->compr_type));
95 } 95 }
96 96
97 err = dbg_check_dir_size(c, inode); 97 err = dbg_check_dir(c, inode);
98 return err; 98 return err;
99} 99}
100 100
@@ -914,7 +914,7 @@ static int check_volume_empty(struct ubifs_info *c)
914 914
915 c->empty = 1; 915 c->empty = 1;
916 for (lnum = 0; lnum < c->leb_cnt; lnum++) { 916 for (lnum = 0; lnum < c->leb_cnt; lnum++) {
917 err = ubi_is_mapped(c->ubi, lnum); 917 err = ubifs_is_mapped(c, lnum);
918 if (unlikely(err < 0)) 918 if (unlikely(err < 0))
919 return err; 919 return err;
920 if (err == 1) { 920 if (err == 1) {
diff --git a/fs/ubifs/tnc.c b/fs/ubifs/tnc.c
index 91b4213dde84..066738647685 100644
--- a/fs/ubifs/tnc.c
+++ b/fs/ubifs/tnc.c
@@ -223,7 +223,7 @@ static struct ubifs_znode *copy_znode(struct ubifs_info *c,
223 __set_bit(DIRTY_ZNODE, &zn->flags); 223 __set_bit(DIRTY_ZNODE, &zn->flags);
224 __clear_bit(COW_ZNODE, &zn->flags); 224 __clear_bit(COW_ZNODE, &zn->flags);
225 225
226 ubifs_assert(!test_bit(OBSOLETE_ZNODE, &znode->flags)); 226 ubifs_assert(!ubifs_zn_obsolete(znode));
227 __set_bit(OBSOLETE_ZNODE, &znode->flags); 227 __set_bit(OBSOLETE_ZNODE, &znode->flags);
228 228
229 if (znode->level != 0) { 229 if (znode->level != 0) {
@@ -271,7 +271,7 @@ static struct ubifs_znode *dirty_cow_znode(struct ubifs_info *c,
271 struct ubifs_znode *zn; 271 struct ubifs_znode *zn;
272 int err; 272 int err;
273 273
274 if (!test_bit(COW_ZNODE, &znode->flags)) { 274 if (!ubifs_zn_cow(znode)) {
275 /* znode is not being committed */ 275 /* znode is not being committed */
276 if (!test_and_set_bit(DIRTY_ZNODE, &znode->flags)) { 276 if (!test_and_set_bit(DIRTY_ZNODE, &znode->flags)) {
277 atomic_long_inc(&c->dirty_zn_cnt); 277 atomic_long_inc(&c->dirty_zn_cnt);
@@ -462,7 +462,7 @@ static int try_read_node(const struct ubifs_info *c, void *buf, int type,
462 462
463 dbg_io("LEB %d:%d, %s, length %d", lnum, offs, dbg_ntype(type), len); 463 dbg_io("LEB %d:%d, %s, length %d", lnum, offs, dbg_ntype(type), len);
464 464
465 err = ubi_read(c->ubi, lnum, buf, offs, len); 465 err = ubifs_leb_read(c, lnum, buf, offs, len, 1);
466 if (err) { 466 if (err) {
467 ubifs_err("cannot read node type %d from LEB %d:%d, error %d", 467 ubifs_err("cannot read node type %d from LEB %d:%d, error %d",
468 type, lnum, offs, err); 468 type, lnum, offs, err);
@@ -1666,7 +1666,7 @@ static int read_wbuf(struct ubifs_wbuf *wbuf, void *buf, int len, int lnum,
1666 if (!overlap) { 1666 if (!overlap) {
1667 /* We may safely unlock the write-buffer and read the data */ 1667 /* We may safely unlock the write-buffer and read the data */
1668 spin_unlock(&wbuf->lock); 1668 spin_unlock(&wbuf->lock);
1669 return ubi_read(c->ubi, lnum, buf, offs, len); 1669 return ubifs_leb_read(c, lnum, buf, offs, len, 0);
1670 } 1670 }
1671 1671
1672 /* Don't read under wbuf */ 1672 /* Don't read under wbuf */
@@ -1680,7 +1680,7 @@ static int read_wbuf(struct ubifs_wbuf *wbuf, void *buf, int len, int lnum,
1680 1680
1681 if (rlen > 0) 1681 if (rlen > 0)
1682 /* Read everything that goes before write-buffer */ 1682 /* Read everything that goes before write-buffer */
1683 return ubi_read(c->ubi, lnum, buf, offs, rlen); 1683 return ubifs_leb_read(c, lnum, buf, offs, rlen, 0);
1684 1684
1685 return 0; 1685 return 0;
1686} 1686}
@@ -1767,7 +1767,7 @@ int ubifs_tnc_bulk_read(struct ubifs_info *c, struct bu_info *bu)
1767 if (wbuf) 1767 if (wbuf)
1768 err = read_wbuf(wbuf, bu->buf, len, lnum, offs); 1768 err = read_wbuf(wbuf, bu->buf, len, lnum, offs);
1769 else 1769 else
1770 err = ubi_read(c->ubi, lnum, bu->buf, offs, len); 1770 err = ubifs_leb_read(c, lnum, bu->buf, offs, len, 0);
1771 1771
1772 /* Check for a race with GC */ 1772 /* Check for a race with GC */
1773 if (maybe_leb_gced(c, lnum, bu->gc_seq)) 1773 if (maybe_leb_gced(c, lnum, bu->gc_seq))
@@ -2423,7 +2423,7 @@ static int tnc_delete(struct ubifs_info *c, struct ubifs_znode *znode, int n)
2423 */ 2423 */
2424 2424
2425 do { 2425 do {
2426 ubifs_assert(!test_bit(OBSOLETE_ZNODE, &znode->flags)); 2426 ubifs_assert(!ubifs_zn_obsolete(znode));
2427 ubifs_assert(ubifs_zn_dirty(znode)); 2427 ubifs_assert(ubifs_zn_dirty(znode));
2428 2428
2429 zp = znode->parent; 2429 zp = znode->parent;
@@ -2479,9 +2479,8 @@ static int tnc_delete(struct ubifs_info *c, struct ubifs_znode *znode, int n)
2479 c->zroot.offs = zbr->offs; 2479 c->zroot.offs = zbr->offs;
2480 c->zroot.len = zbr->len; 2480 c->zroot.len = zbr->len;
2481 c->zroot.znode = znode; 2481 c->zroot.znode = znode;
2482 ubifs_assert(!test_bit(OBSOLETE_ZNODE, 2482 ubifs_assert(!ubifs_zn_obsolete(zp));
2483 &zp->flags)); 2483 ubifs_assert(ubifs_zn_dirty(zp));
2484 ubifs_assert(test_bit(DIRTY_ZNODE, &zp->flags));
2485 atomic_long_dec(&c->dirty_zn_cnt); 2484 atomic_long_dec(&c->dirty_zn_cnt);
2486 2485
2487 if (zp->cnext) { 2486 if (zp->cnext) {
@@ -2865,7 +2864,7 @@ static void tnc_destroy_cnext(struct ubifs_info *c)
2865 struct ubifs_znode *znode = cnext; 2864 struct ubifs_znode *znode = cnext;
2866 2865
2867 cnext = cnext->cnext; 2866 cnext = cnext->cnext;
2868 if (test_bit(OBSOLETE_ZNODE, &znode->flags)) 2867 if (ubifs_zn_obsolete(znode))
2869 kfree(znode); 2868 kfree(znode);
2870 } while (cnext && cnext != c->cnext); 2869 } while (cnext && cnext != c->cnext);
2871} 2870}
@@ -3301,7 +3300,7 @@ int dbg_check_inode_size(struct ubifs_info *c, const struct inode *inode,
3301 3300
3302 if (!S_ISREG(inode->i_mode)) 3301 if (!S_ISREG(inode->i_mode))
3303 return 0; 3302 return 0;
3304 if (!(ubifs_chk_flags & UBIFS_CHK_GEN)) 3303 if (!dbg_is_chk_gen(c))
3305 return 0; 3304 return 0;
3306 3305
3307 block = (size + UBIFS_BLOCK_SIZE - 1) >> UBIFS_BLOCK_SHIFT; 3306 block = (size + UBIFS_BLOCK_SIZE - 1) >> UBIFS_BLOCK_SHIFT;
@@ -3337,9 +3336,10 @@ out_dump:
3337 ubifs_err("inode %lu has size %lld, but there are data at offset %lld " 3336 ubifs_err("inode %lu has size %lld, but there are data at offset %lld "
3338 "(data key %s)", (unsigned long)inode->i_ino, size, 3337 "(data key %s)", (unsigned long)inode->i_ino, size,
3339 ((loff_t)block) << UBIFS_BLOCK_SHIFT, DBGKEY(key)); 3338 ((loff_t)block) << UBIFS_BLOCK_SHIFT, DBGKEY(key));
3339 mutex_unlock(&c->tnc_mutex);
3340 dbg_dump_inode(c, inode); 3340 dbg_dump_inode(c, inode);
3341 dbg_dump_stack(); 3341 dbg_dump_stack();
3342 err = -EINVAL; 3342 return -EINVAL;
3343 3343
3344out_unlock: 3344out_unlock:
3345 mutex_unlock(&c->tnc_mutex); 3345 mutex_unlock(&c->tnc_mutex);
diff --git a/fs/ubifs/tnc_commit.c b/fs/ubifs/tnc_commit.c
index 41920f357bbf..4c15f07a8bb2 100644
--- a/fs/ubifs/tnc_commit.c
+++ b/fs/ubifs/tnc_commit.c
@@ -22,6 +22,7 @@
22 22
23/* This file implements TNC functions for committing */ 23/* This file implements TNC functions for committing */
24 24
25#include <linux/random.h>
25#include "ubifs.h" 26#include "ubifs.h"
26 27
27/** 28/**
@@ -87,8 +88,12 @@ static int make_idx_node(struct ubifs_info *c, struct ubifs_idx_node *idx,
87 atomic_long_dec(&c->dirty_zn_cnt); 88 atomic_long_dec(&c->dirty_zn_cnt);
88 89
89 ubifs_assert(ubifs_zn_dirty(znode)); 90 ubifs_assert(ubifs_zn_dirty(znode));
90 ubifs_assert(test_bit(COW_ZNODE, &znode->flags)); 91 ubifs_assert(ubifs_zn_cow(znode));
91 92
93 /*
94 * Note, unlike 'write_index()' we do not add memory barriers here
95 * because this function is called with @c->tnc_mutex locked.
96 */
92 __clear_bit(DIRTY_ZNODE, &znode->flags); 97 __clear_bit(DIRTY_ZNODE, &znode->flags);
93 __clear_bit(COW_ZNODE, &znode->flags); 98 __clear_bit(COW_ZNODE, &znode->flags);
94 99
@@ -377,7 +382,7 @@ static int layout_in_gaps(struct ubifs_info *c, int cnt)
377 c->gap_lebs = NULL; 382 c->gap_lebs = NULL;
378 return err; 383 return err;
379 } 384 }
380 if (dbg_force_in_the_gaps_enabled()) { 385 if (!dbg_is_chk_index(c)) {
381 /* 386 /*
382 * Do not print scary warnings if the debugging 387 * Do not print scary warnings if the debugging
383 * option which forces in-the-gaps is enabled. 388 * option which forces in-the-gaps is enabled.
@@ -491,25 +496,6 @@ static int layout_in_empty_space(struct ubifs_info *c)
491 else 496 else
492 next_len = ubifs_idx_node_sz(c, cnext->child_cnt); 497 next_len = ubifs_idx_node_sz(c, cnext->child_cnt);
493 498
494 if (c->min_io_size == 1) {
495 buf_offs += ALIGN(len, 8);
496 if (next_len) {
497 if (buf_offs + next_len <= c->leb_size)
498 continue;
499 err = ubifs_update_one_lp(c, lnum, 0,
500 c->leb_size - buf_offs, 0, 0);
501 if (err)
502 return err;
503 lnum = -1;
504 continue;
505 }
506 err = ubifs_update_one_lp(c, lnum,
507 c->leb_size - buf_offs, 0, 0, 0);
508 if (err)
509 return err;
510 break;
511 }
512
513 /* Update buffer positions */ 499 /* Update buffer positions */
514 wlen = used + len; 500 wlen = used + len;
515 used += ALIGN(len, 8); 501 used += ALIGN(len, 8);
@@ -658,7 +644,7 @@ static int get_znodes_to_commit(struct ubifs_info *c)
658 } 644 }
659 cnt += 1; 645 cnt += 1;
660 while (1) { 646 while (1) {
661 ubifs_assert(!test_bit(COW_ZNODE, &znode->flags)); 647 ubifs_assert(!ubifs_zn_cow(znode));
662 __set_bit(COW_ZNODE, &znode->flags); 648 __set_bit(COW_ZNODE, &znode->flags);
663 znode->alt = 0; 649 znode->alt = 0;
664 cnext = find_next_dirty(znode); 650 cnext = find_next_dirty(znode);
@@ -704,7 +690,7 @@ static int alloc_idx_lebs(struct ubifs_info *c, int cnt)
704 c->ilebs[c->ileb_cnt++] = lnum; 690 c->ilebs[c->ileb_cnt++] = lnum;
705 dbg_cmt("LEB %d", lnum); 691 dbg_cmt("LEB %d", lnum);
706 } 692 }
707 if (dbg_force_in_the_gaps()) 693 if (dbg_is_chk_index(c) && !(random32() & 7))
708 return -ENOSPC; 694 return -ENOSPC;
709 return 0; 695 return 0;
710} 696}
@@ -830,7 +816,7 @@ static int write_index(struct ubifs_info *c)
830 struct ubifs_idx_node *idx; 816 struct ubifs_idx_node *idx;
831 struct ubifs_znode *znode, *cnext; 817 struct ubifs_znode *znode, *cnext;
832 int i, lnum, offs, len, next_len, buf_len, buf_offs, used; 818 int i, lnum, offs, len, next_len, buf_len, buf_offs, used;
833 int avail, wlen, err, lnum_pos = 0; 819 int avail, wlen, err, lnum_pos = 0, blen, nxt_offs;
834 820
835 cnext = c->enext; 821 cnext = c->enext;
836 if (!cnext) 822 if (!cnext)
@@ -907,7 +893,7 @@ static int write_index(struct ubifs_info *c)
907 cnext = znode->cnext; 893 cnext = znode->cnext;
908 894
909 ubifs_assert(ubifs_zn_dirty(znode)); 895 ubifs_assert(ubifs_zn_dirty(znode));
910 ubifs_assert(test_bit(COW_ZNODE, &znode->flags)); 896 ubifs_assert(ubifs_zn_cow(znode));
911 897
912 /* 898 /*
913 * It is important that other threads should see %DIRTY_ZNODE 899 * It is important that other threads should see %DIRTY_ZNODE
@@ -922,6 +908,28 @@ static int write_index(struct ubifs_info *c)
922 clear_bit(COW_ZNODE, &znode->flags); 908 clear_bit(COW_ZNODE, &znode->flags);
923 smp_mb__after_clear_bit(); 909 smp_mb__after_clear_bit();
924 910
911 /*
912 * We have marked the znode as clean but have not updated the
913 * @c->clean_zn_cnt counter. If this znode becomes dirty again
914 * before 'free_obsolete_znodes()' is called, then
915 * @c->clean_zn_cnt will be decremented before it gets
916 * incremented (resulting in 2 decrements for the same znode).
917 * This means that @c->clean_zn_cnt may become negative for a
918 * while.
919 *
920 * Q: why we cannot increment @c->clean_zn_cnt?
921 * A: because we do not have the @c->tnc_mutex locked, and the
922 * following code would be racy and buggy:
923 *
924 * if (!ubifs_zn_obsolete(znode)) {
925 * atomic_long_inc(&c->clean_zn_cnt);
926 * atomic_long_inc(&ubifs_clean_zn_cnt);
927 * }
928 *
929 * Thus, we just delay the @c->clean_zn_cnt update until we
930 * have the mutex locked.
931 */
932
925 /* Do not access znode from this point on */ 933 /* Do not access znode from this point on */
926 934
927 /* Update buffer positions */ 935 /* Update buffer positions */
@@ -938,65 +946,38 @@ static int write_index(struct ubifs_info *c)
938 else 946 else
939 next_len = ubifs_idx_node_sz(c, cnext->child_cnt); 947 next_len = ubifs_idx_node_sz(c, cnext->child_cnt);
940 948
941 if (c->min_io_size == 1) { 949 nxt_offs = buf_offs + used + next_len;
942 /* 950 if (next_len && nxt_offs <= c->leb_size) {
943 * Write the prepared index node immediately if there is 951 if (avail > 0)
944 * no minimum IO size
945 */
946 err = ubifs_leb_write(c, lnum, c->cbuf, buf_offs,
947 wlen, UBI_SHORTTERM);
948 if (err)
949 return err;
950 buf_offs += ALIGN(wlen, 8);
951 if (next_len) {
952 used = 0;
953 avail = buf_len;
954 if (buf_offs + next_len > c->leb_size) {
955 err = ubifs_update_one_lp(c, lnum,
956 LPROPS_NC, 0, 0, LPROPS_TAKEN);
957 if (err)
958 return err;
959 lnum = -1;
960 }
961 continue; 952 continue;
962 } 953 else
954 blen = buf_len;
963 } else { 955 } else {
964 int blen, nxt_offs = buf_offs + used + next_len; 956 wlen = ALIGN(wlen, 8);
965 957 blen = ALIGN(wlen, c->min_io_size);
966 if (next_len && nxt_offs <= c->leb_size) { 958 ubifs_pad(c, c->cbuf + wlen, blen - wlen);
967 if (avail > 0) 959 }
968 continue; 960
969 else 961 /* The buffer is full or there are no more znodes to do */
970 blen = buf_len; 962 err = ubifs_leb_write(c, lnum, c->cbuf, buf_offs, blen,
971 } else { 963 UBI_SHORTTERM);
972 wlen = ALIGN(wlen, 8); 964 if (err)
973 blen = ALIGN(wlen, c->min_io_size); 965 return err;
974 ubifs_pad(c, c->cbuf + wlen, blen - wlen); 966 buf_offs += blen;
975 } 967 if (next_len) {
976 /* 968 if (nxt_offs > c->leb_size) {
977 * The buffer is full or there are no more znodes 969 err = ubifs_update_one_lp(c, lnum, LPROPS_NC, 0,
978 * to do 970 0, LPROPS_TAKEN);
979 */ 971 if (err)
980 err = ubifs_leb_write(c, lnum, c->cbuf, buf_offs, 972 return err;
981 blen, UBI_SHORTTERM); 973 lnum = -1;
982 if (err)
983 return err;
984 buf_offs += blen;
985 if (next_len) {
986 if (nxt_offs > c->leb_size) {
987 err = ubifs_update_one_lp(c, lnum,
988 LPROPS_NC, 0, 0, LPROPS_TAKEN);
989 if (err)
990 return err;
991 lnum = -1;
992 }
993 used -= blen;
994 if (used < 0)
995 used = 0;
996 avail = buf_len - used;
997 memmove(c->cbuf, c->cbuf + blen, used);
998 continue;
999 } 974 }
975 used -= blen;
976 if (used < 0)
977 used = 0;
978 avail = buf_len - used;
979 memmove(c->cbuf, c->cbuf + blen, used);
980 continue;
1000 } 981 }
1001 break; 982 break;
1002 } 983 }
@@ -1029,7 +1010,7 @@ static void free_obsolete_znodes(struct ubifs_info *c)
1029 do { 1010 do {
1030 znode = cnext; 1011 znode = cnext;
1031 cnext = znode->cnext; 1012 cnext = znode->cnext;
1032 if (test_bit(OBSOLETE_ZNODE, &znode->flags)) 1013 if (ubifs_zn_obsolete(znode))
1033 kfree(znode); 1014 kfree(znode);
1034 else { 1015 else {
1035 znode->cnext = NULL; 1016 znode->cnext = NULL;
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 4cd648501fa4..27f22551f805 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -230,14 +230,14 @@ enum {
230 * LPT cnode flag bits. 230 * LPT cnode flag bits.
231 * 231 *
232 * DIRTY_CNODE: cnode is dirty 232 * DIRTY_CNODE: cnode is dirty
233 * COW_CNODE: cnode is being committed and must be copied before writing
234 * OBSOLETE_CNODE: cnode is being committed and has been copied (or deleted), 233 * OBSOLETE_CNODE: cnode is being committed and has been copied (or deleted),
235 * so it can (and must) be freed when the commit is finished 234 * so it can (and must) be freed when the commit is finished
235 * COW_CNODE: cnode is being committed and must be copied before writing
236 */ 236 */
237enum { 237enum {
238 DIRTY_CNODE = 0, 238 DIRTY_CNODE = 0,
239 COW_CNODE = 1, 239 OBSOLETE_CNODE = 1,
240 OBSOLETE_CNODE = 2, 240 COW_CNODE = 2,
241}; 241};
242 242
243/* 243/*
@@ -1468,6 +1468,15 @@ extern struct ubifs_compressor *ubifs_compressors[UBIFS_COMPR_TYPES_CNT];
1468 1468
1469/* io.c */ 1469/* io.c */
1470void ubifs_ro_mode(struct ubifs_info *c, int err); 1470void ubifs_ro_mode(struct ubifs_info *c, int err);
1471int ubifs_leb_read(const struct ubifs_info *c, int lnum, void *buf, int offs,
1472 int len, int even_ebadmsg);
1473int ubifs_leb_write(struct ubifs_info *c, int lnum, const void *buf, int offs,
1474 int len, int dtype);
1475int ubifs_leb_change(struct ubifs_info *c, int lnum, const void *buf, int len,
1476 int dtype);
1477int ubifs_leb_unmap(struct ubifs_info *c, int lnum);
1478int ubifs_leb_map(struct ubifs_info *c, int lnum, int dtype);
1479int ubifs_is_mapped(const struct ubifs_info *c, int lnum);
1471int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len); 1480int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len);
1472int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs, 1481int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs,
1473 int dtype); 1482 int dtype);
@@ -1747,8 +1756,8 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum,
1747 int offs, void *sbuf, int jhead); 1756 int offs, void *sbuf, int jhead);
1748struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum, 1757struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum,
1749 int offs, void *sbuf); 1758 int offs, void *sbuf);
1750int ubifs_recover_inl_heads(const struct ubifs_info *c, void *sbuf); 1759int ubifs_recover_inl_heads(struct ubifs_info *c, void *sbuf);
1751int ubifs_clean_lebs(const struct ubifs_info *c, void *sbuf); 1760int ubifs_clean_lebs(struct ubifs_info *c, void *sbuf);
1752int ubifs_rcvry_gc_commit(struct ubifs_info *c); 1761int ubifs_rcvry_gc_commit(struct ubifs_info *c);
1753int ubifs_recover_size_accum(struct ubifs_info *c, union ubifs_key *key, 1762int ubifs_recover_size_accum(struct ubifs_info *c, union ubifs_key *key,
1754 int deletion, loff_t new_size); 1763 int deletion, loff_t new_size);