]> wimlib.net Git - wimlib/blob - src/hardlink.c
Various code cleanups
[wimlib] / src / hardlink.c
1 /*
2  * hardlink.c
3  *
4  * Code to deal with hard links in WIMs.
5  */
6
7 /*
8  * Copyright (C) 2012 Eric Biggers
9  *
10  * This file is part of wimlib, a library for working with WIM files.
11  *
12  * wimlib is free software; you can redistribute it and/or modify it under the
13  * terms of the GNU General Public License as published by the Free
14  * Software Foundation; either version 3 of the License, or (at your option)
15  * any later version.
16  *
17  * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY
18  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
19  * A PARTICULAR PURPOSE. See the GNU General Public License for more
20  * details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with wimlib; if not, see http://www.gnu.org/licenses/.
24  */
25
26 #include "wimlib_internal.h"
27 #include "dentry.h"
28 #include "list.h"
29 #include "lookup_table.h"
30
31 /*                             NULL        NULL
32  *                              ^           ^
33  *         dentry               |           |
34  *        /     \          -----------  -----------
35  *        |      dentry<---|  struct  | |  struct  |---> dentry
36  *        \     /          | wim_inode| | wim_inode|
37  *         dentry          ------------ ------------
38  *                              ^           ^
39  *                              |           |
40  *                              |           |                   dentry
41  *                         -----------  -----------            /      \
42  *               dentry<---|  struct  | |  struct  |---> dentry        dentry
43  *              /          | wim_inode| | wim_inode|           \      /
44  *         dentry          ------------ ------------            dentry
45  *                              ^           ^
46  *                              |           |
47  *                            -----------------
48  *    wim_inode_table->array  | idx 0 | idx 1 |
49  *                            -----------------
50  */
51
52 /* Hash table to find inodes, identified by their inode ID.
53  * */
54 struct wim_inode_table {
55         /* Fields for the hash table */
56         struct hlist_head *array;
57         u64 num_entries;
58         u64 capacity;
59
60         /*
61          * Linked list of "extra" inodes.  These may be:
62          *
63          * - inodes with link count 1, which are all allowed to have 0 for their
64          *   inode number, meaning we cannot insert them into the hash table
65          *   before calling assign_inode_numbers().
66          *
67          * - Groups we create ourselves by splitting a nominal inode due to
68          *   inconsistencies in the dentries.  These inodes will share a inode
69          *   ID with some other inode until assign_inode_numbers() is called.
70          */
71         struct hlist_head extra_inodes;
72 };
73
74 static inline void destroy_inode_table(struct wim_inode_table *table)
75 {
76         FREE(table->array);
77 }
78
79 static int init_inode_table(struct wim_inode_table *table, size_t capacity)
80 {
81         table->array = CALLOC(capacity, sizeof(table->array[0]));
82         if (!table->array) {
83                 ERROR("Cannot initalize inode table: out of memory");
84                 return WIMLIB_ERR_NOMEM;
85         }
86         table->num_entries  = 0;
87         table->capacity     = capacity;
88         INIT_HLIST_HEAD(&table->extra_inodes);
89         return 0;
90 }
91
92 static inline size_t inode_link_count(const struct wim_inode *inode)
93 {
94         const struct list_head *cur;
95         size_t size = 0;
96         list_for_each(cur, &inode->i_dentry)
97                 size++;
98         return size;
99 }
100
101 /* Insert a dentry into the inode table based on the inode number of the
102  * attached inode (which came from the hard link group ID field of the on-disk
103  * WIM dentry) */
104 static int inode_table_insert(struct wim_dentry *dentry, void *__table)
105 {
106         struct wim_inode_table *table = __table;
107         struct wim_inode *d_inode = dentry->d_inode;
108
109         if (d_inode->i_ino == 0) {
110                 /* A dentry with a hard link group ID of 0 indicates that it's
111                  * in a hard link group by itself.  Add it to the list of extra
112                  * inodes rather than inserting it into the hash lists. */
113                 hlist_add_head(&d_inode->i_hlist, &table->extra_inodes);
114
115                 wimlib_assert(d_inode->i_dentry.next == &dentry->d_alias);
116                 wimlib_assert(d_inode->i_dentry.prev == &dentry->d_alias);
117                 wimlib_assert(d_inode->i_nlink == 1);
118         } else {
119                 size_t pos;
120                 struct wim_inode *inode;
121                 struct hlist_node *cur;
122
123                 /* Try adding this dentry to an existing inode */
124                 pos = d_inode->i_ino % table->capacity;
125                 hlist_for_each_entry(inode, cur, &table->array[pos], i_hlist) {
126                         if (inode->i_ino == d_inode->i_ino) {
127                                 inode_add_dentry(dentry, inode);
128                                 inode->i_nlink++;
129                                 return 0;
130                         }
131                 }
132
133                 /* No inode in the table has the same number as this one, so add
134                  * it to the table. */
135                 hlist_add_head(&d_inode->i_hlist, &table->array[pos]);
136
137                 wimlib_assert(d_inode->i_dentry.next == &dentry->d_alias);
138                 wimlib_assert(d_inode->i_dentry.prev == &dentry->d_alias);
139                 wimlib_assert(d_inode->i_nlink == 1);
140
141                 /* XXX Make the table grow when too many entries have been
142                  * inserted. */
143                 table->num_entries++;
144         }
145         return 0;
146 }
147
148 static void print_inode_dentries(const struct wim_inode *inode)
149 {
150         struct wim_dentry *dentry;
151         inode_for_each_dentry(dentry, inode)
152                 printf("`%s'\n", dentry->full_path_utf8);
153 }
154
155 static void inconsistent_inode(const struct wim_inode *inode)
156 {
157         ERROR("An inconsistent hard link group that cannot be corrected has "
158               "been detected");
159         ERROR("The dentries are located at the following paths:");
160 #ifdef ENABLE_ERROR_MESSAGES
161         print_inode_dentries(inode);
162 #endif
163 }
164
165 static bool ref_inodes_consistent(const struct wim_inode * restrict ref_inode_1,
166                                   const struct wim_inode * restrict ref_inode_2)
167 {
168         wimlib_assert(ref_inode_1 != ref_inode_2);
169
170         if (ref_inode_1->i_num_ads != ref_inode_2->i_num_ads)
171                 return false;
172         if (ref_inode_1->i_security_id != ref_inode_2->i_security_id
173             || ref_inode_1->i_attributes != ref_inode_2->i_attributes)
174                 return false;
175         for (unsigned i = 0; i <= ref_inode_1->i_num_ads; i++) {
176                 const u8 *ref_1_hash, *ref_2_hash;
177                 ref_1_hash = inode_stream_hash(ref_inode_1, i);
178                 ref_2_hash = inode_stream_hash(ref_inode_2, i);
179                 if (!hashes_equal(ref_1_hash, ref_2_hash))
180                         return false;
181                 if (i && !ads_entries_have_same_name(&ref_inode_1->i_ads_entries[i - 1],
182                                                      &ref_inode_2->i_ads_entries[i - 1]))
183                         return false;
184
185         }
186         return true;
187 }
188
189 static bool inodes_consistent(const struct wim_inode * restrict ref_inode,
190                               const struct wim_inode * restrict inode)
191 {
192         wimlib_assert(ref_inode != inode);
193
194         if (ref_inode->i_num_ads != inode->i_num_ads &&
195             inode->i_num_ads != 0)
196                 return false;
197         if (ref_inode->i_security_id != inode->i_security_id
198             || ref_inode->i_attributes != inode->i_attributes)
199                 return false;
200         for (unsigned i = 0; i <= min(ref_inode->i_num_ads, inode->i_num_ads); i++) {
201                 const u8 *ref_hash, *hash;
202                 ref_hash = inode_stream_hash(ref_inode, i);
203                 hash = inode_stream_hash(inode, i);
204                 if (!hashes_equal(ref_hash, hash) && !is_zero_hash(hash))
205                         return false;
206                 if (i && !ads_entries_have_same_name(&ref_inode->i_ads_entries[i - 1],
207                                                      &inode->i_ads_entries[i - 1]))
208                         return false;
209         }
210         return true;
211 }
212
213 /* Fix up a "true" inode and check for inconsistencies */
214 static int fix_true_inode(struct wim_inode *inode, struct hlist_head *inode_list)
215 {
216         struct wim_dentry *dentry;
217         struct wim_dentry *ref_dentry = NULL;
218         struct wim_inode *ref_inode;
219         u64 last_ctime = 0;
220         u64 last_mtime = 0;
221         u64 last_atime = 0;
222
223         inode_for_each_dentry(dentry, inode) {
224                 if (!ref_dentry || dentry->d_inode->i_num_ads > ref_dentry->d_inode->i_num_ads)
225                         ref_dentry = dentry;
226                 if (dentry->d_inode->i_creation_time > last_ctime)
227                         last_ctime = dentry->d_inode->i_creation_time;
228                 if (dentry->d_inode->i_last_write_time > last_mtime)
229                         last_mtime = dentry->d_inode->i_last_write_time;
230                 if (dentry->d_inode->i_last_access_time > last_atime)
231                         last_atime = dentry->d_inode->i_last_access_time;
232         }
233
234         ref_inode = ref_dentry->d_inode;
235         ref_inode->i_nlink = 1;
236         hlist_add_head(&ref_inode->i_hlist, inode_list);
237
238         list_del(&inode->i_dentry);
239         list_add(&ref_inode->i_dentry, &ref_dentry->d_alias);
240
241         inode_for_each_dentry(dentry, ref_inode) {
242                 if (dentry != ref_dentry) {
243                         if (!inodes_consistent(ref_inode, dentry->d_inode)) {
244                                 inconsistent_inode(ref_inode);
245                                 return WIMLIB_ERR_INVALID_DENTRY;
246                         }
247                         /* Free the unneeded `struct wim_inode'. */
248                         dentry->d_inode->i_hlist.next = NULL;
249                         dentry->d_inode->i_hlist.pprev = NULL;
250                         free_inode(dentry->d_inode);
251                         dentry->d_inode = ref_inode;
252                         ref_inode->i_nlink++;
253                 }
254         }
255         ref_inode->i_creation_time = last_ctime;
256         ref_inode->i_last_write_time = last_mtime;
257         ref_inode->i_last_access_time = last_atime;
258         wimlib_assert(inode_link_count(ref_inode) == ref_inode->i_nlink);
259         return 0;
260 }
261
262 /*
263  * Fixes up a nominal inode.
264  *
265  * By a nominal inode we mean a group of two or more dentries that share the
266  * same hard link group ID.
267  *
268  * If dentries in the inode are found to be inconsistent, we may split the inode
269  * into several "true" inodes.
270  *
271  * After splitting up each nominal inode into the "true" inodes we will
272  * canonicalize the link group by getting rid of all the unnecessary `struct
273  * wim_inode's.  There will be just one `struct wim_inode' for each hard link
274  * group remaining.
275  */
276 static int fix_nominal_inode(struct wim_inode *inode,
277                              struct hlist_head *inode_list)
278 {
279         struct wim_dentry *dentry;
280         struct hlist_node *cur, *tmp;
281         int ret;
282         size_t num_true_inodes;
283
284         wimlib_assert(inode->i_nlink == inode_link_count(inode));
285
286         LIST_HEAD(dentries_with_data_streams);
287         LIST_HEAD(dentries_with_no_data_streams);
288         HLIST_HEAD(true_inodes);
289
290         /* Create a list of dentries in the nominal inode that have at
291          * least one data stream with a non-zero hash, and another list that
292          * contains the dentries that have a zero hash for all data streams. */
293         inode_for_each_dentry(dentry, inode) {
294                 for (unsigned i = 0; i <= dentry->d_inode->i_num_ads; i++) {
295                         const u8 *hash;
296                         hash = inode_stream_hash(dentry->d_inode, i);
297                         if (!is_zero_hash(hash)) {
298                                 list_add(&dentry->tmp_list,
299                                          &dentries_with_data_streams);
300                                 goto next_dentry;
301                         }
302                 }
303                 list_add(&dentry->tmp_list,
304                          &dentries_with_no_data_streams);
305         next_dentry:
306                 ;
307         }
308
309         /* If there are no dentries with data streams, we require the nominal
310          * inode to be a true inode */
311         if (list_empty(&dentries_with_data_streams)) {
312         #ifdef ENABLE_DEBUG
313                 if (inode->i_nlink > 1) {
314                         DEBUG("Found link group of size %u without "
315                               "any data streams:", inode->i_nlink);
316                         print_inode_dentries(inode);
317                         DEBUG("We are going to interpret it as true "
318                               "link group, provided that the dentries "
319                               "are consistent.");
320                 }
321         #endif
322                 return fix_true_inode(inode, inode_list);
323         }
324
325         /* One or more dentries had data streams specified.  We check each of
326          * these dentries for consistency with the others to form a set of true
327          * inodes. */
328         num_true_inodes = 0;
329         list_for_each_entry(dentry, &dentries_with_data_streams, tmp_list) {
330                 /* Look for a true inode that is consistent with this dentry and
331                  * add this dentry to it.  Or, if none of the true inodes are
332                  * consistent with this dentry, add a new one (if that happens,
333                  * we have split the hard link group). */
334                 hlist_for_each_entry(inode, cur, &true_inodes, i_hlist) {
335                         if (ref_inodes_consistent(inode, dentry->d_inode)) {
336                                 inode_add_dentry(dentry, inode);
337                                 goto next_dentry_2;
338                         }
339                 }
340                 num_true_inodes++;
341                 INIT_LIST_HEAD(&dentry->d_inode->i_dentry);
342                 inode_add_dentry(dentry, dentry->d_inode);
343                 hlist_add_head(&dentry->d_inode->i_hlist, &true_inodes);
344 next_dentry_2:
345                 ;
346         }
347
348         wimlib_assert(num_true_inodes != 0);
349
350         /* If there were dentries with no data streams, we require there to only
351          * be one true inode so that we know which inode to assign the
352          * streamless dentries to. */
353         if (!list_empty(&dentries_with_no_data_streams)) {
354                 if (num_true_inodes != 1) {
355                         ERROR("Hard inode ambiguity detected!");
356                         ERROR("We split up inode 0x%"PRIx64" due to "
357                               "inconsistencies,", inode->i_ino);
358                         ERROR("but dentries with no stream information remained. "
359                               "We don't know which inode");
360                         ERROR("to assign them to.");
361                         return WIMLIB_ERR_INVALID_DENTRY;
362                 }
363                 inode = container_of(true_inodes.first, struct wim_inode, i_hlist);
364                 /* Assign the streamless dentries to the one and only true
365                  * inode. */
366                 list_for_each_entry(dentry, &dentries_with_no_data_streams, tmp_list)
367                         inode_add_dentry(dentry, inode);
368         }
369         #ifdef ENABLE_DEBUG
370         if (num_true_inodes != 1) {
371                 inode = container_of(true_inodes.first, struct wim_inode, i_hlist);
372
373                 printf("Split nominal inode 0x%"PRIx64" into %zu "
374                        "inodes:\n",
375                        inode->i_ino, num_true_inodes);
376                 puts("------------------------------------------------------------------------------");
377                 size_t i = 1;
378                 hlist_for_each_entry(inode, cur, &true_inodes, i_hlist) {
379                         printf("[Split inode %zu]\n", i++);
380                         print_inode_dentries(inode);
381                         putchar('\n');
382                 }
383                 puts("------------------------------------------------------------------------------");
384         }
385         #endif
386
387         hlist_for_each_entry_safe(inode, cur, tmp, &true_inodes, i_hlist) {
388                 ret = fix_true_inode(inode, inode_list);
389                 if (ret != 0)
390                         return ret;
391         }
392         return 0;
393 }
394
395 static int fix_inodes(struct wim_inode_table *table,
396                       struct hlist_head *inode_list)
397 {
398         struct wim_inode *inode;
399         struct hlist_node *cur, *tmp;
400         int ret;
401         INIT_HLIST_HEAD(inode_list);
402         for (u64 i = 0; i < table->capacity; i++) {
403                 hlist_for_each_entry_safe(inode, cur, tmp, &table->array[i], i_hlist) {
404                         ret = fix_nominal_inode(inode, inode_list);
405                         if (ret != 0)
406                                 return ret;
407                 }
408         }
409         hlist_for_each_safe(cur, tmp, &table->extra_inodes)
410                 hlist_add_head(cur, inode_list);
411         return 0;
412 }
413
414 /*
415  * dentry_tree_fix_inodes():
416  *
417  * This function takes as input a tree of WIM dentries that has a different
418  * inode associated with every dentry.  Sets of dentries that share the same
419  * inode (a.k.a. hard link groups) are built using the i_ino field of each
420  * inode, then the link count and alias list for one inode in each set is set
421  * correctly and the unnecessary struct wim_inode's freed.  The effect is to
422  * correctly associate exactly one struct wim_inode with each original inode,
423  * regardless of how many dentries are aliases for that inode.
424  *
425  * The special inode number of 0 indicates that the dentry is in a hard link
426  * group by itself, and therefore has a 'struct wim_inode' with i_nlink=1 to
427  * itself.
428  *
429  * This function also checks the dentries in each hard link group for
430  * consistency.  In some WIMs, such as install.wim for some versions of Windows
431  * 7, dentries can share the same hard link group ID but not actually be hard
432  * linked to each other (e.g. to having different data streams).  This should be
433  * an error, but this case needs be handled.  So, each "nominal" inode (the
434  * inode based on the inode numbers provided in the WIM) is examined for
435  * consistency and may be split into multiple "true" inodes that are maximally
436  * sized consistent sets of dentries.
437  *
438  * Return 0 on success; WIMLIB_ERR_NOMEM or WIMLIB_ERR_INVALID_DENTRY on
439  * failure.  On success, the list of "true" inodes, linked by the i_hlist field,
440  * is returned in the hlist @inode_list.
441  */
442 int dentry_tree_fix_inodes(struct wim_dentry *root, struct hlist_head *inode_list)
443 {
444         struct wim_inode_table inode_tab;
445         int ret;
446
447         DEBUG("Inserting dentries into inode table");
448         ret = init_inode_table(&inode_tab, 9001);
449         if (ret != 0)
450                 return ret;
451
452         for_dentry_in_tree(root, inode_table_insert, &inode_tab);
453
454         DEBUG("Cleaning up the hard link groups");
455         ret = fix_inodes(&inode_tab, inode_list);
456         destroy_inode_table(&inode_tab);
457         return ret;
458 }
459
460 /* Assign inode numbers to a list of inode, and return the next available
461  * number. */
462 u64 assign_inode_numbers(struct hlist_head *inode_list)
463 {
464         DEBUG("Assigning inode numbers");
465         struct wim_inode *inode;
466         struct hlist_node *cur;
467         u64 cur_ino = 1;
468         hlist_for_each_entry(inode, cur, inode_list, i_hlist) {
469                 inode->i_ino = cur_ino;
470                 cur_ino++;
471         }
472         return cur_ino;
473 }