From dc9916cb5419320b2c570af2b81e92f3d26b6e4f Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sun, 18 Aug 2013 14:25:10 -0500 Subject: [PATCH] extract.c: Fix extraction of streams of hard-linked files Due to the re-ordering of dentries in a directory to extract correct DOS names, was_hardlinked could be set on the dentry referenced by a stream, thereby causing the stream not to be extracted. Fix by having each stream reference all possible dentries. --- src/extract.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/extract.c b/src/extract.c index b40d708d..235d504c 100644 --- a/src/extract.c +++ b/src/extract.c @@ -123,13 +123,19 @@ ref_stream_to_extract(struct wim_lookup_table_entry *lte, if (!lte) return 0; - if (likely(!is_linked_extraction(ctx)) || (lte->out_refcnt == 0 && - lte->extracted_file == NULL)) + /* Tally the size only for each extraction of the stream (not hard + * links). */ + if (!(dentry->d_inode->i_visited && + ctx->supported_features.hard_links) && + (!is_linked_extraction(ctx) || (lte->out_refcnt == 0 && + lte->extracted_file == NULL))) { ctx->progress.extract.total_bytes += wim_resource_size(lte); ctx->progress.extract.num_streams++; } + /* Add stream to the extraction_list only one time, even if it's going + * to be extracted to multiple locations. */ if (lte->out_refcnt == 0) { list_add_tail(<e->extraction_list, &ctx->stream_list); ctx->num_streams_remaining++; @@ -183,7 +189,9 @@ ref_stream_to_extract(struct wim_lookup_table_entry *lte, * extracted (ctx->stream_list) if not already done so, and also update the * progress information (ctx->progress) with the stream. Furthermore, if doing * a sequential extraction, build a mapping from each the stream to the dentries - * referencing it. */ + * referencing it. + * + * This uses the i_visited member of the inodes (assumed to be 0 initially). */ static int dentry_add_streams_to_extract(struct wim_dentry *dentry, void *_ctx) { @@ -195,10 +203,6 @@ dentry_add_streams_to_extract(struct wim_dentry *dentry, void *_ctx) if (dentry->extraction_skipped) return 0; - /* Don't process additional hard links. */ - if (inode->i_visited && ctx->supported_features.hard_links) - return 0; - /* The unnamed data stream will always be extracted, except in an * unlikely case. */ if (!inode_is_encrypted_directory(inode)) { -- 2.43.0