]> wimlib.net Git - wimlib/blobdiff - src/write.c
write.c: compaction bug fix
[wimlib] / src / write.c
index 0a899945620acd59f04ddc6239fb2d37abdebd91..ab44f91b411028e2ff5311842f900b781a1ea3dd 100644 (file)
@@ -1340,17 +1340,6 @@ validate_blob_list(struct list_head *blob_list)
        }
 }
 
-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 void
 init_done_with_file_info(struct list_head *blob_list)
 {
@@ -2639,6 +2628,25 @@ should_default_to_solid_compression(WIMStruct *wim, int write_flags)
                wim_has_solid_resources(wim);
 }
 
+/* Update the images' filecount/bytecount stats (in the XML info) to take into
+ * account any recent modifications.  */
+static int
+update_image_stats(WIMStruct *wim)
+{
+       if (!wim_has_metadata(wim))
+               return 0;
+       for (int i = 0; i < wim->hdr.image_count; i++) {
+               struct wim_image_metadata *imd = wim->image_metadata[i];
+               if (imd->stats_outdated) {
+                       int ret = xml_update_image_info(wim, i + 1);
+                       if (ret)
+                               return ret;
+                       imd->stats_outdated = false;
+               }
+       }
+       return 0;
+}
+
 /* Write a standalone WIM or split WIM (SWM) part to a new file or to a file
  * descriptor.  */
 int
@@ -2786,6 +2794,11 @@ write_wim_part(WIMStruct *wim,
                        wim->out_hdr.boot_idx = 1;
        }
 
+       /* Update image stats if needed.  */
+       ret = update_image_stats(wim);
+       if (ret)
+               return ret;
+
        /* Set up the output file descriptor.  */
        if (write_flags & WIMLIB_WRITE_FLAG_FILE_DESCRIPTOR) {
                /* File descriptor was explicitly provided.  */
@@ -2937,6 +2950,20 @@ check_resource_offsets(WIMStruct *wim, off_t end_offset)
        return 0;
 }
 
+static int
+free_blob_if_invalidated(struct blob_descriptor *blob, void *_wim)
+{
+       const WIMStruct *wim = _wim;
+
+       if (!blob->will_be_in_output_wim &&
+           blob->blob_location == BLOB_IN_WIM && blob->rdesc->wim == wim)
+       {
+               blob_table_unlink(wim->blob_table, blob);
+               free_blob_descriptor(blob);
+       }
+       return 0;
+}
+
 /*
  * Overwrite a WIM, possibly appending new resources to it.
  *
@@ -3053,6 +3080,11 @@ overwrite_wim_inplace(WIMStruct *wim, int write_flags, unsigned num_threads)
                if (ret)
                        goto out;
 
+               /* Prevent new files from being deduplicated with existing blobs
+                * in the WIM that we haven't decided to write.  Such blobs will
+                * be overwritten during the compaction.  */
+               for_blob_in_table(wim->blob_table, free_blob_if_invalidated, wim);
+
                if (wim_has_metadata(wim)) {
                        /* Add existing metadata resources to be compacted along
                         * with the file resources.  */
@@ -3130,6 +3162,11 @@ overwrite_wim_inplace(WIMStruct *wim, int write_flags, unsigned num_threads)
                        wimlib_assert(list_empty(&blob_list));
        }
 
+       /* Update image stats if needed.  */
+       ret = update_image_stats(wim);
+       if (ret)
+               goto out;
+
        ret = open_wim_writable(wim, wim->filename, O_RDWR);
        if (ret)
                goto out;