From: Eric Biggers Date: Mon, 20 Aug 2012 07:41:15 +0000 (-0500) Subject: Fixes X-Git-Tag: v1.0.0~120 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=8a7aa1e0e77c5fadb2ee4d062b90532f709f7883 Fixes --- diff --git a/src/lookup_table.h b/src/lookup_table.h index b59eff22..4ec44cd3 100644 --- a/src/lookup_table.h +++ b/src/lookup_table.h @@ -101,13 +101,9 @@ struct lookup_table_entry { * output_resource_entry is the struct resource_entry for the position of the * file resource when written to the output file. */ u32 out_refcnt; - union { - struct resource_entry output_resource_entry; - struct { - struct list_head staging_list; - struct list_head lte_group_list; - }; - }; + struct resource_entry output_resource_entry; + struct list_head lte_group_list; + struct list_head staging_list; }; extern struct lookup_table *new_lookup_table(size_t capacity); diff --git a/src/mount.c b/src/mount.c index 6d21e841..286eadbd 100644 --- a/src/mount.c +++ b/src/mount.c @@ -310,6 +310,8 @@ lte_extract_fds(struct lookup_table_entry *old_lte, u64 link_group) break; } } + DEBUG("old_lte: %u fds open; new_lte: %u fds open", + old_lte->num_opened_fds, new_lte->num_opened_fds); old_lte->num_opened_fds -= num_transferred_fds; new_lte->num_opened_fds = num_transferred_fds; new_lte->num_allocated_fds = num_transferred_fds; @@ -344,7 +346,7 @@ static void lte_transfer_stream_entries(struct lookup_table_entry *new_lte, { /*INIT_LIST_HEAD(&new_lte->lte_group_list);*/ if (stream_idx == 0) { - struct list_head *pos; + struct list_head *pos = &dentry->link_group_list; do { struct dentry *d; d = container_of(pos, struct dentry, link_group_list); @@ -873,8 +875,11 @@ static void wimfs_destroy(void *p) if (status == 0) status = ret; } + } else { + DEBUG("Read-only mount"); } done: + DEBUG("Sending status %u", status); ret = mq_send(daemon_to_unmount_mq, &status, 1, 1); if (ret == -1) ERROR_WITH_ERRNO("Failed to send status to unmount process"); @@ -1006,6 +1011,7 @@ static int wimfs_mkdir(const char *path, mode_t mode) newdir = new_dentry(basename); newdir->attributes |= FILE_ATTRIBUTE_DIRECTORY; + newdir->resolved = true; link_dentry(newdir, parent); return 0; } @@ -1052,6 +1058,8 @@ static int wimfs_mknod(const char *path, mode_t mode, dev_t rdev) return -ENOMEM; dentry->resolved = true; dentry->hard_link = next_link_group_id++; + dentry->lte_group_list.type = STREAM_TYPE_NORMAL; + INIT_LIST_HEAD(&dentry->lte_group_list.list); link_dentry(dentry, parent); } return 0; @@ -1385,6 +1393,7 @@ static int wimfs_symlink(const char *to, const char *from) list_add(&dentry->ads_entries[1].lte_group_list.list, <e->lte_group_list); dentry->ads_entries[1].lte = lte; + dentry->resolved = true; link_dentry(dentry, dentry_parent); return 0; @@ -1559,7 +1568,7 @@ WIMLIBAPI int wimlib_mount(WIMStruct *wim, int image, const char *dir, next_link_group_id = assign_link_groups(wim->image_metadata[image - 1].lgt); - resolve_lookup_table_entries(wim_root_dentry(wim), w->lookup_table); + resolve_lookup_table_entries(wim_root_dentry(wim), wim->lookup_table); if (flags & WIMLIB_MOUNT_FLAG_READWRITE) wim_get_current_image_metadata(wim)->modified = true; diff --git a/src/symlink.c b/src/symlink.c index c94ba750..f7fa10d4 100644 --- a/src/symlink.c +++ b/src/symlink.c @@ -126,26 +126,45 @@ out: return buf; } +static const struct lookup_table_entry * +dentry_first_lte(const struct dentry *dentry, const struct lookup_table *table) +{ + const struct lookup_table_entry *lte; + if (dentry->resolved) { + if (dentry->lte) + return dentry->lte; + for (u16 i = 0; i < dentry->num_ads; i++) + if (dentry->ads_entries[i].lte) + return dentry->ads_entries[i].lte; + } else { + const u8 *hash = dentry->hash; + u16 i = 0; + while (1) { + if ((lte = __lookup_resource(table, hash))) + break; + if (i == dentry->num_ads) + return NULL; + hash = dentry->ads_entries[i].hash; + i++; + } + } + return NULL; +} + /* Get the symlink target from a dentry that's already checked to be either a * "real" symlink or a junction point. */ ssize_t dentry_readlink(const struct dentry *dentry, char *buf, size_t buf_len, const WIMStruct *w) { - struct resource_entry *res_entry; - struct lookup_table_entry *lte; - u16 i = 0; - const u8 *hash = dentry->hash; + const struct resource_entry *res_entry; + const struct lookup_table_entry *lte; wimlib_assert(dentry_is_symlink(dentry)); - while (1) { - if ((lte = __lookup_resource(w->lookup_table, hash))) - break; - if (i == dentry->num_ads) - return -EIO; - hash = dentry->ads_entries[i].hash; - i++; - } + lte = dentry_first_lte(dentry, w->lookup_table); + if (!lte) + return -EIO; + res_entry = <e->resource_entry; if (res_entry->original_size > 10000) return -EIO;