X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fmount_image.c;h=12b193e3ad1081f6ba2f73bfbd9f12e8b1004361;hb=52a908ca68284a4dfa89a884f547fd78d1543772;hp=d9a03a998febc11e2ecc2bb932d956a164be8551;hpb=279a9a65b2b92bada2db886bbb546d276987b677;p=wimlib diff --git a/src/mount_image.c b/src/mount_image.c index d9a03a99..12b193e3 100644 --- a/src/mount_image.c +++ b/src/mount_image.c @@ -80,7 +80,7 @@ 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; }; @@ -116,9 +116,9 @@ struct wimfs_context { /* 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; @@ -229,13 +229,13 @@ alloc_wimfs_fd(struct wim_inode *inode, 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++; @@ -259,8 +259,13 @@ inode_put_fd(struct wim_inode *inode, struct wimfs_fd *fd) inode->i_fds[fd->idx] = NULL; FREE(fd); - if (--inode->i_num_opened_fds == 0 && inode->i_nlink == 0) - free_inode(inode); + 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); + } } static int @@ -274,9 +279,9 @@ lte_put_fd(struct wim_lookup_table_entry *lte, struct wimfs_fd *fd) /* 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; } @@ -562,8 +567,11 @@ extract_resource_to_staging_dir(struct wim_inode *inode, /* 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; @@ -632,15 +640,18 @@ extract_resource_to_staging_dir(struct wim_inode *inode, 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++; } @@ -668,9 +679,9 @@ out_revert_fd_changes: 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++; } @@ -802,7 +813,7 @@ rebuild_wim(struct wimfs_context *ctx, int write_flags, { 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."); @@ -824,8 +835,8 @@ rebuild_wim(struct wimfs_context *ctx, int write_flags, } } - 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; @@ -1592,7 +1603,7 @@ static int 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); @@ -1657,9 +1668,12 @@ wimfs_getxattr(const char *path, const char *name, char *value, 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 @@ -1671,10 +1685,10 @@ wimfs_link(const char *to, const char *from) 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; @@ -1682,7 +1696,7 @@ wimfs_link(const char *to, const char *from) 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)) @@ -1853,12 +1867,15 @@ wimfs_open(const char *path, struct fuse_file_info *fi) 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; @@ -1872,9 +1889,9 @@ wimfs_opendir(const char *path, struct fuse_file_info *fi) 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)) @@ -1916,8 +1933,8 @@ wimfs_read(const char *path, char *buf, size_t size, 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: @@ -2004,7 +2021,7 @@ wimfs_readlink(const char *path, char *buf, size_t buf_len) 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'; @@ -2072,9 +2089,9 @@ static int 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; @@ -2084,7 +2101,7 @@ wimfs_rmdir(const char *path) if (dentry_has_children(dentry)) return -ENOTEMPTY; - remove_dentry(dentry, w->lookup_table); + remove_dentry(dentry, wim->lookup_table); return 0; } @@ -2179,7 +2196,7 @@ wimfs_truncate(const char *path, off_t size) 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; @@ -2240,9 +2257,9 @@ wimfs_utimens(const char *path, const struct timespec tv[2]) { 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; @@ -2267,9 +2284,9 @@ wimfs_utime(const char *path, struct utimbuf *times) { 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; @@ -2295,12 +2312,12 @@ wimfs_write(const char *path, const char *buf, size_t size, 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 */ @@ -2370,7 +2387,7 @@ static struct fuse_operations wimfs_operations = { }; -/* 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, @@ -2429,7 +2446,7 @@ wimlib_mount_image(WIMStruct *wim, int image, const char *dir, } 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; } @@ -2465,7 +2482,7 @@ wimlib_mount_image(WIMStruct *wim, int image, const char *dir, goto out_free_message_queue_names; argc = 0; - argv[argc++] = IMAGEX_PROGNAME; + argv[argc++] = "wimlib"; argv[argc++] = dir_copy; /* disable multi-threaded operation */ @@ -2562,10 +2579,7 @@ out: 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)