summaryrefslogtreecommitdiff
path: root/ubifs-utils/libubifs/lpt_commit.c
diff options
context:
space:
mode:
authorZhihao Cheng <chengzhihao1@huawei.com>2024-11-11 17:08:09 +0800
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2024-11-11 10:32:46 +0100
commit83b7477eae174e974237685f83f0fec4fb794892 (patch)
treecb5e6c3b0e9de5178124fb761e44466b092a55e2 /ubifs-utils/libubifs/lpt_commit.c
parent47c1cfd5e8ec289597f7342f88e103811511f0a8 (diff)
fsck.ubifs: check and correct the space statistics
This is the 12/18 step of fsck. Check and correct the space statistics. There could be following steps and possible errors: Step 1. Exit for check mode, if %FR_LPT_CORRUPTED or %FR_LPT_INCORRECT is set in lpt status, the exit code should have %FSCK_UNCORRECTED. Step 2. Check lpt status, if %FR_LPT_CORRUPTED is set in lpt status, normal mode with 'no' answer will exit, other modes will rebuild lpt. Step 3. Traverse LPT nodes, check the correctness of nnode and pnode, compare LEB scanning result with LEB properties. a. LPT node is corrupted, normal mode with 'no' answer will exit, rebuild lpt for other modes. b. Incorrect nnode/pnode, normal mode with 'no' answer will exit, other other modes will correct the nnode/pnode. c. Inconsistent comparing result, normal mode with 'no' answer will exit, other modes will correct the space statistics. Step 4. Check and correct the lprops table information. Step 5. Set gc lnum(ubifs_rcvry_gc_commit / take_gc_lnum). Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com> Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'ubifs-utils/libubifs/lpt_commit.c')
-rw-r--r--ubifs-utils/libubifs/lpt_commit.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/ubifs-utils/libubifs/lpt_commit.c b/ubifs-utils/libubifs/lpt_commit.c
index 8a44546..ee84f80 100644
--- a/ubifs-utils/libubifs/lpt_commit.c
+++ b/ubifs-utils/libubifs/lpt_commit.c
@@ -1599,7 +1599,7 @@ static int dbg_is_node_dirty(struct ubifs_info *c, int node_type, int lnum,
*
* This function returns %0 on success and a negative error code on failure.
*/
-static int dbg_check_ltab_lnum(struct ubifs_info *c, int lnum)
+int dbg_check_ltab_lnum(struct ubifs_info *c, int lnum)
{
int err, len = c->leb_size, dirty = 0, node_type, node_num, node_len;
int ret;
@@ -1608,7 +1608,7 @@ static int dbg_check_ltab_lnum(struct ubifs_info *c, int lnum)
buf = p = __vmalloc(c->leb_size, GFP_NOFS);
if (!buf) {
ubifs_err(c, "cannot allocate memory for ltab checking");
- return 0;
+ return -ENOMEM;
}
dbg_lp("LEB %d", lnum);
@@ -1632,20 +1632,30 @@ static int dbg_check_ltab_lnum(struct ubifs_info *c, int lnum)
continue;
}
if (!dbg_is_all_ff(p, len)) {
+ set_failure_reason_callback(c, FR_LPT_CORRUPTED);
ubifs_err(c, "invalid empty space in LEB %d at %d",
lnum, c->leb_size - len);
err = -EINVAL;
+ goto out;
}
i = lnum - c->lpt_first;
if (len != c->ltab[i].free) {
ubifs_err(c, "invalid free space in LEB %d (free %d, expected %d)",
- lnum, len, c->ltab[i].free);
+ lnum, c->ltab[i].free, len);
err = -EINVAL;
+ if (handle_failure_callback(c, FR_H_LTAB_INCORRECT, NULL)) {
+ c->ltab[i].free = len;
+ err = 0;
+ }
}
if (dirty != c->ltab[i].dirty) {
ubifs_err(c, "invalid dirty space in LEB %d (dirty %d, expected %d)",
- lnum, dirty, c->ltab[i].dirty);
+ lnum, c->ltab[i].dirty, dirty);
err = -EINVAL;
+ if (handle_failure_callback(c, FR_H_LTAB_INCORRECT, NULL)) {
+ c->ltab[i].dirty = dirty;
+ err = 0;
+ }
}
goto out;
}