aboutsummaryrefslogtreecommitdiff
path: root/ubifs-utils/fsck.ubifs
diff options
context:
space:
mode:
authorZhihao Cheng <chengzhihao1@huawei.com>2024-11-11 17:01:05 +0800
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2024-11-11 10:32:45 +0100
commitfabde6440cac726bcd6cec36bbc9946b67be45da (patch)
tree14650b80e7bb5bb8e14e3d23c2ed886d9b15687c /ubifs-utils/fsck.ubifs
parent518e5374471233125a595c5aeff2d0c3f5d27c0b (diff)
fsck.ubifs: Load filesystem information from UBI volume
Load filesystem information from UBI volume (Similar to UBIFS mounting process), initialize kinds of buffers and read superblock. This is the base step for both fsck and rebuild_fs. Subsequent pacthes will complete this step by adding more steps(eg. read master, replay journal, etc.) which are only used in fsck. Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com> Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'ubifs-utils/fsck.ubifs')
-rw-r--r--ubifs-utils/fsck.ubifs/fsck.ubifs.c7
-rw-r--r--ubifs-utils/fsck.ubifs/fsck.ubifs.h7
-rw-r--r--ubifs-utils/fsck.ubifs/load_fs.c127
-rw-r--r--ubifs-utils/fsck.ubifs/problem.c4
4 files changed, 144 insertions, 1 deletions
diff --git a/ubifs-utils/fsck.ubifs/fsck.ubifs.c b/ubifs-utils/fsck.ubifs/fsck.ubifs.c
index a367241..ef94fcf 100644
--- a/ubifs-utils/fsck.ubifs/fsck.ubifs.c
+++ b/ubifs-utils/fsck.ubifs/fsck.ubifs.c
@@ -423,8 +423,15 @@ int main(int argc, char *argv[])
goto out_destroy_fsck;
}
+ /* Init: Read superblock */
+ err = ubifs_load_filesystem(c);
+ if (err)
+ goto out_close;
+
err = do_fsck();
+ ubifs_destroy_filesystem(c);
+out_close:
ubifs_close_volume(c);
out_destroy_fsck:
destroy_fsck_info(c);
diff --git a/ubifs-utils/fsck.ubifs/fsck.ubifs.h b/ubifs-utils/fsck.ubifs/fsck.ubifs.h
index 762745f..c21082e 100644
--- a/ubifs-utils/fsck.ubifs/fsck.ubifs.h
+++ b/ubifs-utils/fsck.ubifs/fsck.ubifs.h
@@ -36,6 +36,9 @@
enum { NORMAL_MODE = 0, SAFE_MODE, DANGER_MODE0,
DANGER_MODE1, REBUILD_MODE, CHECK_MODE };
+/* Types of inconsistent problems */
+enum { SB_CORRUPTED = 0 };
+
/**
* struct ubifs_fsck_info - UBIFS fsck information.
* @mode: working mode
@@ -95,4 +98,8 @@ extern int exit_code;
/* problem.c */
bool fix_problem(const struct ubifs_info *c, int problem_type);
+/* load_fs.c */
+int ubifs_load_filesystem(struct ubifs_info *c);
+void ubifs_destroy_filesystem(struct ubifs_info *c);
+
#endif
diff --git a/ubifs-utils/fsck.ubifs/load_fs.c b/ubifs-utils/fsck.ubifs/load_fs.c
new file mode 100644
index 0000000..4a06b4c
--- /dev/null
+++ b/ubifs-utils/fsck.ubifs/load_fs.c
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2024, Huawei Technologies Co, Ltd.
+ *
+ * Authors: Zhihao Cheng <chengzhihao1@huawei.com>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "bitops.h"
+#include "kmem.h"
+#include "ubifs.h"
+#include "defs.h"
+#include "debug.h"
+#include "key.h"
+#include "misc.h"
+#include "fsck.ubifs.h"
+
+int ubifs_load_filesystem(struct ubifs_info *c)
+{
+ int err;
+ size_t sz;
+
+ err = init_constants_early(c);
+ if (err) {
+ exit_code |= FSCK_ERROR;
+ return err;
+ }
+
+ err = check_volume_empty(c);
+ if (err <= 0) {
+ exit_code |= FSCK_ERROR;
+ log_err(c, 0, "%s UBI volume!", err < 0 ? "bad" : "empty");
+ return -EINVAL;
+ }
+
+ if (c->ro_media && !c->ro_mount) {
+ exit_code |= FSCK_ERROR;
+ log_err(c, 0, "cannot read-write on read-only media");
+ return -EROFS;
+ }
+
+ err = -ENOMEM;
+ c->bottom_up_buf = kmalloc_array(BOTTOM_UP_HEIGHT, sizeof(int),
+ GFP_KERNEL);
+ if (!c->bottom_up_buf) {
+ exit_code |= FSCK_ERROR;
+ log_err(c, errno, "cannot allocate bottom_up_buf");
+ goto out_free;
+ }
+
+ c->sbuf = vmalloc(c->leb_size);
+ if (!c->sbuf) {
+ exit_code |= FSCK_ERROR;
+ log_err(c, errno, "cannot allocate sbuf");
+ goto out_free;
+ }
+
+ if (!c->ro_mount) {
+ c->ileb_buf = vmalloc(c->leb_size);
+ if (!c->ileb_buf) {
+ exit_code |= FSCK_ERROR;
+ log_err(c, errno, "cannot allocate ileb_buf");
+ goto out_free;
+ }
+ }
+
+ c->mounting = 1;
+
+ log_out(c, "Read superblock");
+ err = ubifs_read_superblock(c);
+ if (err) {
+ if (test_and_clear_failure_reason_callback(c, FR_DATA_CORRUPTED))
+ fix_problem(c, SB_CORRUPTED);
+ exit_code |= FSCK_ERROR;
+ goto out_mounting;
+ }
+
+ err = init_constants_sb(c);
+ if (err) {
+ exit_code |= FSCK_ERROR;
+ goto out_mounting;
+ }
+
+ sz = ALIGN(c->max_idx_node_sz, c->min_io_size) * 2;
+ c->cbuf = kmalloc(sz, GFP_NOFS);
+ if (!c->cbuf) {
+ err = -ENOMEM;
+ exit_code |= FSCK_ERROR;
+ log_err(c, errno, "cannot allocate cbuf");
+ goto out_mounting;
+ }
+
+ err = alloc_wbufs(c);
+ if (err) {
+ exit_code |= FSCK_ERROR;
+ log_err(c, 0, "cannot allocate wbuf");
+ goto out_mounting;
+ }
+
+ c->mounting = 0;
+
+ return 0;
+
+out_mounting:
+ c->mounting = 0;
+out_free:
+ kfree(c->cbuf);
+ kfree(c->ileb_buf);
+ kfree(c->sbuf);
+ kfree(c->bottom_up_buf);
+ kfree(c->sup_node);
+
+ return err;
+}
+
+void ubifs_destroy_filesystem(struct ubifs_info *c)
+{
+ free_wbufs(c);
+
+ kfree(c->cbuf);
+ kfree(c->ileb_buf);
+ kfree(c->sbuf);
+ kfree(c->bottom_up_buf);
+ kfree(c->sup_node);
+}
diff --git a/ubifs-utils/fsck.ubifs/problem.c b/ubifs-utils/fsck.ubifs/problem.c
index 9a8c2e0..acb9e45 100644
--- a/ubifs-utils/fsck.ubifs/problem.c
+++ b/ubifs-utils/fsck.ubifs/problem.c
@@ -34,7 +34,9 @@ struct fsck_problem {
const char *desc;
};
-static const struct fsck_problem problem_table[] = {};
+static const struct fsck_problem problem_table[] = {
+ {0, "Corrupted superblock"}, // SB_CORRUPTED
+};
static void print_problem(const struct ubifs_info *c,
const struct fsck_problem *problem)