From: Eric Biggers Date: Mon, 19 Nov 2012 03:24:52 +0000 (-0600) Subject: wimlib_write(): Add WIMLIB_WRITE_FLAG_FSYNC X-Git-Tag: v1.2.0~34 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=dc63267ac1da2b75837689e400eed0400e764f4d wimlib_write(): Add WIMLIB_WRITE_FLAG_FSYNC Use WIMLIB_WRITE_FLAG_FSYNC to request that fsync() is called on the file descriptor for the WIM being written, before closing it. Done by default when wimlib_write() is called through wimlib_overwrite(). --- diff --git a/src/modify.c b/src/modify.c index 0d096703..455a7cec 100644 --- a/src/modify.c +++ b/src/modify.c @@ -700,6 +700,8 @@ WIMLIBAPI int wimlib_delete_image(WIMStruct *w, int image) /* Remove the image from the XML information. */ xml_delete_image(&w->wim_info, image); + + w->deletion_occurred = true; return 0; } diff --git a/src/wim.c b/src/wim.c index 2278f2eb..ed6ab33d 100644 --- a/src/wim.c +++ b/src/wim.c @@ -428,7 +428,7 @@ static int begin_read(WIMStruct *w, const char *in_wim_path, int open_flags) w->filename = realpath(in_wim_path, NULL); if (!w->filename) { - ERROR("Failed to allocate memory for WIM filename"); + ERROR_WITH_ERRNO("Failed to resolve WIM filename"); return WIMLIB_ERR_NOMEM; } diff --git a/src/wimlib.h b/src/wimlib.h index df2dffab..2ccbd580 100644 --- a/src/wimlib.h +++ b/src/wimlib.h @@ -269,6 +269,9 @@ enum wim_compression_type { /** Print file paths as we write then */ #define WIMLIB_WRITE_FLAG_VERBOSE 0x00000004 +/** Call fsync() when the WIM file is closed */ +#define WIMLIB_WRITE_FLAG_FSYNC 0x00000008 + /** Mark the image being added as the bootable image of the WIM. */ #define WIMLIB_ADD_IMAGE_FLAG_BOOT 0x00000001 diff --git a/src/wimlib_internal.h b/src/wimlib_internal.h index 41028191..96136d8a 100644 --- a/src/wimlib_internal.h +++ b/src/wimlib_internal.h @@ -308,6 +308,8 @@ typedef struct WIMStruct { * subtract 1 from this to get the index of the current image in the * image_metadata array. */ int current_image; + + bool deletion_occurred; } WIMStruct; diff --git a/src/write.c b/src/write.c index 668c7abd..eed40df8 100644 --- a/src/write.c +++ b/src/write.c @@ -80,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; @@ -88,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); @@ -117,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) @@ -1742,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; } @@ -1797,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;