]> wimlib.net Git - wimlib/blobdiff - src/mount.c
Fix sequential extraction, and include progress info
[wimlib] / src / mount.c
index 44857c8c8783972efd1de4f7626fe239504e021f..15d7444ed3036dc182712bed85fde61feaefc77e 100644 (file)
@@ -115,6 +115,11 @@ static inline WIMStruct *wimfs_get_WIMStruct()
        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)
 {
        if (ctx->mount_flags & WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_WINDOWS)
@@ -136,13 +141,15 @@ static inline int 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.
  */
 static int alloc_wimlib_fd(struct inode *inode,
                           u32 stream_id,
                           struct lookup_table_entry *lte,
-                          struct wimlib_fd **fd_ret)
+                          struct wimlib_fd **fd_ret,
+                          bool readonly)
 {
        static const u16 fds_per_alloc = 8;
        static const u16 max_fds = 0xffff;
@@ -192,8 +199,8 @@ static int alloc_wimlib_fd(struct inode *inode,
                        *fd_ret        = fd;
                        inode->fds[i]  = fd;
                        inode->num_opened_fds++;
-                       if (lte)
-                               atomic_inc(&lte->num_opened_fds);
+                       if (lte && !readonly)
+                               lte->num_opened_fds++;
                        DEBUG("Allocated fd (idx = %u)", fd->idx);
                        ret = 0;
                        break;
@@ -889,7 +896,7 @@ static int rebuild_wim(struct wimfs_context *ctx, bool check_integrity)
 
        xml_update_image_info(w, w->current_image);
 
-       ret = wimlib_overwrite(w, check_integrity);
+       ret = wimlib_overwrite(w, check_integrity, 0);
        if (ret != 0) {
                ERROR("Failed to commit changes");
                return ret;
@@ -1056,7 +1063,8 @@ static int wimfs_getxattr(const char *path, const char *name, char *value,
        if (res_size > size)
                return -ERANGE;
 
-       ret = read_full_wim_resource(lte, (u8*)value);
+       ret = read_full_wim_resource(lte, (u8*)value,
+                                    WIMLIB_RESOURCE_FLAG_MULTITHREADED);
        if (ret != 0)
                return -EIO;
 
@@ -1268,7 +1276,8 @@ static int wimfs_open(const char *path, struct fuse_file_info *fi)
                        return ret;
        }
 
-       ret = alloc_wimlib_fd(inode, stream_id, lte, &fd);
+       ret = alloc_wimlib_fd(inode, stream_id, lte, &fd,
+                             wimfs_ctx_readonly(ctx));
        if (ret != 0)
                return ret;
 
@@ -1289,14 +1298,15 @@ static int wimfs_opendir(const char *path, struct fuse_file_info *fi)
        struct inode *inode;
        int ret;
        struct wimlib_fd *fd = NULL;
-       WIMStruct *w = wimfs_get_WIMStruct();
+       struct wimfs_context *ctx = wimfs_get_context();
+       WIMStruct *w = ctx->wim;
 
        inode = wim_pathname_to_inode(w, path);
        if (!inode)
                return -ENOENT;
        if (!inode_is_directory(inode))
                return -ENOTDIR;
-       ret = alloc_wimlib_fd(inode, 0, NULL, &fd);
+       ret = alloc_wimlib_fd(inode, 0, NULL, &fd, wimfs_ctx_readonly(ctx));
        fi->fh = (uintptr_t)fd;
        return ret;
 }
@@ -1334,6 +1344,8 @@ static int wimfs_read(const char *path, char *buf, size_t size,
        } else {
                /* Read from WIM */
 
+               wimlib_assert(fd->f_lte->resource_location == RESOURCE_IN_WIM);
+
                u64 res_size = wim_resource_size(fd->f_lte);
 
                if (offset > res_size)
@@ -1342,7 +1354,8 @@ static int wimfs_read(const char *path, char *buf, size_t size,
                size = min(size, res_size - offset);
 
                if (read_wim_resource(fd->f_lte, (u8*)buf,
-                                     size, offset, false) != 0)
+                                     size, offset,
+                                     WIMLIB_RESOURCE_FLAG_MULTITHREADED) != 0)
                        return -EIO;
                return size;
        }
@@ -1396,7 +1409,8 @@ static int wimfs_readlink(const char *path, char *buf, size_t buf_len)
        if (!inode_is_symlink(inode))
                return -EINVAL;
 
-       ret = inode_readlink(inode, buf, buf_len, ctx->wim);
+       ret = inode_readlink(inode, buf, buf_len, ctx->wim,
+                            WIMLIB_RESOURCE_FLAG_MULTITHREADED);
        if (ret > 0)
                ret = 0;
        return ret;
@@ -1828,6 +1842,14 @@ static struct fuse_operations wimfs_operations = {
        .utime       = wimfs_utime,
 #endif
        .write       = wimfs_write,
+
+#if FUSE_MAJOR_VERSION > 2 || (FUSE_MAJOR_VERSION == 2 && FUSE_MINOR_VERSION >= 8)
+       .flag_nullpath_ok = 1,
+#endif
+#if FUSE_MAJOR_VERSION > 2 || (FUSE_MAJOR_VERSION == 2 && FUSE_MINOR_VERSION >= 9)
+       .flag_nopath = 1,
+       .flag_utime_omit_ok = 1,
+#endif
 };
 
 
@@ -1854,6 +1876,11 @@ WIMLIBAPI int wimlib_mount(WIMStruct *wim, int image, const char *dir,
        if (ret != 0)
                return ret;
 
+       if ((flags & WIMLIB_MOUNT_FLAG_READWRITE) && (wim->hdr.total_parts != 1)) {
+               ERROR("Cannot mount a split WIM read-write");
+               return WIMLIB_ERR_SPLIT_UNSUPPORTED;
+       }
+
        if (num_additional_swms) {
                ret = new_joined_lookup_table(wim, additional_swms,
                                              num_additional_swms,
@@ -1875,7 +1902,14 @@ WIMLIBAPI int wimlib_mount(WIMStruct *wim, int image, const char *dir,
 
        if (imd->root_dentry->refcnt != 1) {
                ERROR("Cannot mount image that was just exported with "
-                     "wimlib_export()");
+                     "wimlib_export_image()");
+               ret = WIMLIB_ERR_INVALID_PARAM;
+               goto out;
+       }
+
+       if (imd->modified) {
+               ERROR("Cannot mount image that was added "
+                     "with wimlib_add_image()");
                ret = WIMLIB_ERR_INVALID_PARAM;
                goto out;
        }
@@ -1953,8 +1987,10 @@ WIMLIBAPI int wimlib_mount(WIMStruct *wim, int image, const char *dir,
 #endif
 
        /* Mark dentry tree as modified if read-write mount. */
-       if (flags & WIMLIB_MOUNT_FLAG_READWRITE)
+       if (flags & WIMLIB_MOUNT_FLAG_READWRITE) {
                imd->modified = true;
+               imd->has_been_mounted_rw = true;
+       }
 
        /* Resolve all the lookup table entries of the dentry tree */
        DEBUG("Resolving lookup table entries");