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;
}
* 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