diff options
author | Zhihao Cheng <chengzhihao1@huawei.com> | 2024-11-11 17:08:05 +0800 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2024-11-11 10:32:46 +0100 |
commit | a251dd9c71006c66a02064210ae103ed7ac59444 (patch) | |
tree | 6417b927c425c7c1e8bd8573a5a9e506036f1cd5 /ubifs-utils/fsck.ubifs/check_files.c | |
parent | c5ca3893ea854e8d8b5916bc492db8523db70122 (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.c | 57 |
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; +} |