X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fmount.c;h=8763be1e2fbcc0307468caf462311c32ff633ca4;hb=81be60d782a4b4b8ae2e40141fc42b6e0e2d2706;hp=adfb7d6649eced85c7c267732c8381be7134b0d7;hpb=b1c4e6a269ae4c969060e33685db12f76a204a58;p=wimlib diff --git a/src/mount.c b/src/mount.c index adfb7d66..8763be1e 100644 --- a/src/mount.c +++ b/src/mount.c @@ -143,14 +143,17 @@ static int close_wimlib_fd(struct wimlib_fd *fd) wimlib_assert(lte); wimlib_assert(lte->num_opened_fds); - if (lte->staging_file_name) { + if (lte->resource_location == RESOURCE_IN_STAGING_FILE) { + wimlib_assert(lte->staging_file_name); wimlib_assert(fd->staging_fd != -1); if (close(fd->staging_fd) != 0) return -errno; } if (--lte->num_opened_fds == 0 && lte->refcnt == 0) { - if (lte->staging_file_name) + if (lte->resource_location == RESOURCE_IN_STAGING_FILE) { + wimlib_assert(lte->staging_file_name); unlink(lte->staging_file_name); + } free_lookup_table_entry(lte); } wimlib_assert(lte->fds[fd->idx] == fd); @@ -205,7 +208,8 @@ int dentry_to_stbuf(const struct dentry *dentry, struct stat *stbuf) /* Use the size of the unnamed (default) file stream. */ lte = dentry_first_lte_resolved(dentry); if (lte) { - if (lte->staging_file_name) { + if (lte->resource_location == RESOURCE_IN_STAGING_FILE) { + wimlib_assert(lte->staging_file_name); struct stat native_stat; if (stat(lte->staging_file_name, &native_stat) != 0) { DEBUG("Failed to stat `%s': %m", @@ -220,9 +224,9 @@ int dentry_to_stbuf(const struct dentry *dentry, struct stat *stbuf) stbuf->st_size = 0; } - stbuf->st_atime = ms_timestamp_to_unix(dentry->last_access_time); - stbuf->st_mtime = ms_timestamp_to_unix(dentry->last_write_time); - stbuf->st_ctime = ms_timestamp_to_unix(dentry->creation_time); + stbuf->st_atime = wim_timestamp_to_unix(dentry->last_access_time); + stbuf->st_mtime = wim_timestamp_to_unix(dentry->last_write_time); + stbuf->st_ctime = wim_timestamp_to_unix(dentry->creation_time); stbuf->st_blocks = (stbuf->st_size + 511) / 512; return 0; } @@ -424,8 +428,7 @@ static int extract_resource_to_staging_dir(struct dentry *dentry, return -errno; if (old_lte) - ret = extract_resource_to_fd(w, &old_lte->resource_entry, fd, - size); + ret = extract_wim_resource_to_fd(old_lte, fd, size); else ret = 0; if (ret != 0 || close(fd) != 0) { @@ -488,6 +491,7 @@ static int extract_resource_to_staging_dir(struct dentry *dentry, new_lte->refcnt = link_group_size; random_hash(new_lte->hash); new_lte->staging_file_name = staging_file_name; + new_lte->resource_location = RESOURCE_IN_STAGING_FILE; lookup_table_insert(w->lookup_table, new_lte); list_add(&new_lte->staging_list, &staging_list); @@ -737,6 +741,8 @@ static int close_lte_fds(struct lookup_table_entry *lte) { for (u16 i = 0, j = 0; j < lte->num_opened_fds; i++) { if (lte->fds[i] && lte->fds[i]->staging_fd != -1) { + wimlib_assert(lte->resource_location == RESOURCE_IN_STAGING_FILE); + wimlib_assert(lte->staging_file_name); if (close(lte->fds[i]->staging_fd) != 0) { ERROR_WITH_ERRNO("Failed close file `%s'", lte->staging_file_name); @@ -772,19 +778,22 @@ static void lte_list_change_lte_ptr(struct lookup_table_entry *lte, } -static int calculate_sha1sum_of_staging_file(struct lookup_table_entry *lte, - struct lookup_table *table) +static int update_lte_of_staging_file(struct lookup_table_entry *lte, + struct lookup_table *table) { struct lookup_table_entry *duplicate_lte; int ret; u8 hash[SHA1_HASH_SIZE]; + struct stat stbuf; + + wimlib_assert(lte->resource_location == RESOURCE_IN_STAGING_FILE); + wimlib_assert(lte->staging_file_name); ret = sha1sum(lte->staging_file_name, hash); if (ret != 0) return ret; lookup_table_unlink(table, lte); - copy_hash(lte->hash, hash); duplicate_lte = __lookup_resource(table, hash); @@ -793,11 +802,20 @@ static int calculate_sha1sum_of_staging_file(struct lookup_table_entry *lte, lte_list_change_lte_ptr(lte, duplicate_lte); duplicate_lte->refcnt += lte->refcnt; - list_splice(&duplicate_lte->lte_group_list, - <e->lte_group_list); + list_splice(<e->lte_group_list, + &duplicate_lte->lte_group_list); free_lookup_table_entry(lte); } else { + if (stat(lte->staging_file_name, &stbuf) != 0) { + ERROR_WITH_ERRNO("Failed to stat `%s'", lte->staging_file_name); + return WIMLIB_ERR_STAT; + } + wimlib_assert(<e->file_on_disk == <e->staging_file_name); + lte->resource_location = RESOURCE_IN_FILE_ON_DISK; + copy_hash(lte->hash, hash); + lte->resource_entry.original_size = stbuf.st_size; + lte->resource_entry.size = stbuf.st_size; lookup_table_insert(table, lte); } @@ -822,7 +840,7 @@ static int rebuild_wim(WIMStruct *w, bool check_integrity) * lookup table entries. */ DEBUG("Calculating SHA1 checksums for all new staging files."); list_for_each_entry_safe(lte, tmp, &staging_list, staging_list) { - ret = calculate_sha1sum_of_staging_file(lte, w->lookup_table); + ret = update_lte_of_staging_file(lte, w->lookup_table); if (ret != 0) return ret; } @@ -1149,7 +1167,7 @@ static int wimfs_open(const char *path, struct fuse_file_info *fi) if (ret != 0) return ret; } - if (lte->staging_file_name) { + if (lte->resource_location == RESOURCE_IN_STAGING_FILE) { fd->staging_fd = open(lte->staging_file_name, fi->flags); if (fd->staging_fd == -1) { close_wimlib_fd(fd); @@ -1193,9 +1211,10 @@ static int wimfs_read(const char *path, char *buf, size_t size, wimlib_assert(fd->lte); - if (fd->lte->staging_file_name) { + if (fd->lte->resource_location == RESOURCE_IN_STAGING_FILE) { /* Read from staging file */ + wimlib_assert(fd->lte->staging_file_name); wimlib_assert(fd->staging_fd != -1); ssize_t ret; @@ -1210,22 +1229,16 @@ static int wimfs_read(const char *path, char *buf, size_t size, } else { /* Read from WIM */ - struct resource_entry *res_entry; - int ctype; + const struct resource_entry *res_entry; res_entry = &fd->lte->resource_entry; - ctype = wim_resource_compression_type(w, res_entry); - if (offset > res_entry->original_size) return -EOVERFLOW; size = min(size, res_entry->original_size - offset); - if (read_resource(w->fp, res_entry->size, - res_entry->original_size, - res_entry->offset, ctype, size, - offset, buf) != 0) + if (read_wim_resource(fd->lte, buf, size, offset, false) != 0) return -EIO; return size; } @@ -1286,7 +1299,7 @@ static int wimfs_release(const char *path, struct fuse_file_info *fi) } if (flags_writable(fi->flags) && fd->dentry) { - u64 now = get_timestamp(); + u64 now = get_wim_timestamp(); fd->dentry->last_access_time = now; fd->dentry->last_write_time = now; } @@ -1513,20 +1526,28 @@ static int wimfs_unlink(const char *path) return 0; } -/* Change the timestamp on a file dentry. +/* + * Change the timestamp on a file dentry. * - * There is no distinction between a file and its alternate data streams here. */ + * Note that alternate data streams do not have their own timestamps. + */ static int wimfs_utimens(const char *path, const struct timespec tv[2]) { struct dentry *dentry = get_dentry(w, path); if (!dentry) return -ENOENT; - time_t last_access_t = (tv[0].tv_nsec == UTIME_NOW) ? - time(NULL) : tv[0].tv_sec; - dentry->last_access_time = unix_timestamp_to_ms(last_access_t); - time_t last_mod_t = (tv[1].tv_nsec == UTIME_NOW) ? - time(NULL) : tv[1].tv_sec; - dentry->last_write_time = unix_timestamp_to_ms(last_mod_t); + if (tv[0].tv_nsec != UTIME_OMIT) { + if (tv[0].tv_nsec == UTIME_NOW) + dentry->last_access_time = get_wim_timestamp(); + else + dentry->last_access_time = timespec_to_wim_timestamp(&tv[0]); + } + if (tv[1].tv_nsec != UTIME_OMIT) { + if (tv[1].tv_nsec == UTIME_NOW) + dentry->last_write_time = get_wim_timestamp(); + else + dentry->last_write_time = timespec_to_wim_timestamp(&tv[1]); + } return 0; } @@ -1656,7 +1677,7 @@ WIMLIBAPI int wimlib_mount(WIMStruct *wim, int image, const char *dir, if (!p) return WIMLIB_ERR_NOMEM; - argv[argc++] = "mount"; + argv[argc++] = "imagex"; argv[argc++] = p; argv[argc++] = "-s"; /* disable multi-threaded operation */