struct lte_overwrite_prepare_args {
WIMStruct *wim;
- struct list_head *stream_list;
off_t end_offset;
+ struct list_head *stream_list;
};
static int lte_overwrite_prepare(struct lookup_table_entry *lte, void *arg)
{
struct lte_overwrite_prepare_args *args = arg;
- if (lte->resource_entry.offset +
- lte->resource_entry.size > args->end_offset)
+ if (lte->resource_location == RESOURCE_IN_WIM &&
+ lte->wim == args->wim &&
+ lte->resource_entry.offset + lte->resource_entry.size > args->end_offset)
{
ERROR("The following resource is after the XML data:");
print_lookup_table_entry(lte);
struct list_head *stream_list)
{
struct lte_overwrite_prepare_args args = {
- .wim = wim,
+ .wim = wim,
+ .end_offset = end_offset,
.stream_list = stream_list,
- .end_offset = end_offset,
};
return for_lookup_table_entry(wim->lookup_table,
lte_overwrite_prepare, &args);
}
-static int dentry_find_streams_to_write(struct dentry *dentry,
- void *wim)
+static int inode_find_streams_to_write(struct inode *inode,
+ struct lookup_table *table,
+ struct list_head *stream_list)
{
- WIMStruct *w = wim;
- struct list_head *stream_list = w->private;
struct lookup_table_entry *lte;
- for (unsigned i = 0; i <= dentry->d_inode->num_ads; i++) {
- lte = inode_stream_lte(dentry->d_inode, i, w->lookup_table);
- if (lte && ++lte->out_refcnt == 1)
- list_add_tail(<e->staging_list, stream_list);
+ for (unsigned i = 0; i <= inode->num_ads; i++) {
+ lte = inode_stream_lte(inode, i, table);
+ if (lte) {
+ if (lte->out_refcnt == 0)
+ list_add_tail(<e->staging_list, stream_list);
+ lte->out_refcnt += inode->link_count;
+ }
}
return 0;
}
-static int find_streams_to_write(WIMStruct *w)
+static int image_find_streams_to_write(WIMStruct *w)
{
- return for_dentry_in_tree(wim_root_dentry(w),
- dentry_find_streams_to_write, w);
+ struct inode *inode;
+ struct hlist_node *cur;
+ struct hlist_head *inode_list;
+
+ inode_list = &wim_get_current_image_metadata(w)->inode_list;
+ hlist_for_each_entry(inode, cur, inode_list, hlist) {
+ inode_find_streams_to_write(inode, w->lookup_table,
+ (struct list_head*)w->private);
+ }
+ return 0;
}
static int write_wim_streams(WIMStruct *w, int image, int write_flags,
for_lookup_table_entry(w->lookup_table, lte_zero_out_refcnt, NULL);
LIST_HEAD(stream_list);
w->private = &stream_list;
- for_image(w, image, find_streams_to_write);
+ for_image(w, image, image_find_streams_to_write);
return write_stream_list(&stream_list, w->out_fp,
wimlib_get_compression_type(w), write_flags,
num_threads, progress_func);
return ret;
}
+static bool any_images_modified(WIMStruct *w)
+{
+ for (int i = 0; i < w->hdr.image_count; i++)
+ if (w->image_metadata[i].modified)
+ return true;
+ return false;
+}
+
/*
* Overwrite a WIM, possibly appending streams to it.
*
*/
static int overwrite_wim_inplace(WIMStruct *w, int write_flags,
unsigned num_threads,
- wimlib_progress_func_t progress_func,
- int modified_image_idx)
+ wimlib_progress_func_t progress_func)
{
int ret;
struct list_head stream_list;
off_t old_wim_end;
+ bool found_modified_image;
DEBUG("Overwriting `%s' in-place", w->filename);
else
old_wim_end = w->hdr.xml_res_entry.offset + w->hdr.xml_res_entry.size;
-
- if (modified_image_idx == w->hdr.image_count && !w->deletion_occurred) {
+ if (!w->deletion_occurred && !any_images_modified(w)) {
/* If no images have been modified and no images have been
* deleted, a new lookup table does not need to be written. */
old_wim_end = w->hdr.lookup_table_res_entry.offset +
DEBUG("No new streams were added");
}
- for (int i = modified_image_idx; i < w->hdr.image_count; i++) {
- select_wim_image(w, i + 1);
- ret = write_metadata_resource(w);
- if (ret != 0)
- goto out_ftruncate;
+ found_modified_image = false;
+ for (int i = 0; i < w->hdr.image_count; i++) {
+ if (!found_modified_image)
+ found_modified_image = w->image_metadata[i].modified;
+ if (found_modified_image) {
+ select_wim_image(w, i + 1);
+ ret = write_metadata_resource(w);
+ if (ret != 0)
+ goto out_ftruncate;
+ }
}
write_flags |= WIMLIB_WRITE_FLAG_REUSE_INTEGRITY_TABLE;
ret = finish_write(w, WIMLIB_ALL_IMAGES, write_flags,
if ((!w->deletion_occurred || (write_flags & WIMLIB_WRITE_FLAG_SOFT_DELETE))
&& !(write_flags & WIMLIB_WRITE_FLAG_REBUILD))
{
- int i;
- int modified_image_idx;
int ret;
-
- for (i = 0; i < w->hdr.image_count && !w->image_metadata[i].modified; i++)
- ;
- modified_image_idx = i;
- for (; i < w->hdr.image_count && w->image_metadata[i].modified; i++)
- ;
- if (i == w->hdr.image_count) {
- ret = overwrite_wim_inplace(w, write_flags, num_threads,
- progress_func,
- modified_image_idx);
- if (ret == WIMLIB_ERR_RESOURCE_ORDER)
- WARNING("Falling back to re-building entire WIM");
- else
- return ret;
- }
+ ret = overwrite_wim_inplace(w, write_flags, num_threads,
+ progress_func);
+ if (ret == WIMLIB_ERR_RESOURCE_ORDER)
+ WARNING("Falling back to re-building entire WIM");
+ else
+ return ret;
}
return overwrite_wim_via_tmpfile(w, write_flags, num_threads,
progress_func);