X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fmount.c;h=bd02cec6ae3f1168cb853d779dca38462c06cd42;hb=46987f6ff2d27b0224f0ccab1b1e91164cae1d86;hp=0c1b5ebd0b5a83eaa832175601912b76a44dc575;hpb=885632f08c75c1d7bb5d25436231c78f6ad7e0c0;p=wimlib diff --git a/src/mount.c b/src/mount.c index 0c1b5ebd..bd02cec6 100644 --- a/src/mount.c +++ b/src/mount.c @@ -374,10 +374,6 @@ static int rebuild_wim(WIMStruct *w, bool check_integrity) ERROR("Failed to commit changes\n"); return ret; } - ret = delete_staging_dir(); - if (ret != 0) { - ERROR("Failed to delete the staging directory: %m\n"); - } return ret; } @@ -431,22 +427,28 @@ static void wimfs_destroy(void *p) DEBUG("Received message: [%d %d]\n", msg[0], msg[1]); } - if (commit && (mount_flags & WIMLIB_MOUNT_FLAG_READWRITE)) { - status = chdir(working_directory); - if (status != 0) { - ERROR("chdir(): %m\n"); - status = WIMLIB_ERR_NOTDIR; - goto done; + status = 0; + if (mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) { + if (commit) { + status = chdir(working_directory); + if (status != 0) { + ERROR("chdir(): %m\n"); + status = WIMLIB_ERR_NOTDIR; + goto done; + } + status = rebuild_wim(w, (check_integrity != 0)); + } + ret = delete_staging_dir(); + if (ret != 0) { + ERROR("Failed to delete the staging directory: %m\n"); + if (status == 0) + status = ret; } - status = rebuild_wim(w, (check_integrity != 0)); - } else { - status = 0; } done: ret = mq_send(daemon_to_unmount_mq, &status, 1, 1); - if (ret == -1) { + if (ret == -1) ERROR("Failed to send status to unmount process: %m\n"); - } close_message_queues(); } @@ -532,6 +534,8 @@ static int create_staging_file(char **name_ret) /* doesn't exist--- ok */ } + DEBUG("Creating staging file '%s'\n", name); + fd = creat(name, 0600); if (fd == -1) { errno_save = errno; @@ -610,19 +614,41 @@ static int wimfs_open(const char *path, struct fuse_file_info *fi) if (dentry_is_directory(dentry)) return -EISDIR; lte = wim_lookup_resource(w, dentry); - if (!lte) - return 0; - - if (lte->staging_file_name) { + if (lte) { /* If this file is in the staging directory and the file is not * currently open, open it. */ - if (lte->staging_num_times_opened == 0) { + if (lte->staging_file_name && lte->staging_num_times_opened == 0) { lte->staging_fd = open(lte->staging_file_name, O_RDWR); if (lte->staging_fd == -1) return -errno; lte->staging_offset = 0; - } + } + } else { + /* no lookup table entry, so the file must be empty. Create a + * lookup table entry for the file. */ + char *tmpfile_name; + int err; + int fd; + + lte = new_lookup_table_entry(); + if (!lte) + return -ENOMEM; + + fd = create_staging_file(&tmpfile_name); + + if (fd == -1) { + err = errno; + free(lte); + return -errno; + } + lte->resource_entry.original_size = 0; + randomize_byte_array(lte->hash, WIM_HASH_SIZE); + memcpy(dentry->hash, lte->hash, WIM_HASH_SIZE); + lte->staging_file_name = tmpfile_name; + lte->staging_fd = fd; + lte->staging_offset = 0; + lookup_table_insert(w->lookup_table, lte); } lte->staging_num_times_opened++; return 0; @@ -905,8 +931,9 @@ static int wimfs_truncate(const char *path, off_t size) if (!dentry) return -EEXIST; lte = wim_lookup_resource(w, dentry); - if (!lte) - return -EEXIST; + + if (!lte) /* Already a zero-length file */ + return 0; if (lte->staging_file_name) { /* File on disk. Call POSIX API */ if (lte->staging_num_times_opened != 0) @@ -963,8 +990,10 @@ static int wimfs_write(const char *path, const char *buf, size_t size, if (!dentry) return -EEXIST; lte = wim_lookup_resource(w, dentry); - if (!lte) + + if (!lte) /* this should not happen */ return -EEXIST; + if (lte->staging_num_times_opened == 0) return -EBADF; if (lte->staging_file_name) {