+/* Assign the inode numbers to dentries in a inode table, and return the
+ * next available inode ID. */
+u64 assign_inode_numbers(struct hlist_head *inode_list)
+{
+ DEBUG("Assigning inode numbers");
+ struct inode *inode;
+ struct hlist_node *cur;
+ u64 cur_ino = 1;
+ hlist_for_each_entry(inode, cur, inode_list, hlist) {
+ inode->ino = cur_ino;
+ cur_ino++;
+ }
+ return cur_ino;
+}
+
+
+static void print_inode_dentries(const struct inode *inode)
+{
+ struct dentry *dentry;
+ list_for_each_entry(dentry, &inode->dentry_list, inode_dentry_list)
+ printf("`%s'\n", dentry->full_path_utf8);
+}
+
+static void inconsistent_inode(const struct inode *inode)
+{
+ ERROR("An inconsistent hard link group that we cannot correct has been "
+ "detected");
+ ERROR("The dentries are located at the following paths:");
+ print_inode_dentries(inode);
+}
+
+static bool ref_inodes_consistent(const struct inode * restrict ref_inode_1,
+ const struct inode * restrict ref_inode_2)
+{
+ wimlib_assert(ref_inode_1 != ref_inode_2);
+
+ if (ref_inode_1->num_ads != ref_inode_2->num_ads)
+ return false;
+ if (ref_inode_1->security_id != ref_inode_2->security_id
+ || ref_inode_1->attributes != ref_inode_2->attributes)
+ return false;
+ for (unsigned i = 0; i <= ref_inode_1->num_ads; i++) {
+ const u8 *ref_1_hash, *ref_2_hash;
+ ref_1_hash = inode_stream_hash(ref_inode_1, i);
+ ref_2_hash = inode_stream_hash(ref_inode_2, i);
+ if (!hashes_equal(ref_1_hash, ref_2_hash))
+ return false;
+ if (i && !ads_entries_have_same_name(ref_inode_1->ads_entries[i - 1],
+ ref_inode_2->ads_entries[i - 1]))
+ return false;
+
+ }
+ return true;
+}
+
+static bool inodes_consistent(const struct inode * restrict ref_inode,
+ const struct inode * restrict inode)
+{
+ wimlib_assert(ref_inode != inode);
+
+ if (ref_inode->num_ads != inode->num_ads &&
+ inode->num_ads != 0)
+ return false;
+ if (ref_inode->security_id != inode->security_id
+ || ref_inode->attributes != inode->attributes)
+ return false;
+ for (unsigned i = 0; i <= min(ref_inode->num_ads, inode->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->ads_entries[i - 1],
+ inode->ads_entries[i - 1]))
+ return false;
+ }
+ return true;
+}
+
+#ifdef ENABLE_DEBUG
+static void
+print_dentry_list(const struct dentry *first_dentry)