]> wimlib.net Git - wimlib/blobdiff - src/hardlink.c
read_dentry_tree(): Ignore duplicate dentries
[wimlib] / src / hardlink.c
index f6752ff4603ef37d8d07f388d383f0b6dd22cffd..5e2c62618ad43b5e2641d97a31cb86f899425e97 100644 (file)
  * along with wimlib; if not, see http://www.gnu.org/licenses/.
  */
 
-#include "wimlib_internal.h"
-#include "dentry.h"
-#include "list.h"
-#include "lookup_table.h"
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include "wimlib/capture.h"
+#include "wimlib/dentry.h"
+#include "wimlib/error.h"
+#include "wimlib/lookup_table.h"
 
 /*                             NULL        NULL
  *                              ^           ^
@@ -305,8 +309,6 @@ fix_true_inode(struct wim_inode *inode, struct list_head *inode_list)
                                return WIMLIB_ERR_INVALID_DENTRY;
                        }
                        /* Free the unneeded `struct wim_inode'. */
-                       dentry->d_inode->i_hlist.next = NULL;
-                       dentry->d_inode->i_hlist.pprev = NULL;
                        free_inode(dentry->d_inode);
                        dentry->d_inode = ref_inode;
                        ref_inode->i_nlink++;
@@ -344,6 +346,13 @@ fix_nominal_inode(struct wim_inode *inode, struct list_head *inode_list,
 
        wimlib_assert(inode->i_nlink == inode_link_count(inode));
 
+       if (inode->i_nlink > 1 &&
+           (inode->i_attributes & FILE_ATTRIBUTE_DIRECTORY))
+       {
+               ERROR("Found unsupported directory hard link!");
+               return WIMLIB_ERR_INVALID_DENTRY;
+       }
+
        LIST_HEAD(dentries_with_data_streams);
        LIST_HEAD(dentries_with_no_data_streams);
        HLIST_HEAD(true_inodes);
@@ -465,6 +474,7 @@ fix_inodes(struct wim_inode_table *table, struct list_head *inode_list,
        INIT_LIST_HEAD(inode_list);
        for (u64 i = 0; i < table->capacity; i++) {
                hlist_for_each_entry_safe(inode, cur, tmp, &table->array[i], i_hlist) {
+                       INIT_LIST_HEAD(&inode->i_list);
                        ret = fix_nominal_inode(inode, inode_list, ino_changes_needed);
                        if (ret)
                                return ret;
@@ -546,7 +556,13 @@ inode_table_prepare_inode_list(struct wim_inode_table *table,
        struct hlist_node *cur, *tmp;
        u64 cur_ino = 1;
 
-       INIT_LIST_HEAD(head);
+       list_for_each_entry(inode, head, i_list) {
+               if (inode->i_nlink > 1)
+                       inode->i_ino = cur_ino++;
+               else
+                       inode->i_ino = 0;
+       }
+
        for (size_t i = 0; i < table->capacity; i++) {
                hlist_for_each_entry_safe(inode, cur, tmp, &table->array[i], i_hlist)
                {