diff options
-rw-r--r-- | ubifs-utils/Makemodule.am | 3 | ||||
-rw-r--r-- | ubifs-utils/fsck.ubifs/fsck.ubifs.c | 15 | ||||
-rw-r--r-- | ubifs-utils/fsck.ubifs/fsck.ubifs.h | 5 | ||||
-rw-r--r-- | ubifs-utils/fsck.ubifs/handle_disconnected.c | 89 |
4 files changed, 110 insertions, 2 deletions
diff --git a/ubifs-utils/Makemodule.am b/ubifs-utils/Makemodule.am index b80196a..a511c40 100644 --- a/ubifs-utils/Makemodule.am +++ b/ubifs-utils/Makemodule.am @@ -86,7 +86,8 @@ fsck_ubifs_SOURCES = \ ubifs-utils/fsck.ubifs/extract_files.c \ ubifs-utils/fsck.ubifs/rebuild_fs.c \ ubifs-utils/fsck.ubifs/check_files.c \ - ubifs-utils/fsck.ubifs/check_space.c + ubifs-utils/fsck.ubifs/check_space.c \ + ubifs-utils/fsck.ubifs/handle_disconnected.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 diff --git a/ubifs-utils/fsck.ubifs/fsck.ubifs.c b/ubifs-utils/fsck.ubifs/fsck.ubifs.c index b97c8e3..550d3f9 100644 --- a/ubifs-utils/fsck.ubifs/fsck.ubifs.c +++ b/ubifs-utils/fsck.ubifs/fsck.ubifs.c @@ -526,8 +526,20 @@ static int do_fsck(void) log_out(c, "Check and create root dir"); err = check_and_create_root(c); - if (err) + if (err) { + exit_code |= FSCK_ERROR; + goto free_disconnected_files_2; + } + + if (list_empty(&FSCK(c)->disconnected_files)) + return err; + + log_out(c, "Check and create lost+found"); + err = check_and_create_lost_found(c); + if (err) { exit_code |= FSCK_ERROR; + goto free_disconnected_files_2; + } free_disconnected_files_2: destroy_file_list(c, &FSCK(c)->disconnected_files); @@ -583,6 +595,7 @@ int main(int argc, char *argv[]) * Step 13: Commit problem fixing modifications * Step 14: Check and correct the index size * Step 15: Check and create root dir + * Step 16: Check and create lost+found */ err = do_fsck(); if (err && FSCK(c)->try_rebuild) { diff --git a/ubifs-utils/fsck.ubifs/fsck.ubifs.h b/ubifs-utils/fsck.ubifs/fsck.ubifs.h index fb7ccca..0e2a081 100644 --- a/ubifs-utils/fsck.ubifs/fsck.ubifs.h +++ b/ubifs-utils/fsck.ubifs/fsck.ubifs.h @@ -277,6 +277,7 @@ struct ubifs_rebuild_info { * @lpts: lprops table * @try_rebuild: %true means that try to rebuild fs when fsck failed * @rebuild: rebuilding-related information + * @lost_and_found: inode number of the lost+found directory, %0 means invalid */ struct ubifs_fsck_info { int mode; @@ -288,6 +289,7 @@ struct ubifs_fsck_info { struct ubifs_lprops *lpts; bool try_rebuild; struct ubifs_rebuild_info *rebuild; + ino_t lost_and_found; }; #define FSCK(c) ((struct ubifs_fsck_info*)c->private) @@ -383,4 +385,7 @@ int build_lpt(struct ubifs_info *c, calculate_lp_callback calculate_lp_cb, int check_and_correct_space(struct ubifs_info *c); int check_and_correct_index_size(struct ubifs_info *c); +/* handle_disconnected.c */ +int check_and_create_lost_found(struct ubifs_info *c); + #endif diff --git a/ubifs-utils/fsck.ubifs/handle_disconnected.c b/ubifs-utils/fsck.ubifs/handle_disconnected.c new file mode 100644 index 0000000..b9a380f --- /dev/null +++ b/ubifs-utils/fsck.ubifs/handle_disconnected.c @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2024, Huawei Technologies Co, Ltd. + * + * Authors: Huang Xiaojia <huangxiaojia2@huawei.com> + * Zhihao Cheng <chengzhihao1@huawei.com> + */ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/stat.h> + +#include "linux_err.h" +#include "kmem.h" +#include "ubifs.h" +#include "defs.h" +#include "debug.h" +#include "key.h" +#include "fsck.ubifs.h" + +#define LOST_FOUND_DIR_NAME "lost+found" + +/** + * check_and_create_lost_found - Check and create the lost+found directory. + * @c: UBIFS file-system description object + * + * This function checks whether the lost+found directory exists and creates a + * new one if no valid lost+found existing. If there is a valid lost+found + * directory, inode number is stored in @FSCK(c)->lost_and_found. Returns zero + * in case of success, a negative error code in case of failure. + */ +int check_and_create_lost_found(struct ubifs_info *c) +{ + struct ubifs_inode *root_ui, *lost_found_ui; + struct fscrypt_name nm; + int err = 0; + + root_ui = ubifs_lookup_by_inum(c, UBIFS_ROOT_INO); + if (IS_ERR(root_ui)) { + err = PTR_ERR(root_ui); + /* Previous step ensures that the root dir is valid. */ + ubifs_assert(c, err != -ENOENT); + return err; + } + + if (root_ui->flags & UBIFS_CRYPT_FL) { + ubifs_msg(c, "The root dir is encrypted, skip checking lost+found"); + goto free_root; + } + + fname_name(&nm) = LOST_FOUND_DIR_NAME; + fname_len(&nm) = strlen(LOST_FOUND_DIR_NAME); + lost_found_ui = ubifs_lookup(c, root_ui, &nm); + if (IS_ERR(lost_found_ui)) { + err = PTR_ERR(lost_found_ui); + if (err != -ENOENT) + goto free_root; + + /* Not found. Create a new lost+found. */ + err = ubifs_mkdir(c, root_ui, &nm, S_IRUGO | S_IWUSR | S_IXUSR); + if (err < 0) { + if (err == -ENOSPC) { + ubifs_msg(c, "No free space to create lost+found"); + err = 0; + } + goto free_root; + } + lost_found_ui = ubifs_lookup(c, root_ui, &nm); + if (IS_ERR(lost_found_ui)) { + err = PTR_ERR(lost_found_ui); + ubifs_assert(c, err != -ENOENT); + goto free_root; + } + FSCK(c)->lost_and_found = lost_found_ui->vfs_inode.inum; + ubifs_msg(c, "Create the lost+found"); + } else if (!(lost_found_ui->flags & UBIFS_CRYPT_FL) && + S_ISDIR(lost_found_ui->vfs_inode.mode)) { + FSCK(c)->lost_and_found = lost_found_ui->vfs_inode.inum; + } else { + ubifs_msg(c, "The type of lost+found is %s%s", + ubifs_get_type_name(ubifs_get_dent_type(lost_found_ui->vfs_inode.mode)), + lost_found_ui->flags & UBIFS_CRYPT_FL ? ", encrypted" : ""); + } + + kfree(lost_found_ui); +free_root: + kfree(root_ui); + return err; +} |