X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Flookup_table.c;h=8dc24109f89ea16697abdfbc6ce6fc283c755e9c;hb=0ac1c0afd3f1b4341409e66cb31c94053d1b8988;hp=6f0786500b817b3bb3568f344778afe1fe623165;hpb=901c4d3b47bebcf5b854e32559f8e693ad3b5f14;p=wimlib diff --git a/src/lookup_table.c b/src/lookup_table.c index 6f078650..8dc24109 100644 --- a/src/lookup_table.c +++ b/src/lookup_table.c @@ -8,20 +8,18 @@ /* * Copyright (C) 2012, 2013, 2014 Eric Biggers * - * This file is part of wimlib, a library for working with WIM files. + * This file is free software; you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at your option) any + * later version. * - * wimlib is free software; you can redistribute it and/or modify it under the - * terms of the GNU General Public License as published by the Free - * Software Foundation; either version 3 of the License, or (at your option) - * any later version. - * - * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the GNU General Public License for more + * This file is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * - * You should have received a copy of the GNU General Public License - * along with wimlib; if not, see http://www.gnu.org/licenses/. + * You should have received a copy of the GNU Lesser General Public License + * along with this file; if not, see http://www.gnu.org/licenses/. */ #ifdef HAVE_CONFIG_H @@ -127,7 +125,6 @@ clone_lookup_table_entry(const struct wim_lookup_table_entry *old) if (new == NULL) return NULL; - new->extracted_file = NULL; switch (new->resource_location) { case RESOURCE_IN_WIM: list_add(&new->rspec_node, &new->rspec->stream_list); @@ -135,6 +132,7 @@ clone_lookup_table_entry(const struct wim_lookup_table_entry *old) case RESOURCE_IN_FILE_ON_DISK: #ifdef __WIN32__ + case RESOURCE_IN_WINNT_FILE_ON_DISK: case RESOURCE_WIN32_ENCRYPTED: #endif #ifdef WITH_FUSE @@ -194,6 +192,7 @@ lte_put_resource(struct wim_lookup_table_entry *lte) break; case RESOURCE_IN_FILE_ON_DISK: #ifdef __WIN32__ + case RESOURCE_IN_WINNT_FILE_ON_DISK: case RESOURCE_WIN32_ENCRYPTED: #endif #ifdef WITH_FUSE @@ -244,20 +243,34 @@ finalize_lte(struct wim_lookup_table_entry *lte) } /* - * Decrements the reference count for the lookup table entry @lte, which must be - * inserted in the stream lookup table @table. + * Decrements the reference count of the single-instance stream @lte, which must + * be inserted in the stream lookup table @table. + * + * If the stream's reference count reaches 0, we may unlink it from @table and + * free it. However, we retain streams with 0 reference count that originated + * from WIM files (RESOURCE_IN_WIM). We do this for two reasons: + * + * 1. This prevents information about valid streams in a WIM file --- streams + * which will continue to be present after appending to the WIM file --- from + * being lost merely because we dropped all references to them. * - * 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. + * 2. Stream reference counts we read from WIM files can't be trusted. It's + * possible that a WIM has reference counts that are too low; WIMGAPI + * sometimes creates WIMs where this is the case. It's also possible that + * streams have been referenced from an external WIM; those streams can + * potentially have any reference count at all, either lower or higher than + * would be expected for this WIM ("this WIM" meaning the owner of @table) if + * it were a standalone WIM. + * + * So we can't take the reference counts too seriously. But at least, we do + * recalculate by default when writing a new WIM file. */ void lte_decrement_refcnt(struct wim_lookup_table_entry *lte, struct wim_lookup_table *table) { - wimlib_assert(lte->refcnt != 0); + if (unlikely(lte->refcnt == 0)) /* See comment above */ + return; if (--lte->refcnt == 0) { if (lte->unhashed) { @@ -268,7 +281,8 @@ lte_decrement_refcnt(struct wim_lookup_table_entry *lte, * that there still may be open file descriptors to it.) * */ if (lte->resource_location == RESOURCE_IN_STAGING_FILE) - unlink(lte->staging_file_name); + unlinkat(lte->staging_dir_fd, + lte->staging_file_name, 0); #endif } else { if (!should_retain_lte(lte)) @@ -444,6 +458,7 @@ cmp_streams_by_sequential_order(const void *p1, const void *p2) case RESOURCE_IN_STAGING_FILE: #endif #ifdef __WIN32__ + case RESOURCE_IN_WINNT_FILE_ON_DISK: case RESOURCE_WIN32_ENCRYPTED: #endif /* Compare files by path: just a heuristic that will place files @@ -562,7 +577,8 @@ struct wim_lookup_table_entry_disk { /* Which part of the split WIM this stream is in; indexed from 1. */ le16 part_number; - /* Reference count of this stream over all WIM images. */ + /* Reference count of this stream over all WIM images. (But see comment + * above lte_decrement_refcnt().) */ le32 refcnt; /* SHA1 message digest of the uncompressed data of this stream, or @@ -1255,30 +1271,6 @@ write_wim_lookup_table_from_stream_list(struct list_head *stream_list, return ret; } -int -lte_zero_real_refcnt(struct wim_lookup_table_entry *lte, void *_ignore) -{ - lte->real_refcnt = 0; - return 0; -} - -int -lte_zero_out_refcnt(struct wim_lookup_table_entry *lte, void *_ignore) -{ - lte->out_refcnt = 0; - return 0; -} - -int -lte_free_extracted_file(struct wim_lookup_table_entry *lte, void *_ignore) -{ - if (lte->extracted_file != NULL) { - FREE(lte->extracted_file); - lte->extracted_file = NULL; - } - return 0; -} - /* Allocate a stream entry for the contents of the buffer, or re-use an existing * entry in @lookup_table for the same stream. */ struct wim_lookup_table_entry *