X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Flookup_table.c;h=3d2abf60539380b9ab3656cdfb72cff13f7d2777;hb=3b05052885168a50852b86609a89f29d1c0c6d97;hp=1950ab21a89bbbefb75fc56473ce64936d12753c;hpb=cc7b6ee47d4037ae8fa11b4c2d5154091d543704;p=wimlib diff --git a/src/lookup_table.c b/src/lookup_table.c index 1950ab21..3d2abf60 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 @@ -35,6 +33,7 @@ #include "wimlib/metadata.h" #include "wimlib/ntfs_3g.h" #include "wimlib/resource.h" +#include "wimlib/unaligned.h" #include "wimlib/util.h" #include "wimlib/write.h" @@ -245,20 +244,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. + * + * 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. * - * 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. + * 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) { @@ -269,7 +282,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)) @@ -364,7 +378,7 @@ lookup_stream(const struct wim_lookup_table *table, const u8 hash[]) struct wim_lookup_table_entry *lte; struct hlist_node *pos; - i = *(size_t*)hash % table->capacity; + i = load_size_t_unaligned(hash) % table->capacity; hlist_for_each_entry(lte, pos, &table->array[i], hash_list) if (hashes_equal(hash, lte->hash)) return lte; @@ -564,7 +578,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 @@ -1257,20 +1272,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; -} - /* 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 *