]> wimlib.net Git - wimlib/blobdiff - src/mount_image.c
Refactor some of the dentry, inode, and lookup table code
[wimlib] / src / mount_image.c
index 7543b6e424b67770a7d35376b753f3e7b76386a1..7c480ebc76c02c7af9808b87f151c5188a8506ae 100644 (file)
@@ -41,6 +41,8 @@
 
 #include "wimlib/encoding.h"
 #include "wimlib/file_io.h"
+#include "wimlib/dentry.h"
+#include "wimlib/inode.h"
 #include "wimlib/lookup_table.h"
 #include "wimlib/metadata.h"
 #include "wimlib/paths.h"
@@ -152,12 +154,6 @@ wimfs_get_WIMStruct(void)
        return wimfs_get_context()->wim;
 }
 
-static inline bool
-wimfs_ctx_readonly(const struct wimfs_context *ctx)
-{
-       return (ctx->mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) == 0;
-}
-
 static inline int
 get_lookup_flags(const struct wimfs_context *ctx)
 {
@@ -178,7 +174,6 @@ flags_writable(int open_flags)
  * @stream_id: ID of the stream we're opening
  * @lte:       Lookup table entry for the stream (may be NULL)
  * @fd_ret:    Return the allocated file descriptor if successful.
- * @readonly:  True if this is a read-only mount.
  *
  * Return 0 iff successful or error code if unsuccessful.
  */
@@ -186,8 +181,7 @@ static int
 alloc_wimfs_fd(struct wim_inode *inode,
               u32 stream_id,
               struct wim_lookup_table_entry *lte,
-              struct wimfs_fd **fd_ret,
-              bool readonly)
+              struct wimfs_fd **fd_ret)
 {
        static const u16 fds_per_alloc = 8;
        static const u16 max_fds = 0xffff;
@@ -236,7 +230,7 @@ alloc_wimfs_fd(struct wim_inode *inode,
                        *fd_ret         = fd;
                        inode->i_fds[i] = fd;
                        inode->i_num_opened_fds++;
-                       if (lte && !readonly)
+                       if (lte)
                                lte->num_opened_fds++;
                        DEBUG("Allocated fd (idx = %u)", fd->idx);
                        ret = 0;
@@ -329,7 +323,7 @@ create_dentry(struct fuse_context *fuse_ctx, const char *path,
        struct wimfs_context *wimfs_ctx = WIMFS_CTX(fuse_ctx);
        int ret;
 
-       parent = get_parent_dentry(wimfs_ctx->wim, path);
+       parent = get_parent_dentry(wimfs_ctx->wim, path, WIMLIB_CASE_SENSITIVE);
        if (!parent)
                return -errno;
 
@@ -337,7 +331,7 @@ create_dentry(struct fuse_context *fuse_ctx, const char *path,
                return -ENOTDIR;
 
        basename = path_basename(path);
-       if (get_dentry_child_with_name(parent, basename))
+       if (get_dentry_child_with_name(parent, basename, WIMLIB_CASE_SENSITIVE))
                return -EEXIST;
 
        ret = new_dentry_with_inode(basename, &new);
@@ -367,6 +361,17 @@ create_dentry(struct fuse_context *fuse_ctx, const char *path,
        return 0;
 }
 
+static struct wim_inode *
+wim_pathname_to_inode(WIMStruct *wim, const tchar *path)
+{
+       struct wim_dentry *dentry;
+       dentry = get_dentry(wim, path, WIMLIB_CASE_SENSITIVE);
+       if (dentry)
+               return dentry->d_inode;
+       else
+               return NULL;
+}
+
 /* Remove a dentry from a mounted WIM image; i.e. remove an alias for the
  * corresponding inode.
  *
@@ -667,8 +672,8 @@ extract_resource_to_staging_dir(struct wim_inode *inode,
        new_lte->staging_file_name   = staging_file_name;
        new_lte->size                = size;
 
-       lookup_table_insert_unhashed(ctx->wim->lookup_table, new_lte,
-                                    inode, stream_id);
+       add_unhashed_stream(new_lte, inode, stream_id,
+                           &wim_get_current_image_metadata(ctx->wim)->unhashed_streams);
        *retrieve_lte_pointer(new_lte) = new_lte;
        *lte = new_lte;
        return 0;
@@ -1293,25 +1298,19 @@ msg_unmount_finished_handler(const void *_msg, void *_handler_ctx)
 static int
 unmount_timed_out_cb(void *_handler_ctx)
 {
-       struct unmount_msg_handler_context *handler_ctx = _handler_ctx;
+       const struct unmount_msg_handler_context *handler_ctx = _handler_ctx;
 
-       if (handler_ctx->daemon_pid == 0) {
-               goto out_crashed;
-       } else {
-               kill(handler_ctx->daemon_pid, 0);
-               if (errno == ESRCH) {
-                       goto out_crashed;
-               } else {
-                       DEBUG("Filesystem daemon is still alive... "
-                             "Waiting another %d seconds\n",
-                             handler_ctx->hdr.timeout_seconds);
-                       return 0;
-               }
+       if (handler_ctx->daemon_pid == 0 ||
+           (kill(handler_ctx->daemon_pid, 0) != 0 && errno == ESRCH))
+       {
+               ERROR("The filesystem daemon has crashed!  Changes to the "
+                     "WIM may not have been commited.");
+               return WIMLIB_ERR_FILESYSTEM_DAEMON_CRASHED;
        }
-out_crashed:
-       ERROR("The filesystem daemon has crashed!  Changes to the "
-             "WIM may not have been commited.");
-       return WIMLIB_ERR_FILESYSTEM_DAEMON_CRASHED;
+
+       DEBUG("Filesystem daemon is still alive... "
+             "Waiting another %d seconds", handler_ctx->hdr.timeout_seconds);
+       return 0;
 }
 
 static int
@@ -1521,10 +1520,12 @@ execute_fusermount(const char *dir, bool lazy)
                                 "terminate");
                return WIMLIB_ERR_FUSERMOUNT;
        }
-       if (status != 0) {
+
+       if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
                ERROR("`umount' did not successfully complete");
                return WIMLIB_ERR_FUSERMOUNT;
        }
+
        return 0;
 }
 
@@ -1695,14 +1696,15 @@ wimfs_link(const char *to, const char *from)
                                   FILE_ATTRIBUTE_REPARSE_POINT))
                return -EPERM;
 
-       from_dentry_parent = get_parent_dentry(wim, from);
+       from_dentry_parent = get_parent_dentry(wim, from, WIMLIB_CASE_SENSITIVE);
        if (!from_dentry_parent)
                return -errno;
        if (!dentry_is_directory(from_dentry_parent))
                return -ENOTDIR;
 
        link_name = path_basename(from);
-       if (get_dentry_child_with_name(from_dentry_parent, link_name))
+       if (get_dentry_child_with_name(from_dentry_parent, link_name,
+                                      WIMLIB_CASE_SENSITIVE))
                return -EEXIST;
 
        ret = new_dentry(link_name, &from_dentry);
@@ -1864,8 +1866,7 @@ wimfs_open(const char *path, struct fuse_file_info *fi)
                *back_ptr = lte;
        }
 
-       ret = alloc_wimfs_fd(inode, stream_id, lte, &fd,
-                            wimfs_ctx_readonly(ctx));
+       ret = alloc_wimfs_fd(inode, stream_id, lte, &fd);
        if (ret)
                return ret;
 
@@ -1899,7 +1900,7 @@ wimfs_opendir(const char *path, struct fuse_file_info *fi)
                return -errno;
        if (!inode_is_directory(inode))
                return -ENOTDIR;
-       ret = alloc_wimfs_fd(inode, 0, NULL, &fd, wimfs_ctx_readonly(ctx));
+       ret = alloc_wimfs_fd(inode, 0, NULL, &fd);
        fi->fh = (uintptr_t)fd;
        return ret;
 }
@@ -1943,7 +1944,7 @@ wimfs_read(const char *path, char *buf, size_t size,
        case RESOURCE_IN_WIM:
                if (read_partial_wim_stream_into_buf(fd->f_lte, size,
                                                     offset, buf))
-                       ret = -errno;
+                       ret = errno ? -errno : -EIO;
                else
                        ret = size;
                break;
@@ -2023,7 +2024,7 @@ wimfs_readlink(const char *path, char *buf, size_t buf_len)
        if (!inode_is_symlink(inode))
                return -EINVAL;
        if (buf_len == 0)
-               return -ENAMETOOLONG;
+               return -EINVAL;
        ret = wim_inode_readlink(inode, buf, buf_len - 1, NULL);
        if (ret >= 0) {
                wimlib_assert(ret <= buf_len - 1);
@@ -2084,7 +2085,8 @@ wimfs_removexattr(const char *path, const char *name)
 static int
 wimfs_rename(const char *from, const char *to)
 {
-       return rename_wim_path(wimfs_get_WIMStruct(), from, to);
+       return rename_wim_path(wimfs_get_WIMStruct(), from, to,
+                              WIMLIB_CASE_SENSITIVE);
 }
 
 /* Remove a directory */
@@ -2094,7 +2096,7 @@ wimfs_rmdir(const char *path)
        struct wim_dentry *dentry;
        WIMStruct *wim = wimfs_get_WIMStruct();
 
-       dentry = get_dentry(wim, path);
+       dentry = get_dentry(wim, path, WIMLIB_CASE_SENSITIVE);
        if (!dentry)
                return -errno;
 
@@ -2262,7 +2264,7 @@ wimfs_utimens(const char *path, const struct timespec tv[2])
        struct wim_inode *inode;
        WIMStruct *wim = wimfs_get_WIMStruct();
 
-       dentry = get_dentry(wim, path);
+       dentry = get_dentry(wim, path, WIMLIB_CASE_SENSITIVE);
        if (!dentry)
                return -errno;
        inode = dentry->d_inode;
@@ -2289,7 +2291,7 @@ wimfs_utime(const char *path, struct utimbuf *times)
        struct wim_inode *inode;
        WIMStruct *wim = wimfs_get_WIMStruct();
 
-       dentry = get_dentry(wim, path);
+       dentry = get_dentry(wim, path, WIMLIB_CASE_SENSITIVE);
        if (!dentry)
                return -errno;
        inode = dentry->d_inode;
@@ -2422,15 +2424,12 @@ wimlib_mount_image(WIMStruct *wim, int image, const char *dir,
 
        imd = wim_get_current_image_metadata(wim);
 
-       if (imd->refcnt != 1) {
-               ERROR("Cannot mount image that was just exported with "
-                     "wimlib_export_image()");
-               return WIMLIB_ERR_INVALID_PARAM;
-       }
-
        if (imd->modified) {
-               ERROR("Cannot mount image that was added "
-                     "with wimlib_add_image()");
+               /* wimfs_read() only supports a limited number of stream
+                * locations, not including RESOURCE_IN_FILE_ON_DISK,
+                * RESOURCE_IN_NTFS_VOLUME, etc. that might appear if files were
+                * added to the WIM image.  */
+               ERROR("Cannot mount an image with newly added files!");
                return WIMLIB_ERR_INVALID_PARAM;
        }
 
@@ -2454,7 +2453,6 @@ wimlib_mount_image(WIMStruct *wim, int image, const char *dir,
        ctx.default_uid = getuid();
        ctx.default_gid = getgid();
        wimlib_assert(list_empty(&imd->unhashed_streams));
-       ctx.wim->lookup_table->unhashed_streams = &imd->unhashed_streams;
        if (mount_flags & WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_WINDOWS)
                ctx.default_lookup_flags = LOOKUP_FLAG_ADS_OK;