aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorhujianyang <hujianyang@huawei.com>2015-02-09 22:28:57 -0500
committerArtem Bityutskiy <artem.bityutskiy@linux.intel.com>2015-02-10 03:06:24 -0500
commit88cff0f0fbcf64cb6c2fbad6cf57e2725475d0ee (patch)
tree3482098bdcb7af25bd970cd329ddf99255257354 /fs
parent832b52a15085d04039b01cec56845d3972c2f301 (diff)
UBIFS: return -EINVAL if log head is empty
CS node is recognized as a sign in UBIFS log replay mechanism. Log relaying during mount should find the CS node in log head at beginning and then replay the following uncommitted buds. Here is a bug in log replay path: If the log head, which is indicated by @log_lnum in mst_node, is empty, current UBIFS replay nothing and directly mount the partition without any warning. This action will put filesystem in an abnormal state, e.g. space management in LPT area is incorrect to the real space usage in main area. We reproduced this bug by fault injection: turn log head leb into all 0xFF. UBIFS driver mount the polluted partition normally. But errors occur while running fs_stress on this mount: [89068.055183] UBI error: ubi_io_read: error -74 (ECC error) while reading 59 bytes from PEB 711:33088, read 59 bytes [89068.179877] UBIFS error (pid 10517): ubifs_check_node: bad magic 0x101031, expected 0x6101831 [89068.179882] UBIFS error (pid 10517): ubifs_check_node: bad node at LEB 591:28992 [89068.179891] Not a node, first 24 bytes: [89068.179892] 00000000: 31 10 10 00 37 84 64 04 10 04 00 00 00 00 00 00 20 00 00 00 02 01 00 00 1...7.d......... ....... [89068.180282] UBIFS error (pid 10517): ubifs_read_node: expected node type 2 This patch fix the problem by checking *lnum* to guarantee the empty leb is not log head leb and return an error if the log head leb is incorrectly empty. After this, we could catch *log head empty* error in place. Signed-off-by: hujianyang <hujianyang@huawei.com> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/ubifs/replay.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c
index 3187925e9879..9b40a1c5e160 100644
--- a/fs/ubifs/replay.c
+++ b/fs/ubifs/replay.c
@@ -1028,9 +1028,22 @@ int ubifs_replay_journal(struct ubifs_info *c)
1028 1028
1029 do { 1029 do {
1030 err = replay_log_leb(c, lnum, 0, c->sbuf); 1030 err = replay_log_leb(c, lnum, 0, c->sbuf);
1031 if (err == 1) 1031 if (err == 1) {
1032 /* We hit the end of the log */ 1032 if (lnum != c->lhead_lnum)
1033 break; 1033 /* We hit the end of the log */
1034 break;
1035
1036 /*
1037 * The head of the log must always start with the
1038 * "commit start" node on a properly formatted UBIFS.
1039 * But we found no nodes at all, which means that
1040 * someting went wrong and we cannot proceed mounting
1041 * the file-system.
1042 */
1043 ubifs_err("no UBIFS nodes found at the log head LEB %d:%d, possibly corrupted",
1044 lnum, 0);
1045 err = -EINVAL;
1046 }
1034 if (err) 1047 if (err)
1035 goto out; 1048 goto out;
1036 lnum = ubifs_next_log_lnum(c, lnum); 1049 lnum = ubifs_next_log_lnum(c, lnum);