aboutsummaryrefslogtreecommitdiff
path: root/ubifs-utils/fsck.ubifs/extract_files.c
diff options
context:
space:
mode:
authorXiang Yang <xiangyang3@huawei.com>2024-11-11 17:08:06 +0800
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2024-11-11 10:32:46 +0100
commitd0b66b0e5bb346e795a4c0ac3cafd287a6e4db9d (patch)
treea266718d7a77f1995d4d5a2ee53cbe843cd1dd6d /ubifs-utils/fsck.ubifs/extract_files.c
parenta251dd9c71006c66a02064210ae103ed7ac59444 (diff)
fsck.ubifs: Check and correct files' information
This is the 10/18 step of fsck. Check and handle inconsistent files, the checking rule is same as rebuild mode which has been implemented in check_and_correct_files, but the methods of handling are different: 1. Correct the file information for safe mode, danger mode and normal mode with 'yes' answer, other modes will exit. Signed-off-by: Xiang Yang <xiangyang3@huawei.com> 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/extract_files.c')
-rw-r--r--ubifs-utils/fsck.ubifs/extract_files.c76
1 files changed, 49 insertions, 27 deletions
diff --git a/ubifs-utils/fsck.ubifs/extract_files.c b/ubifs-utils/fsck.ubifs/extract_files.c
index b24445b..c83d377 100644
--- a/ubifs-utils/fsck.ubifs/extract_files.c
+++ b/ubifs-utils/fsck.ubifs/extract_files.c
@@ -1292,8 +1292,8 @@ reachable:
* data nodes and truncation node. The calculated informaion will be used
* to correct inode node.
*/
-static void calculate_file_info(struct ubifs_info *c, struct scanned_file *file,
- struct rb_root *file_tree)
+static int calculate_file_info(struct ubifs_info *c, struct scanned_file *file,
+ struct rb_root *file_tree)
{
int nlink = 0;
bool corrupted_truncation = false;
@@ -1306,15 +1306,24 @@ static void calculate_file_info(struct ubifs_info *c, struct scanned_file *file,
for (node = rb_first(&file->xattr_files); node; node = rb_next(node)) {
xattr_file = rb_entry(node, struct scanned_file, rb);
+ dent_node = rb_entry(rb_first(&xattr_file->dent_nodes),
+ struct scanned_dent_node, rb);
+ ubifs_assert(c, xattr_file->ino.is_xattr);
ubifs_assert(c, !rb_first(&xattr_file->xattr_files));
- calculate_file_info(c, xattr_file, file_tree);
+ xattr_file->calc_nlink = 1;
+ xattr_file->calc_size = xattr_file->ino.size;
+
+ file->calc_xcnt += 1;
+ file->calc_xsz += CALC_DENT_SIZE(dent_node->nlen);
+ file->calc_xsz += CALC_XATTR_BYTES(xattr_file->ino.size);
+ file->calc_xnms += dent_node->nlen;
}
if (file->inum == UBIFS_ROOT_INO) {
file->calc_nlink += 2;
file->calc_size += UBIFS_INO_NODE_SZ;
- return;
+ return 0;
}
if (S_ISDIR(file->ino.mode)) {
@@ -1326,29 +1335,11 @@ static void calculate_file_info(struct ubifs_info *c, struct scanned_file *file,
parent_file = lookup_file(file_tree, key_inum(c, &dent_node->key));
if (!parent_file) {
ubifs_assert(c, 0);
- return;
+ return 0;
}
parent_file->calc_nlink += 1;
parent_file->calc_size += CALC_DENT_SIZE(dent_node->nlen);
- return;
- }
-
- if (file->ino.is_xattr) {
- file->calc_nlink = 1;
- file->calc_size = file->ino.size;
-
- dent_node = rb_entry(rb_first(&file->dent_nodes),
- struct scanned_dent_node, rb);
- parent_file = lookup_file(file_tree, key_inum(c, &dent_node->key));
- if (!parent_file) {
- ubifs_assert(c, 0);
- return;
- }
- parent_file->calc_xcnt += 1;
- parent_file->calc_xsz += CALC_DENT_SIZE(dent_node->nlen);
- parent_file->calc_xsz += CALC_XATTR_BYTES(file->ino.size);
- parent_file->calc_xnms += dent_node->nlen;
- return;
+ return 0;
}
for (node = rb_first(&file->dent_nodes); node; node = rb_next(node)) {
@@ -1359,7 +1350,7 @@ static void calculate_file_info(struct ubifs_info *c, struct scanned_file *file,
parent_file = lookup_file(file_tree, key_inum(c, &dent_node->key));
if (!parent_file) {
ubifs_assert(c, 0);
- return;
+ return 0;
}
parent_file->calc_size += CALC_DENT_SIZE(dent_node->nlen);
}
@@ -1368,7 +1359,7 @@ static void calculate_file_info(struct ubifs_info *c, struct scanned_file *file,
if (!S_ISREG(file->ino.mode)) {
/* No need to verify i_size for symlink/sock/block/char/fifo. */
file->calc_size = file->ino.size;
- return;
+ return 0;
}
/*
@@ -1452,10 +1443,22 @@ drop_data:
data_node = list_entry(drop_list.next, struct scanned_data_node,
list);
+ if (FSCK(c)->mode != REBUILD_MODE) {
+ /*
+ * Don't ask, inconsistent file correcting will be
+ * asked in function correct_file_info().
+ */
+ int err = delete_node(c, &data_node->key,
+ data_node->header.lnum, data_node->header.offs);
+ if (err)
+ return err;
+ }
list_del(&data_node->list);
rb_erase(&data_node->rb, &file->data_nodes);
kfree(data_node);
}
+
+ return 0;
}
/**
@@ -1490,6 +1493,7 @@ static int correct_file_info(struct ubifs_info *c, struct scanned_file *file)
file->calc_size == file->ino.size)
return 0;
+ handle_invalid_file(c, FILE_IS_INCONSISTENT, file, NULL);
lnum = file->ino.header.lnum;
dbg_fsck("correct file(inum:%lu type:%s), nlink %u->%u, xattr cnt %u->%u, xattr size %u->%u, xattr names %u->%u, size %llu->%llu, at %d:%d, in %s",
file->inum, file->ino.is_xattr ? "xattr" :
@@ -1537,7 +1541,9 @@ int check_and_correct_files(struct ubifs_info *c)
for (node = rb_first(tree); node; node = rb_next(node)) {
file = rb_entry(node, struct scanned_file, rb);
- calculate_file_info(c, file, tree);
+ err = calculate_file_info(c, file, tree);
+ if (err)
+ return err;
}
for (node = rb_first(tree); node; node = rb_next(node)) {
@@ -1548,5 +1554,21 @@ int check_and_correct_files(struct ubifs_info *c)
return err;
}
+ if (list_empty(&FSCK(c)->disconnected_files))
+ return 0;
+
+ ubifs_assert(c, FSCK(c)->mode != REBUILD_MODE);
+ list_for_each_entry(file, &FSCK(c)->disconnected_files, list) {
+ err = calculate_file_info(c, file, tree);
+ if (err)
+ return err;
+
+ /* Reset disconnected file's nlink as one. */
+ file->calc_nlink = 1;
+ err = correct_file_info(c, file);
+ if (err)
+ return err;
+ }
+
return 0;
}