#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"
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)
{
* @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.
*/
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;
*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;
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;
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);
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.
*
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;
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
"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;
}
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);
*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;
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;
}
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);
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 */
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;
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;
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;
if (!wim || !dir)
return WIMLIB_ERR_INVALID_PARAM;
+ if (mount_flags & ~(WIMLIB_MOUNT_FLAG_READWRITE |
+ WIMLIB_MOUNT_FLAG_DEBUG |
+ WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_NONE |
+ WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_XATTR |
+ WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_WINDOWS |
+ WIMLIB_MOUNT_FLAG_UNIX_DATA |
+ WIMLIB_MOUNT_FLAG_ALLOW_OTHER))
+ return WIMLIB_ERR_INVALID_PARAM;
+
if (mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) {
ret = can_delete_from_wim(wim);
if (ret)
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;
}
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;
int ret;
struct wimfs_context wimfs_ctx;
+ if (unmount_flags & ~(WIMLIB_UNMOUNT_FLAG_CHECK_INTEGRITY |
+ WIMLIB_UNMOUNT_FLAG_COMMIT |
+ WIMLIB_UNMOUNT_FLAG_REBUILD |
+ WIMLIB_UNMOUNT_FLAG_RECOMPRESS |
+ WIMLIB_UNMOUNT_FLAG_LAZY))
+ return WIMLIB_ERR_INVALID_PARAM;
+
init_wimfs_context(&wimfs_ctx);
ret = set_message_queue_names(&wimfs_ctx, dir);