X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fextract.c;h=ea9c25228d8c8a4877a59223b6daa78e2777d749;hb=846d3ae386f6c12953816108c04de244533e3a4a;hp=efce477e0a122cd076799ea0cb7ad3af67f79eed;hpb=c48e2f84645abe34faec4994605d7a7b3b451672;p=wimlib diff --git a/src/extract.c b/src/extract.c index efce477e..ea9c2522 100644 --- a/src/extract.c +++ b/src/extract.c @@ -233,19 +233,18 @@ read_blobs_from_pipe(struct apply_ctx *ctx, const struct read_blob_callbacks *cb if (ret) return ret; - wim_reshdr_to_desc(&reshdr, ctx->wim, &rdesc); - - if (!(rdesc.flags & WIM_RESHDR_FLAG_METADATA) + if (!(reshdr.flags & WIM_RESHDR_FLAG_METADATA) && (blob = lookup_blob(ctx->wim->blob_table, hash)) && (blob->out_refcnt)) { - blob_set_is_located_in_nonsolid_wim_resource(blob, &rdesc); + wim_reshdr_to_desc_and_blob(&reshdr, ctx->wim, &rdesc, blob); ret = read_blob_with_sha1(blob, cbs); blob_unset_is_located_in_wim_resource(blob); if (ret) return ret; ctx->num_blobs_remaining--; } else { + wim_reshdr_to_desc(&reshdr, ctx->wim, &rdesc); ret = skip_wim_resource(&rdesc); if (ret) return ret; @@ -329,10 +328,7 @@ extract_chunk_wrapper(const void *chunk, size_t size, void *_ctx) const struct wim_inode *inode = targets[i].inode; const struct wim_dentry *dentry; - list_for_each_entry(dentry, - &inode->i_extraction_aliases, - d_extraction_alias_node) - { + inode_for_each_extraction_alias(dentry, inode) { progress->extract.completed_bytes += size; if (ctx->cur_blob_offset == ctx->cur_blob->size) progress->extract.completed_streams++; @@ -385,61 +381,31 @@ extract_chunk_wrapper(const void *chunk, size_t size, void *_ctx) return call_consume_chunk(chunk, size, ctx->saved_cbs); } +/* Copy the blob's data from the temporary file to each of its targets. + * + * This is executed only in the very uncommon case that a blob is being + * extracted to more than MAX_OPEN_FILES targets! */ static int -extract_from_tmpfile(const tchar *tmpfile_name, struct apply_ctx *ctx) +extract_from_tmpfile(const tchar *tmpfile_name, + const struct blob_descriptor *orig_blob, + const struct read_blob_callbacks *cbs) { struct blob_descriptor tmpfile_blob; - struct blob_descriptor *orig_blob = ctx->cur_blob; - const struct read_blob_callbacks *cbs = ctx->saved_cbs; + const struct blob_extraction_target *targets = blob_extraction_targets(orig_blob); int ret; - const u32 orig_refcnt = orig_blob->out_refcnt; - - BUILD_BUG_ON(MAX_OPEN_FILES < - ARRAY_LEN(orig_blob->inline_blob_extraction_targets)); - - struct blob_extraction_target *targets = orig_blob->blob_extraction_targets; - - /* Copy the blob's data from the temporary file to each of its targets. - * - * This is executed only in the very uncommon case that a blob is being - * extracted to more than MAX_OPEN_FILES targets! */ memcpy(&tmpfile_blob, orig_blob, sizeof(struct blob_descriptor)); tmpfile_blob.blob_location = BLOB_IN_FILE_ON_DISK; - tmpfile_blob.file_on_disk = ctx->tmpfile_name; - ret = 0; - for (u32 i = 0; i < orig_refcnt; i++) { - - /* Note: it usually doesn't matter whether we pass the original - * blob descriptor to callbacks provided by the extraction - * backend as opposed to the tmpfile blob descriptor, since they - * shouldn't actually read data from the blob other than through - * the read_blob_with_cbs() call below. But for - * WIMLIB_EXTRACT_FLAG_WIMBOOT mode on Windows it does matter - * because it needs access to the original WIM resource - * descriptor in order to create the external backing reference. - */ - - orig_blob->out_refcnt = 1; - orig_blob->inline_blob_extraction_targets[0] = targets[i]; - - ret = call_begin_blob(orig_blob, cbs); - if (ret) - break; + tmpfile_blob.file_on_disk = (tchar *)tmpfile_name; + tmpfile_blob.out_refcnt = 1; - struct read_blob_callbacks wrapper_cbs = { - .consume_chunk = cbs->consume_chunk, - .ctx = cbs->ctx, - }; - ret = read_blob_with_cbs(&tmpfile_blob, &wrapper_cbs); - - ret = call_end_blob(orig_blob, ret, cbs); + for (u32 i = 0; i < orig_blob->out_refcnt; i++) { + tmpfile_blob.inline_blob_extraction_targets[0] = targets[i]; + ret = read_blob_with_cbs(&tmpfile_blob, cbs); if (ret) - break; + return ret; } - FREE(targets); - orig_blob->out_refcnt = 0; - return ret; + return 0; } static int @@ -450,7 +416,8 @@ end_extract_blob_wrapper(struct blob_descriptor *blob, int status, void *_ctx) if (unlikely(filedes_valid(&ctx->tmpfile_fd))) { filedes_close(&ctx->tmpfile_fd); if (!status) - status = extract_from_tmpfile(ctx->tmpfile_name, ctx); + status = extract_from_tmpfile(ctx->tmpfile_name, blob, + ctx->saved_cbs); filedes_invalidate(&ctx->tmpfile_fd); tunlink(ctx->tmpfile_name); FREE(ctx->tmpfile_name); @@ -1113,18 +1080,14 @@ static void dentry_list_build_inode_alias_lists(struct list_head *dentry_list) { struct wim_dentry *dentry; - struct wim_inode *inode; + + list_for_each_entry(dentry, dentry_list, d_extraction_list_node) + dentry->d_inode->i_first_extraction_alias = NULL; list_for_each_entry(dentry, dentry_list, d_extraction_list_node) { - inode = dentry->d_inode; - if (!inode->i_visited) - INIT_LIST_HEAD(&inode->i_extraction_aliases); - list_add_tail(&dentry->d_extraction_alias_node, - &inode->i_extraction_aliases); - inode->i_visited = 1; + dentry->d_next_extraction_alias = dentry->d_inode->i_first_extraction_alias; + dentry->d_inode->i_first_extraction_alias = dentry; } - list_for_each_entry(dentry, dentry_list, d_extraction_list_node) - dentry->d_inode->i_visited = 0; } static void @@ -1158,7 +1121,7 @@ inode_tally_features(const struct wim_inode *inode, else features->other_reparse_points++; } - if (inode->i_security_id != -1) + if (inode_has_security_descriptor(inode)) features->security_descriptors++; if (inode_has_unix_data(inode)) features->unix_data++; @@ -1958,9 +1921,8 @@ wimlib_extract_image_from_pipe_with_progress(int pipe_fd, metadata_rdesc = MALLOC(sizeof(struct wim_resource_descriptor)); if (!metadata_rdesc) goto out_wimlib_free; - wim_reshdr_to_desc(&reshdr, pwm, metadata_rdesc); - blob_set_is_located_in_nonsolid_wim_resource(imd->metadata_blob, - metadata_rdesc); + wim_reshdr_to_desc_and_blob(&reshdr, pwm, metadata_rdesc, + imd->metadata_blob); if (i == image) { /* Metadata resource is for the image being extracted.