dentry_find_streams_to_extract(): Handle hard links correctly
authorEric Biggers <ebiggers3@gmail.com>
Tue, 14 May 2013 03:24:06 +0000 (22:24 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Tue, 14 May 2013 03:24:06 +0000 (22:24 -0500)
src/dentry.h
src/extract_image.c

index 1500bd7c3c63238ff07baeadb0b59ddb2c9d33be..a613db42c655c7d412194a533256c767aceb1ceb 100644 (file)
@@ -232,6 +232,8 @@ struct wim_inode {
        /* %true iff verify_inode() has run on this inode. */
        u8 i_verified : 1;
 
+       u8 i_visited : 1;
+
        /* Used only in NTFS-mode extraction */
        u8 i_dos_name_extracted : 1;
 
index 20b44ee26aac24aa1720282398533af2dd00ac29..fd7453aab9d8d6f34d2e98dcf85ab70dfc80774f 100644 (file)
@@ -187,7 +187,8 @@ dentry_find_streams_to_extract(struct wim_dentry *dentry, void *_ctx)
 
        lte = inode_unnamed_lte_resolved(inode);
        if (lte) {
-               maybe_add_stream_for_extraction(lte, stream_list);
+               if (!inode->i_visited)
+                       maybe_add_stream_for_extraction(lte, stream_list);
                list_add_tail(&dentry->tmp_list, &lte->lte_dentry_list);
                dentry_added = true;
        }
@@ -210,8 +211,10 @@ dentry_find_streams_to_extract(struct wim_dentry *dentry, void *_ctx)
                        if (inode->i_ads_entries[i].stream_name_nbytes != 0) {
                                lte = inode->i_ads_entries[i].lte;
                                if (lte) {
-                                       maybe_add_stream_for_extraction(lte,
-                                                                       stream_list);
+                                       if (!inode->i_visited) {
+                                               maybe_add_stream_for_extraction(lte,
+                                                                               stream_list);
+                                       }
                                        if (!dentry_added) {
                                                list_add_tail(&dentry->tmp_list,
                                                              &lte->lte_dentry_list);
@@ -221,6 +224,7 @@ dentry_find_streams_to_extract(struct wim_dentry *dentry, void *_ctx)
                        }
                }
        }
+       inode->i_visited = 1;
        return 0;
 }
 
@@ -259,6 +263,7 @@ static int
 dentry_reset_needs_extraction(struct wim_dentry *dentry, void *_ignore)
 {
        dentry->needs_extraction = 0;
+       dentry->d_inode->i_visited = 0;
        return 0;
 }