]> wimlib.net Git - wimlib/blobdiff - src/write.c
write.c: do not remove empty blobs (not possible anymore)
[wimlib] / src / write.c
index a71359420aed78ade13a05b0f2523c645974e1c2..4ee29defa4f5ca4e10b33f79326740bec3091473 100644 (file)
@@ -52,9 +52,7 @@
 #include "wimlib/progress.h"
 #include "wimlib/resource.h"
 #include "wimlib/solid.h"
-#ifdef __WIN32__
-#  include "wimlib/win32.h" /* win32_rename_replacement() */
-#endif
+#include "wimlib/win32.h" /* win32_rename_replacement() */
 #include "wimlib/write.h"
 #include "wimlib/xml.h"
 
@@ -279,7 +277,7 @@ struct write_blobs_progress_data {
        wimlib_progress_func_t progfunc;
        void *progctx;
        union wimlib_progress_info progress;
-       uint64_t next_progress;
+       u64 next_progress;
 };
 
 static int
@@ -292,7 +290,7 @@ do_write_blobs_progress(struct write_blobs_progress_data *progress_data,
        if (discarded) {
                progress->write_streams.total_bytes -= complete_size;
                progress->write_streams.total_streams -= complete_count;
-               if (progress_data->next_progress != ~(uint64_t)0 &&
+               if (progress_data->next_progress != ~(u64)0 &&
                    progress_data->next_progress > progress->write_streams.total_bytes)
                {
                        progress_data->next_progress = progress->write_streams.total_bytes;
@@ -312,7 +310,7 @@ do_write_blobs_progress(struct write_blobs_progress_data *progress_data,
                        return ret;
 
                if (progress_data->next_progress == progress->write_streams.total_bytes) {
-                       progress_data->next_progress = ~(uint64_t)0;
+                       progress_data->next_progress = ~(u64)0;
                } else {
                        /* Handle rate-limiting of messages  */
 
@@ -797,7 +795,7 @@ write_blob_uncompressed(struct blob_descriptor *blob, struct filedes *out_fd)
        if (filedes_seek(out_fd, begin_offset) == -1)
                return 0;
 
-       ret = extract_full_blob_to_fd(blob, out_fd);
+       ret = extract_blob_to_fd(blob, out_fd);
        if (ret) {
                /* Error reading the uncompressed data.  */
                if (out_fd->offset == begin_offset &&
@@ -1335,19 +1333,13 @@ finish_remaining_chunks(struct write_blobs_ctx *ctx)
 }
 
 static void
-remove_empty_blobs(struct list_head *blob_list)
+validate_blob_list(struct list_head *blob_list)
 {
-       struct blob_descriptor *blob, *tmp;
+       struct blob_descriptor *blob;
 
-       list_for_each_entry_safe(blob, tmp, blob_list, write_blobs_list) {
+       list_for_each_entry(blob, blob_list, write_blobs_list) {
                wimlib_assert(blob->will_be_in_output_wim);
-               if (blob->size == 0) {
-                       list_del(&blob->write_blobs_list);
-                       blob->out_reshdr.offset_in_wim = 0;
-                       blob->out_reshdr.size_in_wim = 0;
-                       blob->out_reshdr.uncompressed_size = 0;
-                       blob->out_reshdr.flags = reshdr_flags_for_blob(blob);
-               }
+               wimlib_assert(blob->size != 0);
        }
 }
 
@@ -1506,7 +1498,7 @@ write_blob_list(struct list_head *blob_list,
                                (WRITE_RESOURCE_FLAG_SOLID |
                                 WRITE_RESOURCE_FLAG_PIPABLE));
 
-       remove_empty_blobs(blob_list);
+       validate_blob_list(blob_list);
 
        if (list_empty(blob_list))
                return 0;
@@ -1617,13 +1609,11 @@ write_blob_list(struct list_head *blob_list,
        /* Read the list of blobs needing to be compressed, using the specified
         * callbacks to execute processing of the data.  */
 
-       struct read_blob_list_callbacks cbs = {
-               .begin_blob             = write_blob_begin_read,
-               .begin_blob_ctx         = &ctx,
-               .consume_chunk          = write_blob_process_chunk,
-               .consume_chunk_ctx      = &ctx,
-               .end_blob               = write_blob_end_read,
-               .end_blob_ctx           = &ctx,
+       struct read_blob_callbacks cbs = {
+               .begin_blob     = write_blob_begin_read,
+               .consume_chunk  = write_blob_process_chunk,
+               .end_blob       = write_blob_end_read,
+               .ctx            = &ctx,
        };
 
        ret = read_blob_list(blob_list,
@@ -1691,16 +1681,6 @@ write_file_data_blobs(WIMStruct *wim,
 
        write_resource_flags = write_flags_to_resource_flags(write_flags);
 
-       /* wimlib v1.7.0: create a solid WIM file by default if the WIM version
-        * has been set to WIM_VERSION_SOLID and at least one blob in the WIM's
-        * blob table is located in a solid resource (may be the same WIM, or a
-        * different one in the case of export).  */
-       if (wim->out_hdr.wim_version == WIM_VERSION_SOLID &&
-           wim_has_solid_resources(wim))
-       {
-               write_resource_flags |= WRITE_RESOURCE_FLAG_SOLID;
-       }
-
        if (write_resource_flags & WRITE_RESOURCE_FLAG_SOLID) {
                out_chunk_size = wim->out_solid_chunk_size;
                out_ctype = wim->out_solid_compression_type;
@@ -1759,6 +1739,13 @@ write_wim_resource_from_buffer(const void *buf,
        int ret;
        struct blob_descriptor blob;
 
+       if (unlikely(buf_size == 0)) {
+               zero_reshdr(out_reshdr);
+               if (hash_ret)
+                       copy_hash(hash_ret, zero_hash);
+               return 0;
+       }
+
        blob_set_is_located_in_attached_buffer(&blob, (void *)buf, buf_size);
        sha1_buffer(buf, buf_size, blob.hash);
        blob.unhashed = 0;
@@ -2627,6 +2614,15 @@ write_pipable_wim(WIMStruct *wim, int image, int write_flags,
         * finish_write().  */
 }
 
+static bool
+should_default_to_solid_compression(WIMStruct *wim, int write_flags)
+{
+       return wim->out_hdr.wim_version == WIM_VERSION_SOLID &&
+               !(write_flags & (WIMLIB_WRITE_FLAG_SOLID |
+                                WIMLIB_WRITE_FLAG_PIPABLE)) &&
+               wim_has_solid_resources(wim);
+}
+
 /* Write a standalone WIM or split WIM (SWM) part to a new file or to a file
  * descriptor.  */
 int
@@ -2714,6 +2710,12 @@ write_wim_part(WIMStruct *wim,
        else
                wim->out_hdr.wim_version = WIM_VERSION_DEFAULT;
 
+       /* Default to solid compression if it is valid in the chosen WIM file
+        * format and the WIMStruct references any solid resources.  This is
+        * useful when exporting an image from a solid WIM.  */
+       if (should_default_to_solid_compression(wim, write_flags))
+               write_flags |= WIMLIB_WRITE_FLAG_SOLID;
+
        /* Set the header flags.  */
        wim->out_hdr.flags = (wim->hdr.flags & (WIM_HDR_FLAG_RP_FIX |
                                                WIM_HDR_FLAG_READONLY));
@@ -2741,9 +2743,9 @@ write_wim_part(WIMStruct *wim,
        if (write_flags & WIMLIB_WRITE_FLAG_RETAIN_GUID)
                guid = wim->hdr.guid;
        if (guid)
-               memcpy(wim->out_hdr.guid, guid, WIMLIB_GUID_LEN);
+               copy_guid(wim->out_hdr.guid, guid);
        else
-               randomize_byte_array(wim->out_hdr.guid, WIMLIB_GUID_LEN);
+               generate_guid(wim->out_hdr.guid);
 
        /* Set the part number and total parts.  */
        wim->out_hdr.part_number = part_number;
@@ -2991,6 +2993,12 @@ overwrite_wim_inplace(WIMStruct *wim, int write_flags, unsigned num_threads)
        if (write_flags & WIMLIB_WRITE_FLAG_SOLID)
                wim->out_hdr.wim_version = WIM_VERSION_SOLID;
 
+       /* Default to solid compression if it is valid in the chosen WIM file
+        * format and the WIMStruct references any solid resources.  This is
+        * useful when updating a solid WIM.  */
+       if (should_default_to_solid_compression(wim, write_flags))
+               write_flags |= WIMLIB_WRITE_FLAG_SOLID;
+
        /* Set additional flags for overwrite.  */
        write_flags |= WIMLIB_WRITE_FLAG_OVERWRITE |
                       WIMLIB_WRITE_FLAG_STREAMS_OK;