int
do_file_extract_progress(struct apply_ctx *ctx, enum wimlib_progress_msg msg)
{
- ctx->count_until_file_progress = 512; /* Arbitrary value to limit calls */
+ ctx->count_until_file_progress = 500; /* Arbitrary value to limit calls */
return extract_progress(ctx, msg);
}
+static int
+start_file_phase(struct apply_ctx *ctx, uint64_t end_file_count, enum wimlib_progress_msg msg)
+{
+ ctx->progress.extract.current_file_count = 0;
+ ctx->progress.extract.end_file_count = end_file_count;
+ return do_file_extract_progress(ctx, msg);
+}
+
+int
+start_file_structure_phase(struct apply_ctx *ctx, uint64_t end_file_count)
+{
+ return start_file_phase(ctx, end_file_count, WIMLIB_PROGRESS_MSG_EXTRACT_FILE_STRUCTURE);
+}
+
+int
+start_file_metadata_phase(struct apply_ctx *ctx, uint64_t end_file_count)
+{
+ return start_file_phase(ctx, end_file_count, WIMLIB_PROGRESS_MSG_EXTRACT_METADATA);
+}
+
+static int
+end_file_phase(struct apply_ctx *ctx, enum wimlib_progress_msg msg)
+{
+ ctx->progress.extract.current_file_count = ctx->progress.extract.end_file_count;
+ return do_file_extract_progress(ctx, msg);
+}
+
+int
+end_file_structure_phase(struct apply_ctx *ctx)
+{
+ return end_file_phase(ctx, WIMLIB_PROGRESS_MSG_EXTRACT_FILE_STRUCTURE);
+}
+
+int
+end_file_metadata_phase(struct apply_ctx *ctx)
+{
+ return end_file_phase(ctx, WIMLIB_PROGRESS_MSG_EXTRACT_METADATA);
+}
+
/* Check whether the extraction of a dentry should be skipped completely. */
static bool
dentry_is_supported(struct wim_dentry *dentry,
}
static int
-dentry_ref_streams(struct wim_dentry *dentry, struct apply_ctx *ctx)
+ref_unnamed_stream(struct wim_dentry *dentry, struct apply_ctx *ctx)
{
struct wim_inode *inode = dentry->d_inode;
int ret;
+ u16 stream_idx;
+ struct wim_lookup_table_entry *stream;
- /* The unnamed data stream will always be extracted, except in an
- * unlikely case. */
- if (!inode_is_encrypted_directory(inode)) {
- u16 stream_idx;
- struct wim_lookup_table_entry *stream;
+ if (unlikely(inode_is_encrypted_directory(inode)))
+ return 0;
- stream = inode_unnamed_stream_resolved(inode, &stream_idx);
- ret = ref_stream(stream, stream_idx, dentry, ctx);
- if (ret)
- return ret;
+ if (unlikely(ctx->apply_ops->will_externally_back)) {
+ ret = (*ctx->apply_ops->will_externally_back)(dentry, ctx);
+ if (ret >= 0) {
+ if (ret) /* Error */
+ return ret;
+ /* Will externally back */
+ return 0;
+ }
+ /* Won't externally back */
}
+ stream = inode_unnamed_stream_resolved(inode, &stream_idx);
+ return ref_stream(stream, stream_idx, dentry, ctx);
+}
+
+static int
+dentry_ref_streams(struct wim_dentry *dentry, struct apply_ctx *ctx)
+{
+ struct wim_inode *inode = dentry->d_inode;
+ int ret;
+
+ /* The unnamed data stream will almost always be extracted, but there
+ * exist cases in which it won't be. */
+ ret = ref_unnamed_stream(dentry, ctx);
+ if (ret)
+ return ret;
+
/* Named data streams will be extracted only if supported in the current
* extraction mode and volume, and to avoid complications, if not doing
* a linked extraction. */
}
INIT_LIST_HEAD(&ctx->stream_list);
filedes_invalidate(&ctx->tmpfile_fd);
+ ctx->apply_ops = ops;
ret = (*ops->get_supported_features)(target, &ctx->supported_features);
if (ret)