From aa3a2830cd4154238bc6a342ffea43d9ac69a14c Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Wed, 1 Apr 2015 21:46:38 -0500 Subject: [PATCH] inode/blob cleanups --- Makefile.am | 2 +- include/wimlib/blob_table.h | 9 +++---- include/wimlib/dentry.h | 30 ++++++++--------------- include/wimlib/header.h | 2 +- include/wimlib/wim.h | 4 ++-- src/blob_table.c | 47 +++++++++++++++---------------------- src/header.c | 8 +++---- src/inode.c | 19 +++++---------- 8 files changed, 48 insertions(+), 73 deletions(-) diff --git a/Makefile.am b/Makefile.am index 23ccd855..54130f65 100644 --- a/Makefile.am +++ b/Makefile.am @@ -96,6 +96,7 @@ libwim_la_SOURCES = \ include/wimlib/assert.h \ include/wimlib/avl_tree.h \ include/wimlib/bitops.h \ + include/wimlib/blob_table.h \ include/wimlib/bt_matchfinder.h \ include/wimlib/callback.h \ include/wimlib/capture.h \ @@ -121,7 +122,6 @@ libwim_la_SOURCES = \ include/wimlib/integrity.h \ include/wimlib/lcpit_matchfinder.h \ include/wimlib/list.h \ - include/wimlib/lookup_table.h \ include/wimlib/lz_extend.h \ include/wimlib/lz_hash.h \ include/wimlib/lzms_common.h \ diff --git a/include/wimlib/blob_table.h b/include/wimlib/blob_table.h index c86fac0d..1adec4ed 100644 --- a/include/wimlib/blob_table.h +++ b/include/wimlib/blob_table.h @@ -55,16 +55,17 @@ enum blob_location { #endif }; -/* A "blob target" is a stream, and the inode to which that stream belongs, to - * which a blob needs to be extracted as part of an extraction operation. Since - * blobs are single-instanced, a blob may have multiple targets. */ +/* A "blob extraction target" is a stream, and the inode to which that stream + * belongs, to which a blob needs to be extracted as part of an extraction + * operation. Since blobs are single-instanced, a blob may have multiple + * extraction targets. */ struct blob_extraction_target { struct wim_inode *inode; struct wim_inode_stream *stream; }; /* - * Descriptor for a blob, which is a known length sequence of binary data. + * Descriptor for a "blob", which is a known length sequence of binary data. * * Within a WIM file, blobs are single instanced and are identified by SHA-1 * message digest. diff --git a/include/wimlib/dentry.h b/include/wimlib/dentry.h index cb0f330b..40a4c8e6 100644 --- a/include/wimlib/dentry.h +++ b/include/wimlib/dentry.h @@ -21,28 +21,18 @@ struct blob_table; * tree for each image in the WIM. * * Note that this is a directory entry and not an inode. Since NTFS allows hard - * links, it's possible for an NTFS inode to correspond to multiple WIM dentries. - * The hard link group ID field of the on-disk WIM dentry tells us the number of - * the NTFS inode that the dentry corresponds to (and this gets placed in - * d_inode->i_ino). + * links, it's possible for an NTFS inode to correspond to multiple WIM + * dentries. The hard link group ID field of the on-disk WIM dentry tells us + * the number of the NTFS inode that the dentry corresponds to (and this gets + * placed in d_inode->i_ino). * * Unfortunately, WIM files do not have an analogue to an inode; instead certain - * information, such as file attributes, the security descriptor, and file - * streams is replicated in each hard-linked dentry, even though this - * information really is associated with an inode. In-memory, we fix up this - * flaw by allocating a `struct wim_inode' for each dentry that contains some of - * this duplicated information, then combining the inodes for each hard link - * group together. - * - * Confusingly, it's possible for stream information to be missing from a dentry - * in a hard link set, in which case the stream information needs to be gotten - * from one of the other dentries in the hard link set. In addition, it is - * possible for dentries to have inconsistent security IDs, file attributes, or - * file streams when they share the same hard link ID (don't even ask. I hope - * that Microsoft may have fixed this problem, since I've only noticed it in the - * 'install.wim' for Windows 7). For those dentries, we have to use the - * conflicting fields to split up the hard link groups. (See - * dentry_tree_fix_inodes() in inode_fixup.c.) + * information, such as file attributes, the security descriptor, and streams is + * replicated in each hard-linked dentry, even though this information really is + * associated with an inode. In-memory, we fix up this flaw by allocating a + * `struct wim_inode' for each dentry that contains some of this duplicated + * information, then combining the inodes for each hard link group together. + * (See dentry_tree_fix_inodes().) */ struct wim_dentry { /* Pointer to the inode for this dentry. This will contain some diff --git a/include/wimlib/header.h b/include/wimlib/header.h index feb31764..735a99fb 100644 --- a/include/wimlib/header.h +++ b/include/wimlib/header.h @@ -13,7 +13,7 @@ * be exactly this size. */ #define WIM_HEADER_DISK_SIZE 208 -/* Default WIM version number. Streams are always compressed independently. */ +/* Default WIM version number. Blobs are always compressed independently. */ #define WIM_VERSION_DEFAULT 0x10d00 /* Version number used for WIMs that allow multiple blobs combined into one diff --git a/include/wimlib/wim.h b/include/wimlib/wim.h index b0d351ec..cb330a21 100644 --- a/include/wimlib/wim.h +++ b/include/wimlib/wim.h @@ -29,7 +29,7 @@ struct blob_table; * * Note 2: although this is the top-level data structure in wimlib, there do * exist cases in which a WIMStruct is not standalone: - * - streams have been referenced from another WIMStruct + * - blobs have been referenced from another WIMStruct * - an image has been imported into this WIMStruct from another * (as this references the metadata rather than copies it) * @@ -154,7 +154,7 @@ struct WIMStruct { /* * Return true if and only if the WIM contains image metadata (actual directory - * trees, not just a collection of streams and their checksums). + * trees, not just a collection of blobs and their checksums). * * See the description of the 'image_metadata' field. Note that we return true * when the image count is 0 because it could be a WIM with 0 images. It's only diff --git a/src/blob_table.c b/src/blob_table.c index cf25d005..2d346e35 100644 --- a/src/blob_table.c +++ b/src/blob_table.c @@ -99,17 +99,8 @@ free_blob_table(struct blob_table *table) struct blob_descriptor * new_blob_descriptor(void) { - struct blob_descriptor *blob; - - blob = CALLOC(1, sizeof(struct blob_descriptor)); - if (blob == NULL) - return NULL; - - /* blob->refcnt = 0 */ - /* blob->blob_location = BLOB_NONEXISTENT */ BUILD_BUG_ON(BLOB_NONEXISTENT != 0); - - return blob; + return CALLOC(1, sizeof(struct blob_descriptor)); } struct blob_descriptor * @@ -1254,27 +1245,27 @@ new_blob_from_data_buffer(const void *buffer, size_t size, struct blob_table *blob_table) { u8 hash[SHA1_HASH_SIZE]; - struct blob_descriptor *blob, *existing_blob; + struct blob_descriptor *blob; + void *buffer_copy; sha1_buffer(buffer, size, hash); - existing_blob = lookup_blob(blob_table, hash); - if (existing_blob) { - wimlib_assert(existing_blob->size == size); - blob = existing_blob; - } else { - void *buffer_copy; - blob = new_blob_descriptor(); - if (blob == NULL) - return NULL; - buffer_copy = memdup(buffer, size); - if (buffer_copy == NULL) { - free_blob_descriptor(blob); - return NULL; - } - blob_set_is_located_in_attached_buffer(blob, buffer_copy, size); - copy_hash(blob->hash, hash); - blob_table_insert(blob_table, blob); + + blob = lookup_blob(blob_table, hash); + if (blob) + return blob; + + blob = new_blob_descriptor(); + if (!blob) + return NULL; + + buffer_copy = memdup(buffer, size); + if (!buffer_copy) { + free_blob_descriptor(blob); + return NULL; } + blob_set_is_located_in_attached_buffer(blob, buffer_copy, size); + copy_hash(blob->hash, hash); + blob_table_insert(blob_table, blob); return blob; } diff --git a/src/header.c b/src/header.c index 82088998..21dec59a 100644 --- a/src/header.c +++ b/src/header.c @@ -313,13 +313,13 @@ wimlib_print_header(const WIMStruct *wim) tprintf(T("Part Number = %hu\n"), hdr->part_number); tprintf(T("Total Parts = %hu\n"), hdr->total_parts); tprintf(T("Image Count = %u\n"), hdr->image_count); - tprintf(T("Blob Table Size = %"PRIu64"\n"), + tprintf(T("Blob Table Size = %"PRIu64"\n"), (u64)hdr->blob_table_reshdr.size_in_wim); - tprintf(T("Blob Table Flags = 0x%hhx\n"), + tprintf(T("Blob Table Flags = 0x%hhx\n"), (u8)hdr->blob_table_reshdr.flags); - tprintf(T("Blob Table Offset = %"PRIu64"\n"), + tprintf(T("Blob Table Offset = %"PRIu64"\n"), hdr->blob_table_reshdr.offset_in_wim); - tprintf(T("Blob Table Original_size = %"PRIu64"\n"), + tprintf(T("Blob Table Original_size = %"PRIu64"\n"), hdr->blob_table_reshdr.uncompressed_size); tprintf(T("XML Data Size = %"PRIu64"\n"), (u64)hdr->xml_data_reshdr.size_in_wim); diff --git a/src/inode.c b/src/inode.c index 0cf092d6..545a940c 100644 --- a/src/inode.c +++ b/src/inode.c @@ -438,7 +438,7 @@ inode_has_named_data_stream(const struct wim_inode *inode) * * If @force is %false: * If any of the needed blobs do not exist in @table, return - * WIMLIB_ERR_RESOURCE_NOT_FOUND and leave the inode unmodified. + * WIMLIB_ERR_RESOURCE_NOT_FOUND. * If @force is %true: * If any of the needed blobs do not exist in @table, allocate new blob * descriptors for them and insert them into @table. This does not, of @@ -453,14 +453,13 @@ int inode_resolve_streams(struct wim_inode *inode, struct blob_table *table, bool force) { - struct blob_descriptor *blobs[inode->i_num_streams]; - for (unsigned i = 0; i < inode->i_num_streams; i++) { + struct wim_inode_stream *strm = &inode->i_streams[i]; - if (inode->i_streams[i].stream_resolved) + if (strm->stream_resolved) continue; - const u8 *hash = stream_hash(&inode->i_streams[i]); + const u8 *hash = stream_hash(strm); struct blob_descriptor *blob = NULL; if (!is_zero_hash(hash)) { @@ -475,14 +474,8 @@ inode_resolve_streams(struct wim_inode *inode, struct blob_table *table, blob_table_insert(table, blob); } } - blobs[i] = blob; - } - - for (unsigned i = 0; i < inode->i_num_streams; i++) { - if (!inode->i_streams[i].stream_resolved) { - inode->i_streams[i]._stream_blob = blobs[i]; - inode->i_streams[i].stream_resolved = 1; - } + strm->_stream_blob = blob; + strm->stream_resolved = 1; } return 0; } -- 2.43.0