]> www.infradead.org Git - mtd-utils.git/commitdiff
fsck.ubifs: Load filesystem information from UBI volume
authorZhihao Cheng <chengzhihao1@huawei.com>
Mon, 11 Nov 2024 09:01:05 +0000 (17:01 +0800)
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>
Mon, 11 Nov 2024 09:32:45 +0000 (10:32 +0100)
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>
ubifs-utils/Makemodule.am
ubifs-utils/fsck.ubifs/fsck.ubifs.c
ubifs-utils/fsck.ubifs/fsck.ubifs.h
ubifs-utils/fsck.ubifs/load_fs.c [new file with mode: 0644]
ubifs-utils/fsck.ubifs/problem.c

index 590f17b69d6b7863c67b67a0854e4eafe497864a..baba185366cffa75074af755f5918c9a53da400e 100644 (file)
@@ -81,7 +81,8 @@ fsck_ubifs_SOURCES = \
        $(libubifs_SOURCES) \
        ubifs-utils/fsck.ubifs/fsck.ubifs.h \
        ubifs-utils/fsck.ubifs/fsck.ubifs.c \
-       ubifs-utils/fsck.ubifs/problem.c
+       ubifs-utils/fsck.ubifs/problem.c \
+       ubifs-utils/fsck.ubifs/load_fs.c
 
 fsck_ubifs_LDADD = libmtd.a libubi.a $(ZLIB_LIBS) $(LZO_LIBS) $(ZSTD_LIBS) $(UUID_LIBS) $(LIBSELINUX_LIBS) $(OPENSSL_LIBS) \
                   $(DUMP_STACK_LD) -lm -lpthread
index a3672411193f08c55b6e4a0a8b2c01251d8a7abf..ef94fcfb159c6954a160b0b5f737d23ba9c5b4e3 100644 (file)
@@ -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);
index 762745f982cc90cf7a84fb572775286f47fe5cb0..c21082e0e21a94b61625631642acabb5fb0a17b2 100644 (file)
@@ -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 (file)
index 0000000..4a06b4c
--- /dev/null
@@ -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);
+}
index 9a8c2e062d07b674da928032fc8d184c979425d8..acb9e45ecd118bb4f41fa1b7cc71a735409dea9c 100644 (file)
@@ -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)