-
- /* One or more dentries had data streams specified. We check each of
- * these dentries for consistency with the others to form a set of true
- * inodes. */
- num_true_inodes = 0;
- list_for_each_entry(dentry, &dentries_with_data_streams, tmp_list) {
- /* Look for a true inode that is consistent with this dentry and
- * add this dentry to it. Or, if none of the true inodes are
- * consistent with this dentry, add a new one (if that happens,
- * we have split the hard link group). */
- hlist_for_each_entry(inode, cur, &true_inodes, i_hlist) {
- if (ref_inodes_consistent(inode, dentry->d_inode)) {
- inode_add_dentry(dentry, inode);
- goto next_dentry_2;
- }
- }
- num_true_inodes++;
- INIT_LIST_HEAD(&dentry->d_inode->i_dentry);
- inode_add_dentry(dentry, dentry->d_inode);
- hlist_add_head(&dentry->d_inode->i_hlist, &true_inodes);
-next_dentry_2:
- ;
- }
-
- wimlib_assert(num_true_inodes != 0);
-
- /* If there were dentries with no data streams, we require there to only
- * be one true inode so that we know which inode to assign the
- * streamless dentries to. */
- if (!list_empty(&dentries_with_no_data_streams)) {
- if (num_true_inodes != 1) {
- ERROR("Hard link ambiguity detected!");
- ERROR("We split up inode 0x%"PRIx64" due to "
- "inconsistencies,", inode->i_ino);
- ERROR("but dentries with no stream information remained. "
- "We don't know which inode");
- ERROR("to assign them to.");
- ret = WIMLIB_ERR_INVALID_METADATA_RESOURCE;
- goto out_cleanup_true_inode_list;
- }
- inode = container_of(true_inodes.first, struct wim_inode, i_hlist);
- /* Assign the streamless dentries to the one and only true
- * inode. */
- list_for_each_entry(dentry, &dentries_with_no_data_streams, tmp_list)
- inode_add_dentry(dentry, inode);
- }
- if (num_true_inodes != 1) {
- #ifdef ENABLE_DEBUG
- inode = container_of(true_inodes.first, struct wim_inode, i_hlist);
-
- tprintf(T("Split nominal inode 0x%"PRIx64" into %zu "
- "inodes:\n"), inode->i_ino, num_true_inodes);
- tputs(T("----------------------------------------------------"
- "--------------------------"));
- size_t i = 1;
- hlist_for_each_entry(inode, cur, &true_inodes, i_hlist) {
- tprintf(T("[Split inode %zu]\n"), i++);
- print_inode_dentries(inode);
- tputchar(T('\n'));
- }
- tputs(T("----------------------------------------------------"
- "--------------------------"));
- #endif
- *ino_changes_needed = true;
- }
-
- hlist_for_each_entry_safe(inode, cur, tmp, &true_inodes, i_hlist) {
- hlist_del_init(&inode->i_hlist);
- ret = fix_true_inode(inode, inode_list);
- if (ret)
- goto out_cleanup_true_inode_list;
- }
- ret = 0;
- goto out;
-out_cleanup_true_inode_list:
- hlist_for_each_entry_safe(inode, cur, tmp, &true_inodes, i_hlist)
- hlist_del_init(&inode->i_hlist);
-out:
- return ret;