}
}
-/* Decrements the reference count for the lookup table entry @lte. If its
- * reference count reaches 0, it is unlinked from the lookup table. If,
- * furthermore, the entry has no opened file descriptors associated with it, the
- * entry is freed. */
+/* Should this stream be retained even if it has no references? */
+static bool
+should_retain_lte(const struct wim_lookup_table_entry *lte)
+{
+ return lte->resource_location == RESOURCE_IN_WIM;
+}
+
+static void
+finalize_lte(struct wim_lookup_table_entry *lte)
+{
+ if (!should_retain_lte(lte))
+ free_lookup_table_entry(lte);
+}
+
+/*
+ * Decrements the reference count for the lookup table entry @lte, which must be
+ * inserted in the stream lookup table @table.
+ *
+ * If the reference count reaches 0, this may cause @lte to be destroyed.
+ * However, we may retain entries with 0 reference count. This does not affect
+ * correctness, but it prevents the entries for valid streams in a WIM archive,
+ * which will continue to be present after appending to the file, from being
+ * lost merely because we dropped all references to them.
+ */
void
lte_decrement_refcnt(struct wim_lookup_table_entry *lte,
struct wim_lookup_table *table)
unlink(lte->staging_file_name);
#endif
} else {
- lookup_table_unlink(table, lte);
+ if (!should_retain_lte(lte))
+ lookup_table_unlink(table, lte);
}
/* If FUSE mounts are enabled, we don't actually free the entry
#ifdef WITH_FUSE
if (lte->num_opened_fds == 0)
#endif
- free_lookup_table_entry(lte);
+ finalize_lte(lte);
}
}
wimlib_assert(lte->num_opened_fds != 0);
if (--lte->num_opened_fds == 0 && lte->refcnt == 0)
- free_lookup_table_entry(lte);
+ finalize_lte(lte);
}
#endif
struct wim_resource_spec *cur_rspec;
void *buf;
bool back_to_back_pack;
+ size_t num_duplicate_entries = 0;
DEBUG("Reading lookup table.");
* resource. */
duplicate_entry = lookup_stream(table, cur_entry->hash);
if (duplicate_entry) {
- WARNING("The WIM lookup table contains two entries "
- "with the same SHA1 message digest!");
+ num_duplicate_entries++;
free_lookup_table_entry(cur_entry);
continue;
}
put_image_metadata(wim->image_metadata[i], NULL);
wim->hdr.image_count = wim->current_image;
}
+
+ if (num_duplicate_entries > 0) {
+ WARNING("Ignoring %zu duplicate streams in the WIM lookup table",
+ num_duplicate_entries);
+ }
+
DEBUG("Done reading lookup table.");
wim->lookup_table = table;
ret = 0;