diff options
author | Xiang Yang <xiangyang3@huawei.com> | 2024-11-11 17:08:06 +0800 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2024-11-11 10:32:46 +0100 |
commit | d0b66b0e5bb346e795a4c0ac3cafd287a6e4db9d (patch) | |
tree | a266718d7a77f1995d4d5a2ee53cbe843cd1dd6d /ubifs-utils/fsck.ubifs/extract_files.c | |
parent | a251dd9c71006c66a02064210ae103ed7ac59444 (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.c | 76 |
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; } |