diff options
Diffstat (limited to 'ubifs-utils/fsck.ubifs')
-rw-r--r-- | ubifs-utils/fsck.ubifs/fsck.ubifs.c | 7 | ||||
-rw-r--r-- | ubifs-utils/fsck.ubifs/fsck.ubifs.h | 7 | ||||
-rw-r--r-- | ubifs-utils/fsck.ubifs/load_fs.c | 127 | ||||
-rw-r--r-- | ubifs-utils/fsck.ubifs/problem.c | 4 |
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) |