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)
* @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;
*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;
}
/*
- * Creates a randomly named staging directory and returns its name into the
- * static variable staging_dir_name.
- *
- * If the staging directory cannot be created, staging_dir_name is set to NULL.
- * */
+ * Creates a randomly named staging directory and saves its name in the
+ * filesystem context structure.
+ */
static int make_staging_dir(struct wimfs_context *ctx)
{
/* XXX Give the user an option of where to stage files */
DEBUG("Closing all staging file descriptors.");
- list_for_each_entry(lte, &ctx->staging_list, staging_list) {
+ list_for_each_entry_safe(lte, tmp, &ctx->staging_list, staging_list) {
ret = inode_close_fds(lte->lte_inode);
if (ret != 0)
return ret;
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;
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;
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;
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;
}
} 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)
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;
}
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;
.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
};
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,
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;
}