X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fwrite.c;h=09b74ec16c8b273ef9c94360c75eaea428fdf36f;hb=c4f28b5ca129af1050dee36690d01e4941efa18f;hp=2673081ae9a57b1d3e6b1ac104f5aabd5ae52088;hpb=c605cbfe13201cf1c4705e38a88832518bf0c027;p=wimlib diff --git a/src/write.c b/src/write.c index 2673081a..09b74ec1 100644 --- a/src/write.c +++ b/src/write.c @@ -286,31 +286,32 @@ struct write_streams_progress_data { static void do_write_streams_progress(struct write_streams_progress_data *progress_data, - struct wim_lookup_table_entry *lte, - bool stream_discarded) + u64 size, + bool discarded, + struct wim_lookup_table_entry *cur_stream) { union wimlib_progress_info *progress = &progress_data->progress; bool new_wim_part; - if (stream_discarded) { - progress->write_streams.total_bytes -= lte->size; + if (discarded) { + progress->write_streams.total_bytes -= size; if (progress_data->next_progress != ~(uint64_t)0 && progress_data->next_progress > progress->write_streams.total_bytes) { progress_data->next_progress = progress->write_streams.total_bytes; } } else { - progress->write_streams.completed_bytes += lte->size; + progress->write_streams.completed_bytes += size; } new_wim_part = false; - if (lte->resource_location == RESOURCE_IN_WIM && - lte->rspec->wim != progress_data->prev_wim_part) + if (cur_stream->resource_location == RESOURCE_IN_WIM && + cur_stream->rspec->wim != progress_data->prev_wim_part) { if (progress_data->prev_wim_part) { new_wim_part = true; progress->write_streams.completed_parts++; } - progress_data->prev_wim_part = lte->rspec->wim; + progress_data->prev_wim_part = cur_stream->rspec->wim; } progress->write_streams.completed_streams++; if (progress_data->progress_func @@ -679,7 +680,7 @@ write_stream_begin_read(struct wim_lookup_table_entry *lte, DEBUG("Discarding duplicate stream of " "length %"PRIu64, lte->size); do_write_streams_progress(&ctx->progress_data, - lte, true); + lte->size, true, lte); list_del(<e->write_streams_list); list_del(<e->lookup_table_list); if (lte_new->will_be_in_output_wim) @@ -720,16 +721,16 @@ write_chunk(struct write_streams_ctx *ctx, const void *cchunk, { int ret; + struct wim_lookup_table_entry *lte; + + lte = list_entry(ctx->pending_streams.next, + struct wim_lookup_table_entry, write_streams_list); + if (ctx->cur_write_res_offset == 0 && !(ctx->write_resource_flags & WIMLIB_WRITE_RESOURCE_FLAG_PACK_STREAMS)) { /* Starting to write a new stream in non-packed mode. */ - struct wim_lookup_table_entry *lte; - - lte = list_entry(ctx->pending_streams.next, - struct wim_lookup_table_entry, write_streams_list); - if (ctx->write_resource_flags & WIMLIB_WRITE_RESOURCE_FLAG_PIPABLE) { int additional_reshdr_flags = 0; if (ctx->compressor != NULL) @@ -774,6 +775,9 @@ write_chunk(struct write_streams_ctx *ctx, const void *cchunk, ctx->cur_write_res_offset += usize; + do_write_streams_progress(&ctx->progress_data, + usize, false, lte); + if (ctx->cur_write_res_offset == ctx->cur_write_res_size && !(ctx->write_resource_flags & WIMLIB_WRITE_RESOURCE_FLAG_PACK_STREAMS)) { @@ -785,8 +789,6 @@ write_chunk(struct write_streams_ctx *ctx, const void *cchunk, /* Finished writing a stream in non-packed mode. */ - do_write_streams_progress(&ctx->progress_data, lte, false); - ret = end_write_resource(ctx, <e->out_reshdr); if (ret) return ret; @@ -1211,6 +1213,12 @@ write_stream_list(struct list_head *stream_list, * bytes needing to be compressed is less 2000000 (heuristic value). */ if (out_ctype != WIMLIB_COMPRESSION_TYPE_NONE) { + if (out_ctype == WIMLIB_COMPRESSION_TYPE_LZMS && + ctx.lookup_table != NULL) { + WARNING("LZMS compression not implemented; data will " + "actually be written uncompressed."); + } + if (ctx.num_bytes_to_compress >= 2000000) { ret = new_parallel_chunk_compressor(out_ctype, out_chunk_size, @@ -1247,6 +1255,11 @@ write_stream_list(struct list_head *stream_list, INIT_LIST_HEAD(&ctx.pending_streams); + if (ctx.progress_data.progress_func) { + (*ctx.progress_data.progress_func)(WIMLIB_PROGRESS_MSG_WRITE_STREAMS, + &ctx.progress_data.progress); + } + if (write_resource_flags & WIMLIB_WRITE_RESOURCE_FLAG_PACK_STREAMS) { ret = begin_write_resource(&ctx, ctx.num_bytes_to_compress); if (ret) @@ -2723,6 +2736,9 @@ overwrite_wim_inplace(WIMStruct *wim, int write_flags, DEBUG("Overwriting `%"TS"' in-place", wim->filename); + /* Save original header so it can be restored in case of error */ + memcpy(&hdr_save, &wim->hdr, sizeof(struct wim_header)); + /* Set default integrity flag. */ if (!(write_flags & (WIMLIB_WRITE_FLAG_CHECK_INTEGRITY | WIMLIB_WRITE_FLAG_NO_CHECK_INTEGRITY))) @@ -2732,8 +2748,12 @@ overwrite_wim_inplace(WIMStruct *wim, int write_flags, /* Set default packed flag. */ if (!(write_flags & (WIMLIB_WRITE_FLAG_PACK_STREAMS | WIMLIB_WRITE_FLAG_NO_PACK_STREAMS))) + { if (wim->hdr.wim_version == WIM_VERSION_PACKED_STREAMS) write_flags |= WIMLIB_WRITE_FLAG_PACK_STREAMS; + } else if (write_flags & WIMLIB_WRITE_FLAG_PACK_STREAMS) { + wim->hdr.wim_version = WIM_VERSION_PACKED_STREAMS; + } /* Set additional flags for overwrite. */ write_flags |= WIMLIB_WRITE_FLAG_OVERWRITE | @@ -2750,12 +2770,14 @@ overwrite_wim_inplace(WIMStruct *wim, int write_flags, if (wim->hdr.integrity_table_reshdr.offset_in_wim != 0 && wim->hdr.integrity_table_reshdr.offset_in_wim < old_xml_end) { WARNING("Didn't expect the integrity table to be before the XML data"); - return WIMLIB_ERR_RESOURCE_ORDER; + ret = WIMLIB_ERR_RESOURCE_ORDER; + goto out_restore_memory_hdr; } if (old_lookup_table_end > old_xml_begin) { WARNING("Didn't expect the lookup table to be after the XML data"); - return WIMLIB_ERR_RESOURCE_ORDER; + ret = WIMLIB_ERR_RESOURCE_ORDER; + goto out_restore_memory_hdr; } /* Set @old_wim_end, which indicates the point beyond which we don't @@ -2786,31 +2808,28 @@ overwrite_wim_inplace(WIMStruct *wim, int write_flags, ret = check_resource_offsets(wim, old_wim_end); if (ret) - return ret; + goto out_restore_memory_hdr; ret = prepare_stream_list_for_write(wim, WIMLIB_ALL_IMAGES, write_flags, &stream_list, &lookup_table_list, &filter_ctx); if (ret) - return ret; + goto out_restore_memory_hdr; ret = open_wim_writable(wim, wim->filename, O_RDWR); if (ret) - return ret; + goto out_restore_memory_hdr; ret = lock_wim(wim, wim->out_fd.fd); if (ret) goto out_close_wim; - /* Save original header so it can be restored in case of error */ - memcpy(&hdr_save, &wim->hdr, sizeof(struct wim_header)); - /* Set WIM_HDR_FLAG_WRITE_IN_PROGRESS flag in header. */ wim->hdr.flags |= WIM_HDR_FLAG_WRITE_IN_PROGRESS; ret = write_wim_header_flags(wim->hdr.flags, &wim->out_fd); if (ret) { ERROR_WITH_ERRNO("Error updating WIM header flags"); - goto out_restore_memory_hdr; + goto out_unlock_wim; } if (filedes_seek(&wim->out_fd, old_wim_end) == -1) { @@ -2843,7 +2862,8 @@ overwrite_wim_inplace(WIMStruct *wim, int write_flags, if (ret) goto out_truncate; - goto out_unlock_wim; + wim->wim_locked = 0; + return 0; out_truncate: if (!(write_flags & WIMLIB_WRITE_FLAG_NO_LOOKUP_TABLE)) { @@ -2855,12 +2875,12 @@ out_truncate: } out_restore_physical_hdr: (void)write_wim_header_flags(hdr_save.flags, &wim->out_fd); -out_restore_memory_hdr: - memcpy(&wim->hdr, &hdr_save, sizeof(struct wim_header)); -out_close_wim: - (void)close_wim_writable(wim, write_flags); out_unlock_wim: wim->wim_locked = 0; +out_close_wim: + (void)close_wim_writable(wim, write_flags); +out_restore_memory_hdr: + memcpy(&wim->hdr, &hdr_save, sizeof(struct wim_header)); return ret; } @@ -2930,15 +2950,10 @@ can_overwrite_wim_inplace(const WIMStruct *wim, int write_flags) if (wim_is_pipable(wim) || (write_flags & WIMLIB_WRITE_FLAG_PIPABLE)) return false; - if (wim->hdr.wim_version != WIM_VERSION_PACKED_STREAMS) { - if (wim->compression_type != wim->out_compression_type) - return false; - if (wim->chunk_size != wim->out_chunk_size) - return false; - } else { - if (write_flags & WIMLIB_WRITE_FLAG_NO_PACK_STREAMS) - return false; - } + if (wim->compression_type != wim->out_compression_type) + return false; + if (wim->chunk_size != wim->out_chunk_size) + return false; return true; }