]> wimlib.net Git - wimlib/blobdiff - src/mount_image.c
encoding.c: Upgrade upcase table and rewrite decompression code
[wimlib] / src / mount_image.c
index 7fe8bb537fb1621a5e5742fba40aa98ed8347dde..8037a38f0da5b6a89dc24f2fb08fe78bde78e26a 100644 (file)
@@ -39,6 +39,8 @@
 
 #define FUSE_USE_VERSION 26
 
+#include <sys/types.h> /* sometimes required before <attr/xattr.h> */
+
 #include <attr/xattr.h>
 #include <dirent.h>
 #include <errno.h>
@@ -50,7 +52,6 @@
 #include <string.h>
 #include <sys/stat.h>
 #include <sys/time.h>
-#include <sys/types.h>
 #include <unistd.h>
 #include <utime.h>
 
@@ -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)