]> wimlib.net Git - wimlib/blobdiff - src/mount.c
Code to handle some weird siutations and bad WIMs
[wimlib] / src / mount.c
index 19e8d5d700a573b39063a8f69b89ae44daecece2..8763be1e2fbcc0307468caf462311c32ff633ca4 100644 (file)
@@ -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",
@@ -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);
@@ -780,13 +786,13 @@ static int update_lte_of_staging_file(struct lookup_table_entry *lte,
        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);
 
        duplicate_lte = __lookup_resource(table, hash);
@@ -805,8 +811,11 @@ static int update_lte_of_staging_file(struct lookup_table_entry *lte,
                        ERROR_WITH_ERRNO("Failed to stat `%s'", lte->staging_file_name);
                        return WIMLIB_ERR_STAT;
                }
+               wimlib_assert(&lte->file_on_disk == &lte->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);
        }
 
@@ -1158,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);
@@ -1202,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;
@@ -1219,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;
        }
@@ -1673,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 */