X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=include%2Fwimlib%2Fblob_table.h;h=c5295820a744b12b19cfe3943d254adad10fd89e;hp=c07acfadab7d1602410457a01dd5cc6af19eca2e;hb=719a063c87e3abab99b0fb53ebc80223fbf33123;hpb=3de1ec66f778edda19865482d685bc6f4e17faf7 diff --git a/include/wimlib/blob_table.h b/include/wimlib/blob_table.h index c07acfad..c5295820 100644 --- a/include/wimlib/blob_table.h +++ b/include/wimlib/blob_table.h @@ -12,7 +12,7 @@ enum blob_location { /* The blob's data does not exist. This is a temporary state only. */ BLOB_NONEXISTENT = 0, - /* The blob's data is located in a WIM resource identified by the + /* The blob's data is available in the WIM resource identified by the * `struct wim_resource_descriptor' pointed to by @rdesc. * @offset_in_res identifies the offset at which this particular blob * begins in the uncompressed data of the resource. */ @@ -35,9 +35,8 @@ enum blob_location { #ifdef WITH_NTFS_3G /* The blob's data is available as the contents of an NTFS attribute - * accessible through libntfs-3g. The attribute is identified by - * volume, path to an inode, attribute name, and attribute type. - * @ntfs_loc points to a structure containing this information. */ + * accessible through libntfs-3g. @ntfs_loc points to a structure which + * identifies the attribute. */ BLOB_IN_NTFS_VOLUME, #endif @@ -55,16 +54,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. @@ -74,35 +74,22 @@ struct blob_descriptor { /* List node for a hash bucket of the blob table */ struct hlist_node hash_list; - /* Uncompressed size of this blob */ + /* + * Uncompressed size of this blob. + * + * In most cases we are now enforcing that this is nonzero; i.e. an + * empty stream will have "no blob" rather than "an empty blob". The + * exceptions are: + * + * - blob descriptors with 'blob_location == BLOB_NONEXISTENT', + * e.g. placeholder entries for new metadata resources or for + * blobs required for pipable WIM extraction. In these cases the + * size is not meaningful information anyway. + * - blob descriptors with 'blob_location == BLOB_IN_STAGING_FILE' + * can vary their size over time, including to 0. + */ u64 size; - /* One of the `enum blob_location' values documented above. */ - u32 blob_location : 4; - - /* Blob flags (WIM_RESHDR_FLAG_*) */ - u32 flags : 8; - - /* 1 iff the SHA-1 message digest of this blob is unknown. */ - u32 unhashed : 1; - - /* Temporary fields used when writing blobs; set as documented for - * prepare_blob_list_for_write(). */ - u32 unique_size : 1; - u32 will_be_in_output_wim : 1; - - /* Set to 1 if this blob represents a metadata resource that has been - * changed. In such cases, the hash cannot be used to verify the data - * if the metadata resource is read again. (This could be avoided if we - * used separate fields for input/output checksum, but most blobs - * wouldn't need this.) */ - u32 dont_check_metadata_hash : 1; - - u32 may_send_done_with_file : 1; - - /* Only used by wimlib_export_image() */ - u32 was_exported : 1; - union { /* * For unhashed == 0: 'hash' is the SHA-1 message digest of the @@ -121,7 +108,7 @@ struct blob_descriptor { struct wim_inode *back_inode; u32 back_stream_id; }; - }; + } _packed_attribute; /* union is SHA1_HASH_SIZE bytes */ /* Number of times this blob is referenced by file streams in WIM * images. See blob_decrement_refcnt() for information about the @@ -147,10 +134,36 @@ struct blob_descriptor { #ifdef WITH_FUSE /* Number of open file descriptors to this blob during a FUSE mount of - * the containing image. */ + * a WIM image. */ u16 num_opened_fds; #endif + /* One of the `enum blob_location' values documented above. */ + u16 blob_location : 4; + + /* 1 iff this blob contains "metadata" as opposed to data. */ + u16 is_metadata : 1; + + /* 1 iff the SHA-1 message digest of this blob is unknown. */ + u16 unhashed : 1; + + /* Temporary fields used when writing blobs; set as documented for + * prepare_blob_list_for_write(). */ + u16 unique_size : 1; + u16 will_be_in_output_wim : 1; + + /* Set to 1 if this blob represents a metadata resource that has been + * changed. In such cases, the hash cannot be used to verify the data + * if the metadata resource is read again. (This could be avoided if we + * used separate fields for input/output checksum, but most blobs + * wouldn't need this.) */ + u16 dont_check_metadata_hash : 1; + + u16 may_send_done_with_file : 1; + + /* Only used by wimlib_export_image() */ + u16 was_exported : 1; + /* Specification of where this blob's data is located. Which member of * this union is valid is determined by the @blob_location field. */ union { @@ -158,37 +171,48 @@ struct blob_descriptor { struct { struct wim_resource_descriptor *rdesc; u64 offset_in_res; + + /* Links together blobs that share the same underlying + * WIM resource. The head is rdesc->blob_list. */ + struct list_head rdesc_node; }; - /* BLOB_IN_FILE_ON_DISK - * BLOB_IN_WINNT_FILE_ON_DISK - * BLOB_WIN32_ENCRYPTED */ struct { - tchar *file_on_disk; - struct wim_inode *file_inode; - }; - /* BLOB_IN_ATTACHED_BUFFER */ - void *attached_buffer; + union { -#ifdef WITH_FUSE - /* BLOB_IN_STAGING_FILE */ - struct { - char *staging_file_name; - int staging_dir_fd; - }; -#endif + /* BLOB_IN_FILE_ON_DISK + * BLOB_IN_WINNT_FILE_ON_DISK + * BLOB_WIN32_ENCRYPTED */ + struct { + tchar *file_on_disk; + struct wim_inode *file_inode; + #ifdef __WIN32__ + u64 sort_key; + #endif + }; -#ifdef WITH_NTFS_3G - /* BLOB_IN_NTFS_VOLUME */ - struct ntfs_location *ntfs_loc; -#endif - }; + /* BLOB_IN_ATTACHED_BUFFER */ + void *attached_buffer; + + #ifdef WITH_FUSE + /* BLOB_IN_STAGING_FILE */ + struct { + char *staging_file_name; + int staging_dir_fd; + }; + #endif + + #ifdef WITH_NTFS_3G + /* BLOB_IN_NTFS_VOLUME */ + struct ntfs_location *ntfs_loc; + #endif + }; - /* Links together blobs that share the same underlying WIM resource. - * The head is the 'blob_list' member of - * 'struct wim_resource_descriptor'. */ - struct list_head rdesc_node; + /* List link for per-WIM-image list of unhashed blobs */ + struct list_head unhashed_list; + }; + }; /* Temporary fields */ union { @@ -253,10 +277,6 @@ struct blob_descriptor { /* Links original list of blobs in the read-write mounted image. */ struct list_head orig_blob_list; }; - - /* Links blobs that are still unhashed after being been added to a WIM. - */ - struct list_head unhashed_list; }; extern struct blob_table * @@ -279,12 +299,15 @@ extern struct blob_descriptor * new_blob_descriptor(void) _malloc_attribute; extern struct blob_descriptor * -clone_blob_descriptor(const struct blob_descriptor *blob) - _malloc_attribute; +clone_blob_descriptor(const struct blob_descriptor *blob) _malloc_attribute; extern void -blob_decrement_refcnt(struct blob_descriptor *blob, - struct blob_table *table); +blob_decrement_refcnt(struct blob_descriptor *blob, struct blob_table *table); + +extern void +blob_subtract_refcnt(struct blob_descriptor *blob, struct blob_table *table, + u32 count); + #ifdef WITH_FUSE extern void blob_decrement_num_opened_fds(struct blob_descriptor *blob); @@ -318,8 +341,7 @@ blob_to_wimlib_resource_entry(const struct blob_descriptor *blob, struct wimlib_resource_entry *wentry); extern int -sort_blob_list(struct list_head *blob_list, - size_t list_head_offset, +sort_blob_list(struct list_head *blob_list, size_t list_head_offset, int (*compar)(const void *, const void*)); extern int @@ -329,26 +351,8 @@ sort_blob_list_by_sequential_order(struct list_head *blob_list, extern int cmp_blobs_by_sequential_order(const void *p1, const void *p2); -static inline bool -blob_is_in_solid_wim_resource(const struct blob_descriptor *blob) -{ - return blob->blob_location == BLOB_IN_WIM && - blob->size != blob->rdesc->uncompressed_size; -} - -static inline bool -blob_is_in_file(const struct blob_descriptor *blob) -{ - return blob->blob_location == BLOB_IN_FILE_ON_DISK -#ifdef __WIN32__ - || blob->blob_location == BLOB_IN_WINNT_FILE_ON_DISK - || blob->blob_location == BLOB_WIN32_ENCRYPTED -#endif - ; -} - static inline const struct blob_extraction_target * -blob_extraction_targets(struct blob_descriptor *blob) +blob_extraction_targets(const struct blob_descriptor *blob) { if (blob->out_refcnt <= ARRAY_LEN(blob->inline_blob_extraction_targets)) return blob->inline_blob_extraction_targets; @@ -356,13 +360,19 @@ blob_extraction_targets(struct blob_descriptor *blob) return blob->blob_extraction_targets; } +/* + * Declare that the specified blob is located in the specified WIM resource at + * the specified offset. The caller is expected to set blob->size if required. + */ static inline void blob_set_is_located_in_wim_resource(struct blob_descriptor *blob, - struct wim_resource_descriptor *rdesc) + struct wim_resource_descriptor *rdesc, + u64 offset_in_res) { blob->blob_location = BLOB_IN_WIM; blob->rdesc = rdesc; list_add_tail(&blob->rdesc_node, &rdesc->blob_list); + blob->offset_in_res = offset_in_res; } static inline void @@ -372,13 +382,26 @@ blob_unset_is_located_in_wim_resource(struct blob_descriptor *blob) blob->blob_location = BLOB_NONEXISTENT; } +static inline void +blob_set_is_located_in_attached_buffer(struct blob_descriptor *blob, + void *buffer, size_t size) +{ + blob->blob_location = BLOB_IN_ATTACHED_BUFFER; + blob->attached_buffer = buffer; + blob->size = size; +} + extern struct blob_descriptor * new_blob_from_data_buffer(const void *buffer, size_t size, struct blob_table *blob_table); +extern struct blob_descriptor * +after_blob_hashed(struct blob_descriptor *blob, + struct blob_descriptor **back_ptr, + struct blob_table *blob_table); + extern int -hash_unhashed_blob(struct blob_descriptor *blob, - struct blob_table *blob_table, +hash_unhashed_blob(struct blob_descriptor *blob, struct blob_table *blob_table, struct blob_descriptor **blob_ret); extern struct blob_descriptor **