wimlib_update_image() should not be walking the entire image's directory
tree on every call.
* 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;
* 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
};
/* Retrieve the metadata of the image in @wim currently selected with
/* 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
/* 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);
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 */
}
/* Iterate over each inode in a WIM image */
}
INIT_LIST_HEAD(&ctx->orig_blob_list);
delete_empty_blobs(ctx);
}
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;
mark_image_dirty(wim_get_current_image_metadata(ctx->wim));
write_flags = 0;
#include "wimlib/metadata.h"
#include "wimlib/paths.h"
#include "wimlib/progress.h"
#include "wimlib/metadata.h"
#include "wimlib/paths.h"
#include "wimlib/progress.h"
/* Saved specification of a "primitive" update operation that was performed. */
struct update_primitive {
/* Saved specification of a "primitive" update operation that was performed. */
struct update_primitive {
- /* 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)
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)
wim_has_solid_resources(wim);
}
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
/* Write a standalone WIM or split WIM (SWM) part to a new file or to a file
* descriptor. */
int
wim->out_hdr.boot_idx = 1;
}
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. */
/* Set up the output file descriptor. */
if (write_flags & WIMLIB_WRITE_FLAG_FILE_DESCRIPTOR) {
/* File descriptor was explicitly provided. */
wimlib_assert(list_empty(&blob_list));
}
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;
ret = open_wim_writable(wim, wim->filename, O_RDWR);
if (ret)
goto out;
xmlFreeNode(totalbytes_node);
xmlFreeNode(hardlinkbytes_node);
xmlFreeNode(lastmodificationtime_node);
xmlFreeNode(totalbytes_node);
xmlFreeNode(hardlinkbytes_node);
xmlFreeNode(lastmodificationtime_node);
- WARNING("Failed to update image information!");
return WIMLIB_ERR_NOMEM;
}
return WIMLIB_ERR_NOMEM;
}