]> wimlib.net Git - wimlib/blobdiff - src/write.c
WIM capture: Share inodes immediately
[wimlib] / src / write.c
index 6a07c44ed3aeae03b20f0ad85e76a7481eff8354..e5dbbdf95c600f377a67f8af4bc96b70f61dc711 100644 (file)
@@ -42,9 +42,6 @@
 #include "dentry.h"
 #include "lookup_table.h"
 #include "xml.h"
-#include "lzx.h"
-#include "xpress.h"
-
 
 #ifdef ENABLE_MULTITHREADED_COMPRESSION
 #  include <pthread.h>
@@ -152,8 +149,9 @@ out:
 
 /*
  * compress_func_t- Pointer to a function to compresses a chunk
- *                  of a WIM resource.  This may be either xpress_compress()
- *                  (xpress-compress.c) or lzx_compress() (lzx-compress.c).
+ *                  of a WIM resource.  This may be either
+ *                  wimlib_xpress_compress() (xpress-compress.c) or
+ *                  wimlib_lzx_compress() (lzx-compress.c).
  *
  * @chunk:       Uncompressed data of the chunk.
  * @chunk_size:          Size of the uncompressed chunk, in bytes.
@@ -179,9 +177,9 @@ compress_func_t
 get_compress_func(int out_ctype)
 {
        if (out_ctype == WIMLIB_COMPRESSION_TYPE_LZX)
-               return lzx_compress;
+               return wimlib_lzx_compress;
        else
-               return xpress_compress;
+               return wimlib_xpress_compress;
 }
 
 /*
@@ -738,6 +736,29 @@ compressor_thread_proc(void *arg)
 }
 #endif /* ENABLE_MULTITHREADED_COMPRESSION */
 
+static void
+do_write_streams_progress(union wimlib_progress_info *progress,
+                         wimlib_progress_func_t progress_func,
+                         uint64_t size_added)
+{
+       progress->write_streams.completed_bytes += size_added;
+       progress->write_streams.completed_streams++;
+       if (progress_func &&
+           progress->write_streams.completed_bytes >= progress->write_streams._private)
+       {
+               progress_func(WIMLIB_PROGRESS_MSG_WRITE_STREAMS,
+                             progress);
+               if (progress->write_streams._private == progress->write_streams.total_bytes) {
+                       progress->write_streams._private = ~0;
+               } else {
+                       progress->write_streams._private =
+                               min(progress->write_streams.total_bytes,
+                                   progress->write_streams.completed_bytes +
+                                       progress->write_streams.total_bytes / 100);
+               }
+       }
+}
+
 static int
 do_write_stream_list(struct list_head *my_resources,
                     FILE *out_fp,
@@ -758,13 +779,10 @@ do_write_stream_list(struct list_head *my_resources,
                if (ret != 0)
                        return ret;
                list_del(&lte->staging_list);
-               progress->write_streams.completed_bytes +=
-                       wim_resource_size(lte);
-               progress->write_streams.completed_streams++;
-               if (progress_func) {
-                       progress_func(WIMLIB_PROGRESS_MSG_WRITE_STREAMS,
-                                     progress);
-               }
+
+               do_write_streams_progress(progress,
+                                         progress_func,
+                                         wim_resource_size(lte));
        }
        return 0;
 }
@@ -1159,14 +1177,8 @@ main_writer_thread_proc(struct list_head *stream_list,
                                                        WIM_RESHDR_FLAG_COMPRESSED;
                                }
 
-                               progress->write_streams.completed_bytes +=
-                                               wim_resource_size(cur_lte);
-                               progress->write_streams.completed_streams++;
-
-                               if (progress_func) {
-                                       progress_func(WIMLIB_PROGRESS_MSG_WRITE_STREAMS,
-                                                     progress);
-                               }
+                               do_write_streams_progress(progress, progress_func,
+                                                         wim_resource_size(cur_lte));
 
                                FREE(cur_chunk_tab);
                                cur_chunk_tab = NULL;
@@ -1395,6 +1407,7 @@ write_stream_list(struct list_head *stream_list, FILE *out_fp,
        progress.write_streams.completed_streams = 0;
        progress.write_streams.num_threads       = num_threads;
        progress.write_streams.compression_type  = out_ctype;
+       progress.write_streams._private          = 0;
 
 #ifdef ENABLE_MULTITHREADED_COMPRESSION
        if (total_compression_bytes >= 1000000 && num_threads != 1)
@@ -1440,24 +1453,29 @@ lte_overwrite_prepare(struct wim_lookup_table_entry *lte, void *arg)
        lte->out_refcnt = lte->refcnt;
        memcpy(&lte->output_resource_entry, &lte->resource_entry,
               sizeof(struct resource_entry));
-       if (!(lte->resource_entry.flags & WIM_RESHDR_FLAG_METADATA)) {
-               wimlib_assert(lte->resource_location != RESOURCE_NONEXISTENT);
+       if (!(lte->resource_entry.flags & WIM_RESHDR_FLAG_METADATA))
                if (lte->resource_location != RESOURCE_IN_WIM || lte->wim != args->wim)
                        list_add(&lte->staging_list, args->stream_list);
-       }
        return 0;
 }
 
 static int
-wim_find_new_streams(WIMStruct *wim, off_t end_offset,
-                    struct list_head *stream_list)
+wim_prepare_streams(WIMStruct *wim, off_t end_offset,
+                   struct list_head *stream_list)
 {
        struct lte_overwrite_prepare_args args = {
                .wim         = wim,
                .end_offset  = end_offset,
                .stream_list = stream_list,
        };
+       int ret;
 
+       for (int i = 0; i < wim->hdr.image_count; i++) {
+               ret = lte_overwrite_prepare(wim->image_metadata[i].metadata_lte,
+                                           &args);
+               if (ret)
+                       return ret;
+       }
        return for_lookup_table_entry(wim->lookup_table,
                                      lte_overwrite_prepare, &args);
 }
@@ -1553,7 +1571,7 @@ finish_write(WIMStruct *w, int image, int write_flags,
        memcpy(&hdr, &w->hdr, sizeof(struct wim_header));
 
        if (!(write_flags & WIMLIB_WRITE_FLAG_NO_LOOKUP_TABLE)) {
-               ret = write_lookup_table(w->lookup_table, out, &hdr.lookup_table_res_entry);
+               ret = write_lookup_table(w, image, &hdr.lookup_table_res_entry);
                if (ret != 0)
                        goto out;
        }
@@ -1868,7 +1886,6 @@ overwrite_wim_inplace(WIMStruct *w, int write_flags,
        int ret;
        struct list_head stream_list;
        off_t old_wim_end;
-       bool found_modified_image;
 
        DEBUG("Overwriting `%"TS"' in-place", w->filename);
 
@@ -1902,7 +1919,7 @@ overwrite_wim_inplace(WIMStruct *w, int write_flags,
                               WIMLIB_WRITE_FLAG_CHECKPOINT_AFTER_XML;
        }
        INIT_LIST_HEAD(&stream_list);
-       ret = wim_find_new_streams(w, old_wim_end, &stream_list);
+       ret = wim_prepare_streams(w, old_wim_end, &stream_list);
        if (ret != 0)
                return ret;
 
@@ -1939,11 +1956,8 @@ overwrite_wim_inplace(WIMStruct *w, int write_flags,
                DEBUG("No new streams were added");
        }
 
-       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) {
+               if (w->image_metadata[i].modified) {
                        select_wim_image(w, i + 1);
                        ret = write_metadata_resource(w);
                        if (ret != 0)