aboutsummaryrefslogtreecommitdiff
path: root/ubifs-utils/fsck.ubifs/check_files.c
diff options
context:
space:
mode:
authorZhihao Cheng <chengzhihao1@huawei.com>2024-11-11 17:08:05 +0800
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2024-11-11 10:32:46 +0100
commita251dd9c71006c66a02064210ae103ed7ac59444 (patch)
tree6417b927c425c7c1e8bd8573a5a9e506036f1cd5 /ubifs-utils/fsck.ubifs/check_files.c
parentc5ca3893ea854e8d8b5916bc492db8523db70122 (diff)
fsck.ubifs: Check and handle unreachable files
This is the 9/18 step of fsck. Check and handle unreachable files, the checking rule is same as rebuild mode which has been implemented in file_is_reachable, but the methods of handling are different: 1. Move unreachable regular file into disconnected list, let subsequent steps to handle them with lost+found. 2. Delete unreachable non-regular file. 3. Delete unreachable directory entries. Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com> Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'ubifs-utils/fsck.ubifs/check_files.c')
-rw-r--r--ubifs-utils/fsck.ubifs/check_files.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/ubifs-utils/fsck.ubifs/check_files.c b/ubifs-utils/fsck.ubifs/check_files.c
index c5c606e..2be9619 100644
--- a/ubifs-utils/fsck.ubifs/check_files.c
+++ b/ubifs-utils/fsck.ubifs/check_files.c
@@ -7,6 +7,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <sys/stat.h>
#include "linux_err.h"
#include "bitops.h"
@@ -442,3 +443,59 @@ int handle_invalid_files(struct ubifs_info *c)
return 0;
}
+
+/**
+ * handle_dentry_tree - Handle unreachable dentries and files.
+ * @c: UBIFS file-system description object
+ *
+ * This function iterates all directory entries and remove those unreachable
+ * ones. If file has no directory entries, it becomes unreachable:
+ * 1. If the unreachable file has non-regular type, delete it;
+ * 2. If the unreachable file has regular type, move it into the
+ * @FSCK(c)->disconnected_files.
+ * 'Unreachable' means that a directory entry can not be searched from '/'.
+ *
+ * Returns zero in case of success, a negative error code in case of failure.
+ */
+int handle_dentry_tree(struct ubifs_info *c)
+{
+ struct rb_node *node;
+ struct scanned_file *file;
+ struct rb_root *tree = &FSCK(c)->scanned_files;
+ LIST_HEAD(unreachable);
+
+ for (node = rb_first(tree); node; node = rb_next(node)) {
+ file = rb_entry(node, struct scanned_file, rb);
+
+ /*
+ * Since all xattr files are already attached to corresponding
+ * host file, there are only non-xattr files in the file tree.
+ */
+ ubifs_assert(c, !file->ino.is_xattr);
+ if (!file_is_reachable(c, file, tree))
+ list_add(&file->list, &unreachable);
+ }
+
+ while (!list_empty(&unreachable)) {
+ file = list_entry(unreachable.next, struct scanned_file, list);
+
+ list_del(&file->list);
+ if (S_ISREG(file->ino.mode)) {
+ /*
+ * Move regular type unreachable file into the
+ * @FSCK(c)->disconnected_files.
+ */
+ list_add(&file->list, &FSCK(c)->disconnected_files);
+ rb_erase(&file->rb, tree);
+ } else {
+ /* Delete non-regular type unreachable file. */
+ int err = delete_file(c, file);
+ if (err)
+ return err;
+ rb_erase(&file->rb, tree);
+ kfree(file);
+ }
+ }
+
+ return 0;
+}