X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;ds=sidebyside;f=src%2Fmount.c;h=15d7444ed3036dc182712bed85fde61feaefc77e;hb=5bae0e225874077fe8aa06a5649aa7bc45d9ef8f;hp=44857c8c8783972efd1de4f7626fe239504e021f;hpb=44faa9130b1a6082f37501377c01d23604030fa5;p=wimlib diff --git a/src/mount.c b/src/mount.c index 44857c8c..15d7444e 100644 --- a/src/mount.c +++ b/src/mount.c @@ -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(<e->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");