#include "wimlib_internal.h"
#include "lookup_table.h"
#include "io.h"
+#include <errno.h>
struct lookup_table *new_lookup_table(size_t capacity)
{
}
+void free_lookup_table_entry(struct lookup_table_entry *lte)
+{
+ if (lte) {
+ if (lte->staging_list.next)
+ list_del(<e->staging_list);
+ FREE(lte->file_on_disk);
+ FREE(lte);
+ }
+}
/*
* Inserts an entry into the lookup table.
return entry;
}
+/* Like lookup_table_decrement_refcnt(), but for when we already know the lookup
+ * table entry. */
+struct lookup_table_entry *
+lte_decrement_refcnt(struct lookup_table_entry *lte, struct lookup_table *table)
+{
+ wimlib_assert(lte->refcnt);
+ if (lte && --lte->refcnt == 0) {
+ lookup_table_unlink(table, lte);
+ if (lte->num_opened_fds == 0) {
+ free_lookup_table_entry(lte);
+ lte = NULL;
+ }
+ }
+ return lte;
+}
+
/*
* Calls a function on all the entries in the lookup table. Stop early and
return NULL;
}
+/* Only for resolved lte's */
int lookup_resource(WIMStruct *w, const char *path,
int lookup_flags,
struct dentry **dentry_ret,
struct lookup_table_entry **lte_ret,
- u8 **hash_ret)
+ unsigned *stream_idx_ret)
{
struct dentry *dentry = get_dentry(w, path);
struct lookup_table_entry *lte;
- u8 *hash;
+ unsigned stream_idx = 0;
+ lte = dentry->lte;
if (!dentry)
return -ENOENT;
if (!(lookup_flags & LOOKUP_FLAG_DIRECTORY_OK)
stream_name,
stream_name_len))
{
- hash = dentry->ads_entries[i].hash;
- goto do_lookup;
+ stream_idx = i + 1;
+ lte = dentry->ads_entries[i].lte;
+ goto out;
}
}
return -ENOENT;
}
}
- hash = dentry->hash;
-do_lookup:
- lte = __lookup_resource(w->lookup_table, hash);
+out:
if (dentry_ret)
*dentry_ret = dentry;
if (lte_ret)
*lte_ret = lte;
- if (hash_ret)
- *hash_ret = hash;
+ if (stream_idx_ret)
+ *stream_idx_ret = stream_idx;
return 0;
}
+
+static int lte_init_lte_group_list(struct lookup_table_entry *lte, void *ignore)
+{
+ INIT_LIST_HEAD(<e->lte_group_list);
+ return 0;
+}
+
+/* Resolve a dentry's lookup table entries */
+static int dentry_resolve_ltes(struct dentry *dentry, void *__table)
+{
+ struct lookup_table *table = __table;
+ struct lookup_table_entry *lte;
+
+ /* Default file stream */
+ lte = __lookup_resource(table, dentry->hash);
+ if (lte)
+ list_add(&dentry->lte_group_list.list, <e->lte_group_list);
+ else
+ INIT_LIST_HEAD(&dentry->lte_group_list.list);
+ dentry->lte_group_list.type = STREAM_TYPE_NORMAL;
+ dentry->lte = lte;
+
+ /* Alternate data streams */
+ if (dentry->link_group_master_status != GROUP_SLAVE) {
+ for (u16 i = 0; i < dentry->num_ads; i++) {
+ struct ads_entry *cur_entry = &dentry->ads_entries[i];
+
+ lte = __lookup_resource(table, cur_entry->hash);
+ if (lte)
+ list_add(&cur_entry->lte_group_list.list,
+ <e->lte_group_list);
+ else
+ INIT_LIST_HEAD(&cur_entry->lte_group_list.list);
+ cur_entry->lte = lte;
+ cur_entry->lte_group_list.type = STREAM_TYPE_ADS;
+ }
+ }
+ return 0;
+}
+
+/* Resolve all the lookup table entries of a dentry tree */
+void resolve_lookup_table_entries(struct dentry *root, struct lookup_table *table)
+{
+ for_lookup_table_entry(table, lte_init_lte_group_list, NULL);
+ for_dentry_in_tree(root, dentry_resolve_ltes, table);
+}