Delay xml_update_image_info() until write
authorEric Biggers <ebiggers3@gmail.com>
Mon, 19 Oct 2015 00:39:36 +0000 (19:39 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Mon, 19 Oct 2015 02:01:13 +0000 (21:01 -0500)
wimlib_update_image() should not be walking the entire image's directory
tree on every call.

include/wimlib/metadata.h
src/mount_image.c
src/update_image.c
src/write.c
src/xml.c

index 845d395..f9307a6 100644 (file)
@@ -36,6 +36,10 @@ struct wim_image_metadata {
         * into the WIMStruct's blob table.  This list is appended to when files
         * are scanned for inclusion in this WIM image.  */
        struct list_head unhashed_blobs;
+
+       /* Are the filecount/bytecount stats (in the XML info) out of date for
+        * this image?  */
+       bool stats_outdated;
 };
 
 /* Retrieve the metadata of the image in @wim currently selected with
@@ -82,11 +86,12 @@ is_image_unchanged_from_wim(const struct wim_image_metadata *imd,
 
 /* Mark the metadata for the specified WIM image "dirty" following changes to
  * the image's directory tree.  This records that the metadata no longer matches
- * the version in the WIM file (if any).  */
+ * the version in the WIM file (if any) and that its stats are out of date.  */
 static inline void
 mark_image_dirty(struct wim_image_metadata *imd)
 {
        blob_release_location(imd->metadata_blob);
+       imd->stats_outdated = true;
 }
 
 /* Iterate over each inode in a WIM image  */
index 7750a4e..bca9e43 100644 (file)
@@ -1116,7 +1116,6 @@ commit_image(struct wimfs_context *ctx, int unmount_flags, mqd_t mq)
        }
        INIT_LIST_HEAD(&ctx->orig_blob_list);
        delete_empty_blobs(ctx);
-       xml_update_image_info(ctx->wim, ctx->wim->current_image);
        mark_image_dirty(wim_get_current_image_metadata(ctx->wim));
 
        write_flags = 0;
index 66e5ed8..15458a1 100644 (file)
@@ -64,7 +64,6 @@
 #include "wimlib/metadata.h"
 #include "wimlib/paths.h"
 #include "wimlib/progress.h"
-#include "wimlib/xml.h"
 
 /* Saved specification of a "primitive" update operation that was performed.  */
 struct update_primitive {
@@ -1435,11 +1434,6 @@ wimlib_update_image(WIMStruct *wim,
 
        mark_image_dirty(imd);
 
-       /* Statistics about the WIM image, such as the numbers of files and
-        * directories, may have changed.  Call xml_update_image_info() to
-        * recalculate these statistics. */
-       xml_update_image_info(wim, image);
-
        for (size_t i = 0; i < num_cmds; i++)
                if (cmds_copy[i].op == WIMLIB_UPDATE_OP_ADD &&
                    cmds_copy[i].add.add_flags & WIMLIB_ADD_FLAG_RPFIX)
index 0a89994..23dda57 100644 (file)
@@ -2639,6 +2639,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 +2805,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.  */
@@ -3130,6 +3154,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;
index baf5194..8280e8e 100644 (file)
--- a/src/xml.c
+++ b/src/xml.c
@@ -716,7 +716,6 @@ xml_update_image_info(WIMStruct *wim, int image)
                xmlFreeNode(totalbytes_node);
                xmlFreeNode(hardlinkbytes_node);
                xmlFreeNode(lastmodificationtime_node);
-               WARNING("Failed to update image information!");
                return WIMLIB_ERR_NOMEM;
        }