X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;ds=sidebyside;f=src%2Fwrite.c;h=e495cb5b29721c21aa7a1526b0d8d604453348f5;hb=883833a4b3dabec325edf1ca938000f91d587c00;hp=8cf038220d8a80b814ed845aa267feefc7334f80;hpb=a15d2daaeb81d829a21d497f63cce66af1db0b03;p=wimlib diff --git a/src/write.c b/src/write.c index 8cf03822..e495cb5b 100644 --- a/src/write.c +++ b/src/write.c @@ -34,7 +34,7 @@ # include #endif -#include "wimlib/compress_chunks.h" +#include "wimlib/chunk_compressor.h" #include "wimlib/endianness.h" #include "wimlib/error.h" #include "wimlib/file_io.h" @@ -1047,7 +1047,8 @@ write_raw_copy_resource(struct wim_resource_spec *in_rspec, out_offset_in_wim += sizeof(struct pwm_stream_hdr); } in_fd = &in_rspec->wim->in_fd; - while (cur_read_offset != end_read_offset) { + wimlib_assert(cur_read_offset != end_read_offset); + do { bytes_to_read = min(sizeof(buf), end_read_offset - cur_read_offset); @@ -1060,7 +1061,8 @@ write_raw_copy_resource(struct wim_resource_spec *in_rspec, return ret; cur_read_offset += bytes_to_read; - } + + } while (cur_read_offset != end_read_offset); list_for_each_entry(lte, &in_rspec->stream_list, rspec_node) { if (lte->will_be_in_output_wim) { @@ -1079,7 +1081,8 @@ write_raw_copy_resource(struct wim_resource_spec *in_rspec, * file being written. */ static int write_raw_copy_resources(struct list_head *raw_copy_resources, - struct filedes *out_fd) + struct filedes *out_fd, + struct write_streams_progress_data *progress_data) { struct wim_lookup_table_entry *lte; int ret; @@ -1088,6 +1091,7 @@ write_raw_copy_resources(struct list_head *raw_copy_resources, ret = write_raw_copy_resource(lte->rspec, out_fd); if (ret) return ret; + do_write_streams_progress(progress_data, lte->size, false, lte); } return 0; } @@ -1195,11 +1199,6 @@ remove_zero_length_streams(struct list_head *stream_list) * no streams are hard-filtered or no streams are unhashed, this parameter * can be NULL. * - * @comp_ctx - * A location in which to allocate the pointer to the default LZX - * compression context. This will only be used if @out_ctype is - * WIMLIB_COMPRESSION_TYPE_LZX. - * * @progress_func * If non-NULL, a progress function that will be called periodically with * WIMLIB_PROGRESS_MSG_WRITE_STREAMS messages. Note that on-the-fly @@ -1264,7 +1263,6 @@ write_stream_list(struct list_head *stream_list, unsigned num_threads, struct wim_lookup_table *lookup_table, struct filter_context *filter_ctx, - struct wimlib_lzx_context **comp_ctx, wimlib_progress_func_t progress_func) { int ret; @@ -1363,15 +1361,8 @@ write_stream_list(struct list_head *stream_list, } if (ctx.compressor == NULL) { - if (out_ctype == WIMLIB_COMPRESSION_TYPE_LZX) { - ret = wimlib_lzx_alloc_context(out_chunk_size, - NULL, - comp_ctx); - if (ret) - goto out_destroy_context; - } ret = new_serial_chunk_compressor(out_ctype, out_chunk_size, - *comp_ctx, &ctx.compressor); + &ctx.compressor); if (ret) goto out_destroy_context; } @@ -1456,7 +1447,8 @@ write_stream_list(struct list_head *stream_list, out_write_raw_copy_resources: /* Copy any compressed resources for which the raw data can be reused * without decompression. */ - ret = write_raw_copy_resources(&raw_copy_resources, ctx.out_fd); + ret = write_raw_copy_resources(&raw_copy_resources, ctx.out_fd, + &ctx.progress_data); out_destroy_context: if (out_chunk_size > STACK_MAX) @@ -1473,8 +1465,7 @@ write_wim_resource(struct wim_lookup_table_entry *lte, struct filedes *out_fd, int out_ctype, u32 out_chunk_size, - int write_resource_flags, - struct wimlib_lzx_context **comp_ctx) + int write_resource_flags) { LIST_HEAD(stream_list); list_add(<e->write_streams_list, &stream_list); @@ -1487,7 +1478,6 @@ write_wim_resource(struct wim_lookup_table_entry *lte, 1, NULL, NULL, - comp_ctx, NULL); } @@ -1498,8 +1488,7 @@ write_wim_resource_from_buffer(const void *buf, size_t buf_size, u32 out_chunk_size, struct wim_reshdr *out_reshdr, u8 *hash, - int write_resource_flags, - struct wimlib_lzx_context **comp_ctx) + int write_resource_flags) { int ret; struct wim_lookup_table_entry *lte; @@ -1524,7 +1513,7 @@ write_wim_resource_from_buffer(const void *buf, size_t buf_size, } ret = write_wim_resource(lte, out_fd, out_ctype, out_chunk_size, - write_resource_flags, comp_ctx); + write_resource_flags); if (ret) goto out_free_lte; @@ -1931,7 +1920,6 @@ write_wim_streams(WIMStruct *wim, int image, int write_flags, num_threads, wim->lookup_table, filter_ctx, - &wim->lzx_context, progress_func); } @@ -1991,8 +1979,7 @@ write_wim_metadata_resources(WIMStruct *wim, int image, int write_flags, &wim->out_fd, wim->out_compression_type, wim->out_chunk_size, - write_resource_flags, - &wim->lzx_context); + write_resource_flags); } if (ret) return ret; @@ -2112,8 +2099,7 @@ write_wim_lookup_table(WIMStruct *wim, int image, int write_flags, &wim->out_fd, wim->hdr.part_number, out_reshdr, - write_flags_to_resource_flags(write_flags), - &wim->lzx_context); + write_flags_to_resource_flags(write_flags)); } /* @@ -2578,7 +2564,10 @@ write_wim_part(WIMStruct *wim, WIMLIB_WRITE_FLAG_PACK_STREAMS)) == (WIMLIB_WRITE_FLAG_PIPABLE | WIMLIB_WRITE_FLAG_PACK_STREAMS)) + { + ERROR("Cannot specify both PIPABLE and PACK_STREAMS!"); return WIMLIB_ERR_INVALID_PARAM; + } /* Set appropriate magic number. */ if (write_flags & WIMLIB_WRITE_FLAG_PIPABLE) @@ -2881,8 +2870,13 @@ overwrite_wim_inplace(WIMStruct *wim, int write_flags, if (!(write_flags & (WIMLIB_WRITE_FLAG_PACK_STREAMS | WIMLIB_WRITE_FLAG_NO_PACK_STREAMS))) { + #if 0 if (wim->hdr.wim_version == WIM_VERSION_PACKED_STREAMS) write_flags |= WIMLIB_WRITE_FLAG_PACK_STREAMS; + #endif + /* wimlib allows multiple packs in a single WIM, but they don't + * seem to be compatible with WIMGAPI. Write new streams + * unpacked. */ } else if (write_flags & WIMLIB_WRITE_FLAG_PACK_STREAMS) { wim->hdr.wim_version = WIM_VERSION_PACKED_STREAMS; } @@ -2978,7 +2972,6 @@ overwrite_wim_inplace(WIMStruct *wim, int write_flags, num_threads, wim->lookup_table, &filter_ctx, - &wim->lzx_context, progress_func); if (ret) goto out_truncate; @@ -3070,18 +3063,35 @@ overwrite_wim_via_tmpfile(WIMStruct *wim, int write_flags, return 0; } +/* Determine if the specified WIM file may be updated by appending in-place + * rather than writing and replacing it with an entirely new file. */ static bool can_overwrite_wim_inplace(const WIMStruct *wim, int write_flags) { + /* REBUILD flag forces full rebuild. */ if (write_flags & WIMLIB_WRITE_FLAG_REBUILD) return false; + /* Deletions cause full rebuild by default. */ if (wim->deletion_occurred && !(write_flags & WIMLIB_WRITE_FLAG_SOFT_DELETE)) return false; + /* Pipable WIMs cannot be updated in place, nor can a non-pipable WIM be + * turned into a pipable WIM in-place. */ if (wim_is_pipable(wim) || (write_flags & WIMLIB_WRITE_FLAG_PIPABLE)) return false; + /* wimlib allows multiple packs in a single WIM, but they don't seem to + * be compatible with WIMGAPI, so force all streams to be repacked if + * the WIM already may have contained a pack and PACK_STREAMS was + * requested. */ + if (write_flags & WIMLIB_WRITE_FLAG_PACK_STREAMS && + wim->hdr.wim_version == WIM_VERSION_PACKED_STREAMS) + return false; + + /* The default compression type and compression chunk size selected for + * the output WIM must be the same as those currently used for the WIM. + */ if (wim->compression_type != wim->out_compression_type) return false; if (wim->chunk_size != wim->out_chunk_size)