From: Eric Biggers Date: Mon, 28 Apr 2014 06:47:37 +0000 (-0500) Subject: Don't immediately discard streams with 0 references X-Git-Tag: v1.7.0~255 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=bafd3460a2f40174b8329e6059fd7338730958e8 Don't immediately discard streams with 0 references --- diff --git a/src/export_image.c b/src/export_image.c index bfeef97a..8d449ea9 100644 --- a/src/export_image.c +++ b/src/export_image.c @@ -87,10 +87,12 @@ lte_unexport(struct wim_lookup_table_entry *lte, void *_lookup_table) { struct wim_lookup_table *lookup_table = _lookup_table; - lte->refcnt -= lte->out_refcnt; - if (lte->refcnt == 0) { - lookup_table_unlink(lookup_table, lte); - free_lookup_table_entry(lte); + if (lte->out_refcnt) { + lte->refcnt -= lte->out_refcnt; + if (lte->refcnt == 0) { + lookup_table_unlink(lookup_table, lte); + free_lookup_table_entry(lte); + } } return 0; } diff --git a/src/lookup_table.c b/src/lookup_table.c index 889013e0..ed0ab750 100644 --- a/src/lookup_table.c +++ b/src/lookup_table.c @@ -235,10 +235,30 @@ free_lookup_table_entry(struct wim_lookup_table_entry *lte) } } -/* 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) @@ -257,7 +277,8 @@ lte_decrement_refcnt(struct wim_lookup_table_entry *lte, 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 @@ -266,7 +287,7 @@ lte_decrement_refcnt(struct wim_lookup_table_entry *lte, #ifdef WITH_FUSE if (lte->num_opened_fds == 0) #endif - free_lookup_table_entry(lte); + finalize_lte(lte); } } @@ -277,7 +298,7 @@ lte_decrement_num_opened_fds(struct wim_lookup_table_entry *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