X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fmount_image.c;h=8037a38f0da5b6a89dc24f2fb08fe78bde78e26a;hb=44153b02cd98bddef5b7057bda7dd2d4aca5a5b3;hp=7fe8bb537fb1621a5e5742fba40aa98ed8347dde;hpb=15ded30b9bcce7ac0388dec90dd4d6ef3d6d1596;p=wimlib diff --git a/src/mount_image.c b/src/mount_image.c index 7fe8bb53..8037a38f 100644 --- a/src/mount_image.c +++ b/src/mount_image.c @@ -39,6 +39,8 @@ #define FUSE_USE_VERSION 26 +#include /* sometimes required before */ + #include #include #include @@ -50,7 +52,6 @@ #include #include #include -#include #include #include @@ -357,7 +358,7 @@ inode_get_data_stream_tstr(const struct wim_inode *inode, struct wim_inode_stream *strm; if (!stream_name || !*stream_name) { - strm = inode_get_unnamed_stream(inode, STREAM_TYPE_DATA); + strm = inode_get_unnamed_data_stream(inode); } else { const utf16lechar *uname; @@ -502,8 +503,8 @@ create_file(struct fuse_context *fuse_ctx, const char *path, } } - list_add_tail(&new_inode->i_list, - &wim_get_current_image_metadata(wimfs_ctx->wim)->inode_list); + hlist_add_head(&new_inode->i_hlist, + &wim_get_current_image_metadata(wimfs_ctx->wim)->inode_list); dentry_add_child(parent, new_dentry); @@ -549,6 +550,25 @@ inode_default_unix_mode(const struct wim_inode *inode) return inode_unix_file_type(inode) | 0777; } +static u64 +blob_size(const struct blob_descriptor *blob) +{ + if (!blob) + return 0; + return blob->size; +} + +static u64 +blob_stored_size(const struct blob_descriptor *blob) +{ + if (!blob) + return 0; + if (blob->blob_location == BLOB_IN_WIM && + blob->size == blob->rdesc->uncompressed_size) + return blob->rdesc->size_in_wim; + return blob->size; +} + /* * Retrieve standard UNIX metadata ('struct stat') for a WIM inode. * @@ -586,8 +606,7 @@ inode_to_stbuf(const struct wim_inode *inode, } stbuf->st_ino = inode->i_ino; stbuf->st_nlink = inode->i_nlink; - if (blob) - stbuf->st_size = blob->size; + stbuf->st_size = blob_size(blob); #ifdef HAVE_STAT_NANOSECOND_PRECISION stbuf->st_atim = wim_timestamp_to_timespec(inode->i_last_access_time); stbuf->st_mtim = wim_timestamp_to_timespec(inode->i_last_write_time); @@ -597,7 +616,7 @@ inode_to_stbuf(const struct wim_inode *inode, stbuf->st_mtime = wim_timestamp_to_time_t(inode->i_last_write_time); stbuf->st_ctime = stbuf->st_mtime; #endif - stbuf->st_blocks = DIV_ROUND_UP(stbuf->st_size, 512); + stbuf->st_blocks = DIV_ROUND_UP(blob_stored_size(blob), 512); return 0; } @@ -921,17 +940,20 @@ delete_staging_dir(struct wimfs_context *ctx) close(ctx->parent_dir_fd); } -/* Number the inodes in the mounted image sequentially. */ static void -reassign_inode_numbers(struct wimfs_context *ctx) +prepare_inodes(struct wimfs_context *ctx) { struct wim_image_metadata *imd; struct wim_inode *inode; ctx->next_ino = 1; imd = wim_get_current_image_metadata(ctx->wim); - image_for_each_inode(inode, imd) + image_for_each_inode(inode, imd) { inode->i_ino = ctx->next_ino++; + inode->i_num_opened_fds = 0; + inode->i_num_allocated_fds = 0; + inode->i_fds = NULL; + } } static void @@ -983,12 +1005,13 @@ inode_close_fds(struct wim_inode *inode) static void close_all_fds(struct wimfs_context *ctx) { - struct wim_inode *inode, *tmp; + struct wim_inode *inode; + struct hlist_node *tmp; struct wim_image_metadata *imd; imd = wim_get_current_image_metadata(ctx->wim); - list_for_each_entry_safe(inode, tmp, &imd->inode_list, i_list) + image_for_each_inode_safe(inode, tmp, imd) inode_close_fds(inode); } @@ -1018,9 +1041,10 @@ renew_current_image(struct wimfs_context *ctx) new_blob = new_blob_descriptor(); if (!new_blob) goto err_put_replace_imd; + new_blob->refcnt = 1; - new_blob->flags = WIM_RESHDR_FLAG_METADATA; new_blob->unhashed = 1; + new_blob->is_metadata = 1; /* Make the image being moved available at a new index. Increments the * WIM's image count, but does not increment the reference count of the @@ -1572,7 +1596,7 @@ wimfs_open(const char *path, struct fuse_file_info *fi) (!blob || blob->blob_location != BLOB_IN_STAGING_FILE)) { ret = extract_blob_to_staging_dir(inode, strm, - blob ? blob->size : 0, + blob_size(blob), ctx); if (ret) return ret; @@ -1612,7 +1636,7 @@ wimfs_opendir(const char *path, struct fuse_file_info *fi) return -errno; if (!inode_is_directory(inode)) return -ENOTDIR; - strm = inode_get_unnamed_stream(inode, STREAM_TYPE_DATA); + strm = inode_get_unnamed_data_stream(inode); if (!strm) return -ENOTDIR; ret = alloc_wimfs_fd(inode, strm, &fd); @@ -2124,6 +2148,11 @@ wimlib_mount_image(WIMStruct *wim, int image, const char *dir, return ret; } + if (wim_has_solid_resources(wim)) { + WARNING("Mounting a WIM file containing solid-compressed data; " + "file access may be slow."); + } + /* If the user did not specify an interface for accessing named * data streams, use the default (extended attributes). */ if (!(mount_flags & (WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_NONE | @@ -2180,8 +2209,9 @@ wimlib_mount_image(WIMStruct *wim, int image, const char *dir, } } - /* Assign new inode numbers. */ - reassign_inode_numbers(&ctx); + /* Number the inodes in the mounted image sequentially and initialize + * the file descriptor arrays */ + prepare_inodes(&ctx); /* If a read-write mount, mark the image as modified. */ if (mount_flags & WIMLIB_MOUNT_FLAG_READWRITE)