1 #ifndef _WIMLIB_LOOKUP_TABLE_H
2 #define _WIMLIB_LOOKUP_TABLE_H
3 #include "wimlib_internal.h"
8 /* Size of each lookup table entry in the WIM file. */
9 #define WIM_LOOKUP_TABLE_ENTRY_DISK_SIZE 50
11 #define LOOKUP_FLAG_ADS_OK 0x00000001
12 #define LOOKUP_FLAG_DIRECTORY_OK 0x00000002
13 #define LOOKUP_FLAG_FOLLOW_SYMLINKS 0x00000004
16 /* A lookup table that is used to translate the hash codes of dentries into the
17 * offsets and sizes of uncompressed or compressed file resources. It is
18 * implemented as a hash table. */
20 struct hlist_head *array;
28 * An entry in the lookup table in the WIM file.
30 * It is used to find data streams for files in the WIM.
32 * The lookup_table_entry for a given dentry in the WIM is found using the SHA1
33 * message digest field.
35 struct lookup_table_entry {
37 /* List of lookup table entries in this hash bucket */
38 struct hlist_node hash_list;
40 /* @resource_entry is read from the lookup table in the WIM
41 * file; it says where to find the file resource in the WIM
42 * file, and whether it is compressed or not. */
43 struct resource_entry resource_entry;
45 /* Currently ignored; set to 1 in new lookup table entries. */
48 /* If %true, this lookup table entry corresponds to a symbolic link
49 * reparse buffer. @symlink_reparse_data_buf will give the target of
50 * the symbolic link. */
53 /* Number of times this lookup table entry is referenced by dentries. */
57 /* SHA1 hash of the file resource pointed to by this lookup
59 u8 hash[SHA1_HASH_SIZE];
61 /* First 4 or 8 bytes of the SHA1 hash, used for inserting the
62 * entry into the hash table. Since the SHA1 hashes can be
63 * considered random, we don't really need the full 20 byte hash
64 * just to insert the entry in a hash table. */
68 /* If @file_on_disk != NULL, the file resource indicated by this lookup
69 * table entry is not in the WIM file, but rather a file on disk; this
70 * occurs for files that are added to the WIM. In that case,
71 * file_on_disk is the name of the file in the outside filesystem.
72 * It will not be compressed, and its size will be given by
73 * resource_entry.size and resource_entry.original_size. */
76 char *staging_file_name;
78 struct lookup_table_entry *next_lte_in_swm;
82 struct { /* Used for wimlib_export. */
84 /* If (other_wim_fp != NULL), the file resource indicated
85 * by this lookup table entry is in a different WIM
86 * file, and other_wim_fp is the FILE* for it. */
89 /* Compression type used in other WIM. */
93 struct { /* Used for wimlib_mount */
95 /* File descriptors table for this data stream */
96 struct wimlib_fd **fds;
97 u16 num_allocated_fds;
102 /* When a WIM file is written, out_refcnt starts at 0 and is incremented
103 * whenever the file resource pointed to by this lookup table entry
104 * needs to be written. Naturally, the file resource only need to be
105 * written when out_refcnt is 0. Incrementing it further is needed to
106 * find the correct reference count to write to the lookup table in the
107 * output file, which may be less than the regular refcnt if not all
108 * images in the WIM file are written.
110 * output_resource_entry is the struct resource_entry for the position of the
111 * file resource when written to the output file. */
113 struct resource_entry output_resource_entry;
115 /* Circular linked list of streams that share the same lookup table
118 * This list of streams may include streams from different hard link
119 * sets that happen to be the same. */
120 struct list_head lte_group_list;
122 /* List of lookup table entries that correspond to streams that have
123 * been extracted to the staging directory when modifying a read-write
125 struct list_head staging_list;
129 extern struct lookup_table *new_lookup_table(size_t capacity);
131 extern void lookup_table_insert(struct lookup_table *table,
132 struct lookup_table_entry *lte);
134 /* Unlinks a lookup table entry from the table; does not free it. */
135 static inline void lookup_table_unlink(struct lookup_table *table,
136 struct lookup_table_entry *lte)
138 hlist_del(<e->hash_list);
139 table->num_entries--;
143 extern struct lookup_table_entry *
144 lookup_table_decrement_refcnt(struct lookup_table* table, const u8 hash[]);
146 extern struct lookup_table_entry *
147 lte_decrement_refcnt(struct lookup_table_entry *lte,
148 struct lookup_table *table);
151 extern struct lookup_table_entry *new_lookup_table_entry();
153 extern int for_lookup_table_entry(struct lookup_table *table,
154 int (*visitor)(struct lookup_table_entry *, void *),
157 extern struct lookup_table_entry *
158 __lookup_resource(const struct lookup_table *table, const u8 hash[]);
160 extern int lookup_resource(WIMStruct *w, const char *path,
161 int lookup_flags, struct dentry **dentry_ret,
162 struct lookup_table_entry **lte_ret,
163 unsigned *stream_idx_ret);
165 extern int zero_out_refcnts(struct lookup_table_entry *entry, void *ignore);
167 extern void print_lookup_table_entry(struct lookup_table_entry *entry);
169 extern int read_lookup_table(FILE *fp, u64 offset, u64 size,
170 struct lookup_table **table_ret);
172 extern void free_lookup_table(struct lookup_table *table);
174 extern int write_lookup_table_entry(struct lookup_table_entry *lte, void *__out);
176 extern void free_lookup_table_entry(struct lookup_table_entry *lte);
178 extern int dentry_resolve_ltes(struct dentry *dentry, void *__table);
180 /* Writes the lookup table to the output file. */
181 static inline int write_lookup_table(struct lookup_table *table, FILE *out)
183 return for_lookup_table_entry(table, write_lookup_table_entry, out);
186 /* Unlinks and frees an entry from a lookup table. */
187 static inline void lookup_table_remove(struct lookup_table *table,
188 struct lookup_table_entry *lte)
190 lookup_table_unlink(table, lte);
191 free_lookup_table_entry(lte);
194 static inline struct resource_entry* wim_metadata_resource_entry(WIMStruct *w)
196 return &w->image_metadata[
197 w->current_image - 1].metadata_lte->resource_entry;
200 static inline struct lookup_table_entry *
201 dentry_stream_lte_resolved(const struct dentry *dentry, unsigned stream_idx)
203 wimlib_assert(dentry->resolved);
204 wimlib_assert(stream_idx <= dentry->num_ads);
208 return dentry->ads_entries[stream_idx - 1].lte;
211 static inline struct lookup_table_entry *
212 dentry_stream_lte_unresolved(const struct dentry *dentry, unsigned stream_idx,
213 const struct lookup_table *table)
215 wimlib_assert(!dentry->resolved);
216 wimlib_assert(stream_idx <= dentry->num_ads);
220 return __lookup_resource(table, dentry->hash);
222 return __lookup_resource(table,
224 stream_idx - 1].hash);
227 * Returns the lookup table entry for stream @stream_idx of the dentry, where
228 * stream_idx = 0 means the default un-named file stream, and stream_idx >= 1
229 * corresponds to an alternate data stream.
231 * This works for both resolved and un-resolved dentries.
233 static inline struct lookup_table_entry *
234 dentry_stream_lte(const struct dentry *dentry, unsigned stream_idx,
235 const struct lookup_table *table)
237 if (dentry->resolved)
238 return dentry_stream_lte_resolved(dentry, stream_idx);
240 return dentry_stream_lte_unresolved(dentry, stream_idx, table);
244 static inline const u8 *dentry_stream_hash_unresolved(const struct dentry *dentry,
247 wimlib_assert(!dentry->resolved);
248 wimlib_assert(stream_idx <= dentry->num_ads);
252 return dentry->ads_entries[stream_idx - 1].hash;
255 static inline const u8 *dentry_stream_hash_resolved(const struct dentry *dentry,
258 struct lookup_table_entry *lte;
259 lte = dentry_stream_lte_resolved(dentry, stream_idx);
267 * Returns the hash for stream @stream_idx of the dentry, where stream_idx = 0
268 * means the default un-named file stream, and stream_idx >= 1 corresponds to an
269 * alternate data stream.
271 * This works for both resolved and un-resolved dentries.
273 static inline const u8 *dentry_stream_hash(const struct dentry *dentry,
276 if (dentry->resolved)
277 return dentry_stream_hash_resolved(dentry, stream_idx);
279 return dentry_stream_hash_unresolved(dentry, stream_idx);
282 static inline struct lookup_table_entry *
283 dentry_first_lte_resolved(const struct dentry *dentry)
285 struct lookup_table_entry *lte;
286 wimlib_assert(dentry->resolved);
288 for (unsigned i = 0; i <= dentry->num_ads; i++) {
289 lte = dentry_stream_lte_resolved(dentry, i);
296 static inline struct lookup_table_entry *
297 dentry_first_lte_unresolved(const struct dentry *dentry,
298 const struct lookup_table *table)
300 struct lookup_table_entry *lte;
301 wimlib_assert(!dentry->resolved);
303 for (unsigned i = 0; i <= dentry->num_ads; i++) {
304 lte = dentry_stream_lte_unresolved(dentry, i, table);
311 extern struct lookup_table_entry *
312 dentry_first_lte(const struct dentry *dentry, const struct lookup_table *table);