]> wimlib.net Git - wimlib/blobdiff - include/wimlib/blob_table.h
extract.c: simplify extract_from_tmpfile()
[wimlib] / include / wimlib / blob_table.h
index c07acfadab7d1602410457a01dd5cc6af19eca2e..6dbbe55a7e9c9b489e39c9eeb6ebb28bb8c8650b 100644 (file)
@@ -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
@@ -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);
@@ -329,26 +352,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 +361,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,10 +383,24 @@ 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,