]> wimlib.net Git - wimlib/blobdiff - src/write.c
Set WIM_RESHDR_FLAG_METADATA on XML data
[wimlib] / src / write.c
index ef1e02dba39effd838e25408d0d1e2e6b60b6fa3..bc3d93c2a0681a49e9a13ebb9cec34175895b33b 100644 (file)
 
 #ifdef HAVE_ALLOCA_H
 #include <alloca.h>
+#else
+#include <stdlib.h>
 #endif
 
-
 /* Reopens the FILE* for a WIM read-write. */
 static int reopen_rw(WIMStruct *w)
 {
@@ -79,7 +80,6 @@ static int reopen_rw(WIMStruct *w)
 WIMLIBAPI int wimlib_overwrite(WIMStruct *w, int write_flags,
                               unsigned num_threads)
 {
-       const char *wimfile_name;
        size_t wim_name_len;
        int ret;
 
@@ -87,23 +87,21 @@ WIMLIBAPI int wimlib_overwrite(WIMStruct *w, int write_flags,
                return WIMLIB_ERR_INVALID_PARAM;
 
        write_flags &= ~WIMLIB_WRITE_FLAG_NO_LOOKUP_TABLE;
-
-       wimfile_name = w->filename;
-
-       DEBUG("Replacing WIM file `%s'.", wimfile_name);
-
-       if (!wimfile_name)
+       if (!w->filename)
                return WIMLIB_ERR_NO_FILENAME;
 
+       DEBUG("Replacing WIM file `%s'.", w->filename);
+
        /* Write the WIM to a temporary file. */
        /* XXX should the temporary file be somewhere else? */
-       wim_name_len = strlen(wimfile_name);
+       wim_name_len = strlen(w->filename);
        char tmpfile[wim_name_len + 10];
-       memcpy(tmpfile, wimfile_name, wim_name_len);
+       memcpy(tmpfile, w->filename, wim_name_len);
        randomize_char_array_with_alnum(tmpfile + wim_name_len, 9);
        tmpfile[wim_name_len + 9] = '\0';
 
-       ret = wimlib_write(w, tmpfile, WIM_ALL_IMAGES, write_flags,
+       ret = wimlib_write(w, tmpfile, WIM_ALL_IMAGES,
+                          write_flags | WIMLIB_WRITE_FLAG_FSYNC,
                           num_threads);
        if (ret != 0) {
                ERROR("Failed to write the WIM file `%s'", tmpfile);
@@ -116,27 +114,30 @@ WIMLIBAPI int wimlib_overwrite(WIMStruct *w, int write_flags,
        /* Close the original WIM file that was opened for reading. */
        if (w->fp) {
                if (fclose(w->fp) != 0) {
-                       WARNING("Failed to close the file `%s'", wimfile_name);
+                       WARNING("Failed to close the file `%s'", w->filename);
                }
                w->fp = NULL;
        }
 
-       DEBUG("Renaming `%s' to `%s'", tmpfile, wimfile_name);
+       DEBUG("Renaming `%s' to `%s'", tmpfile, w->filename);
 
        /* Rename the new file to the old file .*/
-       if (rename(tmpfile, wimfile_name) != 0) {
+       if (rename(tmpfile, w->filename) != 0) {
                ERROR_WITH_ERRNO("Failed to rename `%s' to `%s'",
-                                tmpfile, wimfile_name);
-               /* Remove temporary file. */
-               if (unlink(tmpfile) != 0)
-                       ERROR_WITH_ERRNO("Failed to remove `%s'", tmpfile);
-               return WIMLIB_ERR_RENAME;
+                                tmpfile, w->filename);
+               ret = WIMLIB_ERR_RENAME;
+               goto err;
        }
 
        if (write_flags & WIMLIB_WRITE_FLAG_SHOW_PROGRESS)
-               printf("Successfully renamed `%s' to `%s'\n", tmpfile, wimfile_name);
+               printf("Successfully renamed `%s' to `%s'\n", tmpfile, w->filename);
 
        return 0;
+err:
+       /* Remove temporary file. */
+       if (unlink(tmpfile) != 0)
+               ERROR_WITH_ERRNO("Failed to remove `%s'", tmpfile);
+       return ret;
 }
 
 static int check_resource_offset(struct lookup_table_entry *lte, void *arg)
@@ -1071,6 +1072,8 @@ static int main_writer_thread_proc(struct list_head *stream_list,
 #else
        ret = prepare_resource_for_read(next_lte);
 #endif
+       if (ret != 0)
+               goto out;
 
        DEBUG("Initializing buffers for uncompressed "
              "and compressed data (%zu bytes needed)",
@@ -1093,6 +1096,9 @@ static int main_writer_thread_proc(struct list_head *stream_list,
                }
        }
 
+       // This loop is executed until all resources have been written, except
+       // possibly a few that have been added to the @my_resources list for
+       // writing later.
        while (1) {
                // Send chunks to the compressor threads until either (a) there
                // are no more messages available since they were all sent off,
@@ -1258,9 +1264,6 @@ static int main_writer_thread_proc(struct list_head *stream_list,
                        DEBUG2("Complete msg (begin_chunk=%"PRIu64")", msg->begin_chunk);
                        if (msg->begin_chunk == 0) {
                                DEBUG2("Begin chunk tab");
-
-
-
                                if (write_flags & WIMLIB_WRITE_FLAG_SHOW_PROGRESS) {
                                        show_stream_write_progress(&cur_size,
                                                                   &next_size,
@@ -1382,12 +1385,6 @@ out:
 #endif
        if (ret == 0) {
                list_for_each_entry(lte, &my_resources, staging_list) {
-                       ret = write_wim_resource(lte, out_fp,
-                                                out_ctype,
-                                                &lte->output_resource_entry,
-                                                0);
-                       if (ret != 0)
-                               break;
                        if (write_flags & WIMLIB_WRITE_FLAG_SHOW_PROGRESS) {
                                show_stream_write_progress(&cur_size,
                                                           &next_size,
@@ -1396,6 +1393,12 @@ out:
                                                           &cur_percent,
                                                           lte);
                        }
+                       ret = write_wim_resource(lte, out_fp,
+                                                out_ctype,
+                                                &lte->output_resource_entry,
+                                                0);
+                       if (ret != 0)
+                               break;
                }
                if (write_flags & WIMLIB_WRITE_FLAG_SHOW_PROGRESS)
                        finish_stream_write_progress(total_size);
@@ -1427,6 +1430,19 @@ out:
        return ret;
 }
 
+
+static const char *get_data_type(int ctype)
+{
+       switch (ctype) {
+       case WIM_COMPRESSION_TYPE_NONE:
+               return "uncompressed";
+       case WIM_COMPRESSION_TYPE_LZX:
+               return "LZX-compressed";
+       case WIM_COMPRESSION_TYPE_XPRESS:
+               return "XPRESS-compressed";
+       }
+}
+
 static int write_stream_list_parallel(struct list_head *stream_list,
                                      FILE *out_fp, int out_ctype,
                                      int write_flags, u64 total_size,
@@ -1484,8 +1500,8 @@ static int write_stream_list_parallel(struct list_head *stream_list,
        }
 
        if (write_flags & WIMLIB_WRITE_FLAG_SHOW_PROGRESS) {
-               printf("Writing compressed data using %u threads...\n",
-                      num_threads);
+               printf("Writing %s compressed data using %u threads...\n",
+                      get_data_type(out_ctype), num_threads);
        }
 
        ret = main_writer_thread_proc(stream_list,
@@ -1561,7 +1577,8 @@ static int write_stream_list(struct list_head *stream_list, FILE *out_fp,
                        const char *reason = "";
                        if (!compression_needed)
                                reason = " (no compression needed)";
-                       printf("Writing data using 1 thread%s\n", reason);
+                       printf("Writing %s data using 1 thread%s\n",
+                              get_data_type(out_ctype), reason);
                }
 
                return write_stream_list_serial(stream_list, out_fp,
@@ -1663,10 +1680,10 @@ int finish_write(WIMStruct *w, int image, int write_flags)
                return WIMLIB_ERR_WRITE;
        xml_data_size = integrity_offset - xml_data_offset;
 
-       hdr.xml_res_entry.offset                 = xml_data_offset;
-       hdr.xml_res_entry.size                   = xml_data_size;
-       hdr.xml_res_entry.original_size          = xml_data_size;
-       hdr.xml_res_entry.flags                  = 0;
+       hdr.xml_res_entry.offset        = xml_data_offset;
+       hdr.xml_res_entry.size          = xml_data_size;
+       hdr.xml_res_entry.original_size = xml_data_size;
+       hdr.xml_res_entry.flags         = WIM_RESHDR_FLAG_METADATA;
 
        if (write_flags & WIMLIB_WRITE_FLAG_CHECK_INTEGRITY) {
                ret = write_integrity_table(out, WIM_HEADER_DISK_SIZE,
@@ -1725,9 +1742,19 @@ int finish_write(WIMStruct *w, int image, int write_flags)
        if (ret != 0)
                return ret;
 
-       DEBUG("Closing output file.");
-       wimlib_assert(w->out_fp != NULL);
-       if (fclose(w->out_fp) != 0) {
+       if (write_flags & WIMLIB_WRITE_FLAG_FSYNC) {
+               DEBUG("fsync output WIM file");
+               if (fflush(out) != 0
+                   || fsync(fileno(out)) != 0)
+               {
+                       ERROR_WITH_ERRNO("Error flushing data to WIM file");
+                       ret = WIMLIB_ERR_WRITE;
+               }
+       }
+
+       DEBUG("Closing output WIM file.");
+
+       if (fclose(out) != 0) {
                ERROR_WITH_ERRNO("Failed to close the WIM file");
                ret = WIMLIB_ERR_WRITE;
        }
@@ -1780,6 +1807,7 @@ WIMLIBAPI int wimlib_write(WIMStruct *w, const char *path,
                return WIMLIB_ERR_INVALID_IMAGE;
 
 
+
        if (w->hdr.total_parts != 1) {
                ERROR("Cannot call wimlib_write() on part of a split WIM");
                return WIMLIB_ERR_SPLIT_UNSUPPORTED;