* 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);
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;
{
/*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);
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");
newdir = new_dentry(basename);
newdir->attributes |= FILE_ATTRIBUTE_DIRECTORY;
+ newdir->resolved = true;
link_dentry(newdir, parent);
return 0;
}
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;
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;
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;
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;