From: Eric Biggers Date: Mon, 19 Oct 2015 00:39:36 +0000 (-0500) Subject: Delay xml_update_image_info() until write X-Git-Tag: v1.8.3~36 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=52c44c6a506cdfae17fd5fd5c6611622d342c128;hp=ae7d142ac04cf51ba134750f3338f43af285a433 Delay xml_update_image_info() until write wimlib_update_image() should not be walking the entire image's directory tree on every call. --- diff --git a/include/wimlib/metadata.h b/include/wimlib/metadata.h index 845d3954..f9307a67 100644 --- a/include/wimlib/metadata.h +++ b/include/wimlib/metadata.h @@ -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 */ diff --git a/src/mount_image.c b/src/mount_image.c index 7750a4ee..bca9e439 100644 --- a/src/mount_image.c +++ b/src/mount_image.c @@ -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; diff --git a/src/update_image.c b/src/update_image.c index 66e5ed8d..15458a12 100644 --- a/src/update_image.c +++ b/src/update_image.c @@ -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) diff --git a/src/write.c b/src/write.c index 0a899945..23dda573 100644 --- a/src/write.c +++ b/src/write.c @@ -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; diff --git a/src/xml.c b/src/xml.c index baf51941..8280e8ed 100644 --- 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; }