struct wimfs_fd {
struct wim_inode *f_inode;
struct wim_lookup_table_entry *f_lte;
- int staging_fd;
+ struct filedes staging_fd;
u16 idx;
u32 stream_id;
};
/* Name and message queue descriptors for message queues between the
* filesystem daemon process and the unmount process. These are used
* when the filesystem is unmounted and the process running
- * wimlib_unmount_image() (i.e. the `imagex unmount' command) needs to
- * communicate with the filesystem daemon running fuse_main() (i.e. the
- * daemon created by the `imagex mount' or `imagex mountrw' commands */
+ * wimlib_unmount_image() needs to communicate with the filesystem
+ * daemon running fuse_main() (i.e. the process created by a call to
+ * wimlib_mount_image(). */
char *unmount_to_daemon_mq_name;
char *daemon_to_unmount_mq_name;
mqd_t unmount_to_daemon_mq;
static const u16 max_fds = 0xffff;
int ret;
- pthread_mutex_lock(&inode->i_mutex);
-
DEBUG("Allocating fd for stream ID %u from inode %#"PRIx64" "
"(open = %u, allocated = %u)",
stream_id, inode->i_ino, inode->i_num_opened_fds,
ret = -ENOMEM;
break;
}
- fd->f_inode = inode;
- fd->f_lte = lte;
- fd->staging_fd = -1;
- fd->idx = i;
- fd->stream_id = stream_id;
- *fd_ret = fd;
- inode->i_fds[i] = fd;
+ fd->f_inode = inode;
+ fd->f_lte = lte;
+ filedes_invalidate(&fd->staging_fd);
+ fd->idx = i;
+ fd->stream_id = stream_id;
+ *fd_ret = fd;
+ inode->i_fds[i] = fd;
inode->i_num_opened_fds++;
if (lte && !readonly)
lte->num_opened_fds++;
}
}
out:
- pthread_mutex_unlock(&inode->i_mutex);
return ret;
}
inode_put_fd(struct wim_inode *inode, struct wimfs_fd *fd)
{
wimlib_assert(inode != NULL);
-
- pthread_mutex_lock(&inode->i_mutex);
-
wimlib_assert(fd->f_inode == inode);
wimlib_assert(inode->i_num_opened_fds != 0);
wimlib_assert(fd->idx < inode->i_num_allocated_fds);
inode->i_fds[fd->idx] = NULL;
FREE(fd);
- if (--inode->i_num_opened_fds == 0 && inode->i_nlink == 0) {
- pthread_mutex_unlock(&inode->i_mutex);
- free_inode(inode);
- } else {
- pthread_mutex_unlock(&inode->i_mutex);
+ if (--inode->i_num_opened_fds == 0) {
+ FREE(inode->i_fds);
+ inode->i_fds = NULL;
+ inode->i_num_allocated_fds = 0;
+ if (inode->i_nlink == 0)
+ free_inode(inode);
}
}
/* Close staging file descriptor if needed. */
if (lte->resource_location == RESOURCE_IN_STAGING_FILE
- && fd->staging_fd != -1)
+ && filedes_valid(&fd->staging_fd))
{
- if (close(fd->staging_fd) != 0) {
+ if (filedes_close(&fd->staging_fd)) {
ERROR_WITH_ERRNO("Failed to close staging file");
return -errno;
}
/* Extract the stream to the staging file (possibly truncated) */
if (old_lte) {
+ struct filedes wimlib_fd;
+ filedes_init(&wimlib_fd, fd);
extract_size = min(wim_resource_size(old_lte), size);
- ret = extract_wim_resource_to_fd(old_lte, fd, extract_size);
+ ret = extract_wim_resource_to_fd(old_lte, &wimlib_fd,
+ extract_size);
} else {
ret = 0;
extract_size = 0;
struct wimfs_fd *fd = inode->i_fds[i];
if (fd) {
if (fd->stream_id == stream_id) {
+ int raw_fd;
+
wimlib_assert(fd->f_lte == old_lte);
- wimlib_assert(fd->staging_fd == -1);
+ wimlib_assert(!filedes_valid(&fd->staging_fd));
fd->f_lte = new_lte;
new_lte->num_opened_fds++;
- fd->staging_fd = open(staging_file_name, O_RDONLY);
- if (fd->staging_fd == -1) {
+ raw_fd = open(staging_file_name, O_RDONLY);
+ if (raw_fd < 0) {
ret = -errno;
goto out_revert_fd_changes;
}
+ filedes_init(&fd->staging_fd, raw_fd);
}
j++;
}
struct wimfs_fd *fd = inode->i_fds[i];
if (fd && fd->stream_id == stream_id && fd->f_lte == new_lte) {
fd->f_lte = old_lte;
- if (fd->staging_fd != -1) {
- close(fd->staging_fd);
- fd->staging_fd = -1;
+ if (filedes_valid(&fd->staging_fd)) {
+ filedes_close(&fd->staging_fd);
+ filedes_invalidate(&fd->staging_fd);
}
j++;
}
{
int ret;
struct wim_lookup_table_entry *lte, *tmp;
- WIMStruct *w = ctx->wim;
+ WIMStruct *wim = ctx->wim;
struct wim_image_metadata *imd = wim_get_current_image_metadata(ctx->wim);
DEBUG("Closing all staging file descriptors.");
}
}
- xml_update_image_info(w, w->current_image);
- ret = wimlib_overwrite(w, write_flags, 0, progress_func);
+ xml_update_image_info(wim, wim->current_image);
+ ret = wimlib_overwrite(wim, write_flags, 0, progress_func);
if (ret)
ERROR("Failed to commit changes to mounted WIM image");
return ret;
wimfs_ftruncate(const char *path, off_t size, struct fuse_file_info *fi)
{
struct wimfs_fd *fd = (struct wimfs_fd*)(uintptr_t)fi->fh;
- int ret = ftruncate(fd->staging_fd, size);
+ int ret = ftruncate(fd->staging_fd.fd, size);
if (ret)
return -errno;
touch_inode(fd->f_inode);
return -ERANGE;
ret = read_full_resource_into_buf(lte, value);
- if (ret)
- return -EIO;
-
+ if (ret) {
+ if (errno)
+ return -errno;
+ else
+ return -EIO;
+ }
return res_size;
}
#endif
struct wim_dentry *from_dentry, *from_dentry_parent;
const char *link_name;
struct wim_inode *inode;
- WIMStruct *w = wimfs_get_WIMStruct();
+ WIMStruct *wim = wimfs_get_WIMStruct();
int ret;
- inode = wim_pathname_to_inode(w, to);
+ inode = wim_pathname_to_inode(wim, to);
if (!inode)
return -errno;
FILE_ATTRIBUTE_REPARSE_POINT))
return -EPERM;
- from_dentry_parent = get_parent_dentry(w, from);
+ from_dentry_parent = get_parent_dentry(wim, from);
if (!from_dentry_parent)
return -errno;
if (!dentry_is_directory(from_dentry_parent))
return ret;
if (lte && lte->resource_location == RESOURCE_IN_STAGING_FILE) {
- fd->staging_fd = open(lte->staging_file_name, fi->flags);
- if (fd->staging_fd == -1) {
+ int raw_fd;
+
+ raw_fd = open(lte->staging_file_name, fi->flags);
+ if (raw_fd < 0) {
int errno_save = errno;
close_wimfs_fd(fd);
return -errno_save;
}
+ filedes_init(&fd->staging_fd, raw_fd);
}
fi->fh = (uintptr_t)fd;
return 0;
int ret;
struct wimfs_fd *fd = NULL;
struct wimfs_context *ctx = wimfs_get_context();
- WIMStruct *w = ctx->wim;
+ WIMStruct *wim = ctx->wim;
- inode = wim_pathname_to_inode(w, path);
+ inode = wim_pathname_to_inode(wim, path);
if (!inode)
return -errno;
if (!inode_is_directory(inode))
switch (fd->f_lte->resource_location) {
case RESOURCE_IN_STAGING_FILE:
- ret = full_pread(fd->staging_fd, buf, size, offset);
- if (ret != size)
+ ret = raw_pread(&fd->staging_fd, buf, size, offset);
+ if (ret == -1)
ret = -errno;
break;
case RESOURCE_IN_WIM:
return -EINVAL;
if (buf_len == 0)
return -ENAMETOOLONG;
- ret = wim_inode_readlink(inode, buf, buf_len - 1);
+ ret = wim_inode_readlink(inode, buf, buf_len - 1, NULL);
if (ret >= 0) {
wimlib_assert(ret <= buf_len - 1);
buf[ret] = '\0';
wimfs_rmdir(const char *path)
{
struct wim_dentry *dentry;
- WIMStruct *w = wimfs_get_WIMStruct();
+ WIMStruct *wim = wimfs_get_WIMStruct();
- dentry = get_dentry(w, path);
+ dentry = get_dentry(wim, path);
if (!dentry)
return -errno;
if (dentry_has_children(dentry))
return -ENOTEMPTY;
- remove_dentry(dentry, w->lookup_table);
+ remove_dentry(dentry, wim->lookup_table);
return 0;
}
if (lte == NULL && size == 0)
return 0;
- if (lte->resource_location == RESOURCE_IN_STAGING_FILE) {
+ if (lte != NULL && lte->resource_location == RESOURCE_IN_STAGING_FILE) {
ret = truncate(lte->staging_file_name, size);
if (ret)
ret = -errno;
{
struct wim_dentry *dentry;
struct wim_inode *inode;
- WIMStruct *w = wimfs_get_WIMStruct();
+ WIMStruct *wim = wimfs_get_WIMStruct();
- dentry = get_dentry(w, path);
+ dentry = get_dentry(wim, path);
if (!dentry)
return -errno;
inode = dentry->d_inode;
{
struct wim_dentry *dentry;
struct wim_inode *inode;
- WIMStruct *w = wimfs_get_WIMStruct();
+ WIMStruct *wim = wimfs_get_WIMStruct();
- dentry = get_dentry(w, path);
+ dentry = get_dentry(wim, path);
if (!dentry)
return -errno;
inode = dentry->d_inode;
wimlib_assert(fd->f_lte != NULL);
wimlib_assert(fd->f_lte->staging_file_name != NULL);
- wimlib_assert(fd->staging_fd != -1);
+ wimlib_assert(filedes_valid(&fd->staging_fd));
wimlib_assert(fd->f_inode != NULL);
/* Write the data. */
- ret = full_pwrite(fd->staging_fd, buf, size, offset);
- if (ret != size)
+ ret = raw_pwrite(&fd->staging_fd, buf, size, offset);
+ if (ret == -1)
return -errno;
/* Update file size */
};
-/* Mounts an image from a WIM file. */
+/* API function documented in wimlib.h */
WIMLIBAPI int
wimlib_mount_image(WIMStruct *wim, int image, const char *dir,
int mount_flags, WIMStruct **additional_swms,
if (ret)
goto out;
- if ((mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) && (wim->hdr.total_parts != 1)) {
- ERROR("Cannot mount a split WIM read-write");
- ret = WIMLIB_ERR_SPLIT_UNSUPPORTED;
- goto out;
- }
-
- if (num_additional_swms)
- merge_lookup_tables(wim, additional_swms, num_additional_swms);
-
if (mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) {
- ret = wim_run_full_verifications(wim);
+ ret = can_delete_from_wim(wim);
if (ret)
- goto out_restore_lookup_table;
+ goto out;
}
- ret = wim_checksum_unhashed_streams(wim);
- if (ret)
- goto out_restore_lookup_table;
+ if (num_additional_swms)
+ merge_lookup_tables(wim, additional_swms, num_additional_swms);
ret = select_wim_image(wim, image);
if (ret)
}
if (mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) {
- ret = lock_wim(wim, wim->in_fd);
+ ret = lock_wim(wim, wim->in_fd.fd);
if (ret)
goto out_restore_lookup_table;
}
goto out_free_message_queue_names;
argc = 0;
- argv[argc++] = "imagex";
+ argv[argc++] = "wimlib";
argv[argc++] = dir_copy;
- /* disable multi-threaded operation for read-write mounts */
- if (mount_flags & WIMLIB_MOUNT_FLAG_READWRITE)
- argv[argc++] = "-s";
+ /* disable multi-threaded operation */
+ argv[argc++] = "-s";
if (mount_flags & WIMLIB_MOUNT_FLAG_DEBUG)
argv[argc++] = "-d";
* assign inode numbers */
DEBUG("Resolving lookup table entries and assigning inode numbers");
ctx.next_ino = 1;
- image_for_each_inode(inode, imd) {
- inode_resolve_ltes(inode, wim->lookup_table);
+ image_for_each_inode(inode, imd)
inode->i_ino = ctx.next_ino++;
- }
DEBUG("(next_ino = %"PRIu64")", ctx.next_ino);
DEBUG("Calling fuse_main()");
return ret;
}
-/*
- * Unmounts the WIM file that was previously mounted on @dir by using
- * wimlib_mount_image().
- */
+/* API function documented in wimlib.h */
WIMLIBAPI int
wimlib_unmount_image(const char *dir, int unmount_flags,
wimlib_progress_func_t progress_func)