X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Finode_fixup.c;h=01a16d19af2e13ca07202477b972f9c926172f51;hp=5f203b7ba0708212526143465200cdca73fb1d03;hb=9b2a1ba93ab90a85466eaa3acda69a2d3f914f3e;hpb=5d3d469e410dc5f4a28814ad231336fc174cba56 diff --git a/src/inode_fixup.c b/src/inode_fixup.c index 5f203b7b..01a16d19 100644 --- a/src/inode_fixup.c +++ b/src/inode_fixup.c @@ -97,27 +97,63 @@ ref_inodes_consistent(const struct wim_inode * restrict ref_inode_1, return true; } +/* Returns true iff the specified inode has any data streams with nonzero hash. + */ static bool -inodes_consistent(const struct wim_inode * restrict ref_inode, - const struct wim_inode * restrict inode) +inode_has_data_streams(const struct wim_inode *inode) { - wimlib_assert(ref_inode != inode); + for (unsigned i = 0; i <= inode->i_num_ads; i++) + if (!is_zero_hash(inode_stream_hash(inode, i))) + return true; + return false; +} - if (ref_inode->i_num_ads != inode->i_num_ads && - inode->i_num_ads != 0) +/* Returns true iff the specified dentry has any data streams with nonzero hash. + */ +static bool +dentry_has_data_streams(const struct wim_dentry *dentry) +{ + return inode_has_data_streams(dentry->d_inode); +} + +static bool +inodes_consistent(const struct wim_inode *ref_inode, + const struct wim_inode *inode) +{ + if (ref_inode->i_security_id != inode->i_security_id) { + ERROR("Security ID mismatch: %d != %d", + ref_inode->i_security_id, inode->i_security_id); return false; - if (ref_inode->i_security_id != inode->i_security_id - || ref_inode->i_attributes != inode->i_attributes) + } + + if (ref_inode->i_attributes != inode->i_attributes) { + ERROR("Attributes mismatch: 0x%08x != 0x%08x", + ref_inode->i_attributes, inode->i_attributes); return false; - for (unsigned i = 0; i <= min(ref_inode->i_num_ads, inode->i_num_ads); i++) { - const u8 *ref_hash, *hash; - ref_hash = inode_stream_hash(ref_inode, i); - hash = inode_stream_hash(inode, i); - if (!hashes_equal(ref_hash, hash) && !is_zero_hash(hash)) - return false; - if (i && !ads_entries_have_same_name(&ref_inode->i_ads_entries[i - 1], - &inode->i_ads_entries[i - 1])) + } + + if (inode_has_data_streams(inode)) { + if (ref_inode->i_num_ads != inode->i_num_ads) { + ERROR("Stream count mismatch: %u != %u", + ref_inode->i_num_ads, inode->i_num_ads); return false; + } + for (unsigned i = 0; i <= ref_inode->i_num_ads; i++) { + const u8 *ref_hash, *hash; + + ref_hash = inode_stream_hash(ref_inode, i); + hash = inode_stream_hash(inode, i); + if (!hashes_equal(ref_hash, hash) && !is_zero_hash(hash)) { + ERROR("Stream hash mismatch"); + return false; + } + if (i && !ads_entries_have_same_name(&ref_inode->i_ads_entries[i - 1], + &inode->i_ads_entries[i - 1])) + { + ERROR("Stream name mismatch"); + return false; + } + } } return true; } @@ -202,19 +238,10 @@ fix_nominal_inode(struct wim_inode *inode, struct list_head *inode_list, * least one data stream with a non-zero hash, and another list that * contains the dentries that have a zero hash for all data streams. */ inode_for_each_dentry(dentry, inode) { - for (unsigned i = 0; i <= dentry->d_inode->i_num_ads; i++) { - const u8 *hash; - hash = inode_stream_hash(dentry->d_inode, i); - if (!is_zero_hash(hash)) { - list_add(&dentry->tmp_list, - &dentries_with_data_streams); - goto next_dentry; - } - } - list_add(&dentry->tmp_list, - &dentries_with_no_data_streams); - next_dentry: - ; + if (dentry_has_data_streams(dentry)) + list_add(&dentry->tmp_list, &dentries_with_data_streams); + else + list_add(&dentry->tmp_list, &dentries_with_no_data_streams); } /* If there are no dentries with data streams, we require the nominal @@ -441,7 +468,8 @@ dentry_tree_fix_inodes(struct wim_dentry *root, struct list_head *inode_list) if (ino_changes_needed) { u64 cur_ino = 1; - WARNING("Re-assigning inode numbers due to inode inconsistencies"); + WARNING("The WIM image contains invalid hard links. Fixing."); + list_for_each_entry(inode, inode_list, i_list) { if (inode->i_nlink > 1) inode->i_ino = cur_ino++;