]> www.infradead.org Git - mtd-utils.git/commitdiff
fsck.ubifs: Check and create the lost+found
authorHuang Xiaojia <huangxiaojia2@huawei.com>
Mon, 11 Nov 2024 09:08:14 +0000 (17:08 +0800)
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>
Mon, 11 Nov 2024 09:32:46 +0000 (10:32 +0100)
This is the 16/18 step of fsck. Check whether the lost+found is existed,
create a new one if it is not found. This step makes sure that disconnected
file can be recovered under the lost+found.

Signed-off-by: Huang Xiaojia <huangxiaojia2@huawei.com>
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/handle_disconnected.c [new file with mode: 0644]

index b80196a30dcbefe0d771900d96cea61b8f76dea8..a511c40d9e17e6fa87c3121f904aa31e458460fe 100644 (file)
@@ -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
index b97c8e3bc15520fe6f1b34f5a8d7915537344f23..550d3f98e764941cdbdd34696c19b26a5d667794 100644 (file)
@@ -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) {
index fb7ccca01f5d2243befd29ceba6bcf482f2278eb..0e2a0811a8e1cd6314fe227e9e6702ed7df4c6e0 100644 (file)
@@ -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 (file)
index 0000000..b9a380f
--- /dev/null
@@ -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;
+}