aboutsummaryrefslogtreecommitdiff
path: root/ubifs-utils/fsck.ubifs
diff options
context:
space:
mode:
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)