6 * Copyright (C) 2012, 2013 Eric Biggers
8 * This file is part of wimlib, a library for working with WIM files.
10 * wimlib is free software; you can redistribute it and/or modify it under the
11 * terms of the GNU General Public License as published by the Free
12 * Software Foundation; either version 3 of the License, or (at your option)
15 * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY
16 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
17 * A PARTICULAR PURPOSE. See the GNU General Public License for more
20 * You should have received a copy of the GNU General Public License
21 * along with wimlib; if not, see http://www.gnu.org/licenses/.
28 #include "wimlib/assert.h"
29 #include "wimlib/case.h"
30 #include "wimlib/dentry.h" /* Only for dentry_full_path(). Otherwise the code
31 in this file doesn't care about file names/paths.
33 #include "wimlib/encoding.h"
34 #include "wimlib/endianness.h"
35 #include "wimlib/error.h"
36 #include "wimlib/inode.h"
37 #include "wimlib/inode_table.h"
38 #include "wimlib/lookup_table.h"
39 #include "wimlib/security.h"
40 #include "wimlib/timestamp.h"
44 /* Allocate a new inode. Set the timestamps to the current time. */
48 struct wim_inode *inode = new_timeless_inode();
50 u64 now = get_wim_timestamp();
51 inode->i_creation_time = now;
52 inode->i_last_access_time = now;
53 inode->i_last_write_time = now;
59 /* Allocate a new inode. Leave the timestamps zeroed out. */
61 new_timeless_inode(void)
63 struct wim_inode *inode = CALLOC(1, sizeof(struct wim_inode));
65 inode->i_security_id = -1;
67 inode->i_next_stream_id = 1;
68 inode->i_not_rpfixed = 1;
69 inode->i_canonical_streams = 1;
70 INIT_LIST_HEAD(&inode->i_list);
71 INIT_LIST_HEAD(&inode->i_dentry);
76 /* Decrement link count on an inode. */
78 put_inode(struct wim_inode *inode)
80 wimlib_assert(inode->i_nlink != 0);
81 if (--inode->i_nlink == 0) {
82 /* If FUSE mounts are enabled, we must keep a unlinked inode
83 * around until all file descriptors to it have been closed.
84 * inode_put_fd() in mount_image.c handles dropping a file
87 if (inode->i_num_opened_fds == 0)
93 /* De-allocate memory for an alternate data stream entry. */
95 destroy_ads_entry(struct wim_ads_entry *ads_entry)
97 FREE(ads_entry->stream_name);
100 /* Free an inode. Only use this if there can't be other links to the inode or
101 * if it doesn't matter if there are. */
103 free_inode(struct wim_inode *inode)
108 if (inode->i_ads_entries) {
109 for (u16 i = 0; i < inode->i_num_ads; i++)
110 destroy_ads_entry(&inode->i_ads_entries[i]);
111 FREE(inode->i_ads_entries);
114 FREE(inode->i_extra);
115 /* HACK: This may instead delete the inode from i_list, but hlist_del()
116 * behaves the same as list_del(). */
117 if (!hlist_unhashed(&inode->i_hlist))
118 hlist_del(&inode->i_hlist);
122 /* Return %true iff the alternate data stream entry @entry has the UTF-16LE
123 * stream name @name that has length @name_nbytes bytes. */
125 ads_entry_has_name(const struct wim_ads_entry *entry,
126 const utf16lechar *name, size_t name_nbytes,
129 return 0 == cmp_utf16le_strings(name,
132 entry->stream_name_nbytes / 2,
137 * Returns the alternate data stream entry belonging to @inode that has the
138 * stream name @stream_name, or NULL if the inode has no alternate data stream
141 * If @p stream_name is the empty string, NULL is returned --- that is, this
142 * function will not return "unnamed" alternate data stream entries.
144 * If NULL is returned, errno is set.
146 struct wim_ads_entry *
147 inode_get_ads_entry(struct wim_inode *inode, const tchar *stream_name)
150 const utf16lechar *stream_name_utf16le;
151 size_t stream_name_utf16le_nbytes;
153 struct wim_ads_entry *result;
155 if (inode->i_num_ads == 0) {
160 if (stream_name[0] == T('\0')) {
165 ret = tstr_get_utf16le_and_len(stream_name, &stream_name_utf16le,
166 &stream_name_utf16le_nbytes);
173 if (ads_entry_has_name(&inode->i_ads_entries[i],
175 stream_name_utf16le_nbytes,
176 default_ignore_case))
178 result = &inode->i_ads_entries[i];
181 } while (++i != inode->i_num_ads);
183 tstr_put_utf16le(stream_name_utf16le);
190 static struct wim_ads_entry *
191 do_inode_add_ads(struct wim_inode *inode,
192 utf16lechar *stream_name, size_t stream_name_nbytes)
195 struct wim_ads_entry *ads_entries;
196 struct wim_ads_entry *new_entry;
198 if (inode->i_num_ads >= 0xfffe) {
199 ERROR("Too many alternate data streams in one inode!");
203 num_ads = inode->i_num_ads + 1;
204 ads_entries = REALLOC(inode->i_ads_entries,
205 num_ads * sizeof(inode->i_ads_entries[0]));
206 if (ads_entries == NULL) {
207 ERROR("Failed to allocate memory for new alternate data stream");
210 inode->i_ads_entries = ads_entries;
212 new_entry = &inode->i_ads_entries[num_ads - 1];
214 memset(new_entry, 0, sizeof(struct wim_ads_entry));
215 new_entry->stream_name = stream_name;
216 new_entry->stream_name_nbytes = stream_name_nbytes;
217 new_entry->stream_id = inode->i_next_stream_id++;
218 inode->i_num_ads = num_ads;
222 struct wim_ads_entry *
223 inode_add_ads_utf16le(struct wim_inode *inode,
224 const utf16lechar *stream_name, size_t stream_name_nbytes)
226 utf16lechar *dup = NULL;
227 struct wim_ads_entry *result;
229 if (stream_name_nbytes) {
230 dup = utf16le_dupz(stream_name, stream_name_nbytes);
235 result = do_inode_add_ads(inode, dup, stream_name_nbytes);
242 * Add an alternate stream entry to a WIM inode. On success, returns a pointer
243 * to the new entry; on failure, returns NULL and sets errno.
245 struct wim_ads_entry *
246 inode_add_ads(struct wim_inode *inode, const tchar *stream_name)
248 utf16lechar *stream_name_utf16le = NULL;
249 size_t stream_name_utf16le_nbytes = 0;
250 struct wim_ads_entry *result;
252 if (stream_name && *stream_name)
253 if (tstr_to_utf16le(stream_name,
254 tstrlen(stream_name) * sizeof(tchar),
255 &stream_name_utf16le,
256 &stream_name_utf16le_nbytes))
259 result = do_inode_add_ads(inode, stream_name_utf16le,
260 stream_name_utf16le_nbytes);
262 FREE(stream_name_utf16le);
266 struct wim_ads_entry *
267 inode_add_ads_with_data(struct wim_inode *inode, const tchar *name,
268 const void *value, size_t size,
269 struct wim_lookup_table *lookup_table)
271 struct wim_ads_entry *new_entry;
273 wimlib_assert(inode->i_resolved);
275 new_entry = inode_add_ads(inode, name);
279 new_entry->lte = new_stream_from_data_buffer(value, size, lookup_table);
280 if (!new_entry->lte) {
281 inode_remove_ads(inode, new_entry, lookup_table);
288 inode_has_named_stream(const struct wim_inode *inode)
290 for (u16 i = 0; i < inode->i_num_ads; i++)
291 if (ads_entry_is_named_stream(&inode->i_ads_entries[i]))
296 /* Set the unnamed stream of a WIM inode, given a data buffer containing the
297 * stream contents. */
299 inode_set_unnamed_stream(struct wim_inode *inode, const void *data, size_t len,
300 struct wim_lookup_table *lookup_table)
302 wimlib_assert(inode->i_resolved);
303 inode->i_lte = new_stream_from_data_buffer(data, len, lookup_table);
304 if (inode->i_lte == NULL)
305 return WIMLIB_ERR_NOMEM;
309 /* Remove an alternate data stream from a WIM inode */
311 inode_remove_ads(struct wim_inode *inode, struct wim_ads_entry *entry,
312 struct wim_lookup_table *lookup_table)
314 struct wim_lookup_table_entry *lte;
315 unsigned idx = entry - inode->i_ads_entries;
317 wimlib_assert(idx < inode->i_num_ads);
318 wimlib_assert(inode->i_resolved);
322 lte_decrement_refcnt(lte, lookup_table);
324 destroy_ads_entry(entry);
326 memmove(&inode->i_ads_entries[idx],
327 &inode->i_ads_entries[idx + 1],
328 (inode->i_num_ads - idx - 1) * sizeof(inode->i_ads_entries[0]));
333 * Resolve an inode's lookup table entries.
335 * This replaces the SHA1 hash fields (which are used to lookup an entry in the
336 * lookup table) with pointers directly to the lookup table entries.
338 * If @force is %false:
339 * If any needed SHA1 message digests are not found in the lookup table,
340 * WIMLIB_ERR_RESOURCE_NOT_FOUND is returned and the inode is left
342 * If @force is %true:
343 * If any needed SHA1 message digests are not found in the lookup table,
344 * new entries are allocated and inserted into the lookup table.
347 inode_resolve_streams(struct wim_inode *inode, struct wim_lookup_table *table,
352 if (!inode->i_resolved) {
353 struct wim_lookup_table_entry *lte, *ads_lte;
355 /* Resolve the default file stream */
357 hash = inode->i_hash;
358 if (!is_zero_hash(hash)) {
359 lte = lookup_stream(table, hash);
362 lte = new_lookup_table_entry();
364 return WIMLIB_ERR_NOMEM;
365 copy_hash(lte->hash, hash);
366 lookup_table_insert(table, lte);
368 goto stream_not_found;
373 /* Resolve the alternate data streams */
374 struct wim_lookup_table_entry *ads_ltes[inode->i_num_ads];
375 for (u16 i = 0; i < inode->i_num_ads; i++) {
376 struct wim_ads_entry *cur_entry;
379 cur_entry = &inode->i_ads_entries[i];
380 hash = cur_entry->hash;
381 if (!is_zero_hash(hash)) {
382 ads_lte = lookup_stream(table, hash);
385 ads_lte = new_lookup_table_entry();
387 return WIMLIB_ERR_NOMEM;
388 copy_hash(ads_lte->hash, hash);
389 lookup_table_insert(table, ads_lte);
391 goto stream_not_found;
395 ads_ltes[i] = ads_lte;
398 for (u16 i = 0; i < inode->i_num_ads; i++)
399 inode->i_ads_entries[i].lte = ads_ltes[i];
400 inode->i_resolved = 1;
405 return stream_not_found_error(inode, hash);
409 inode_unresolve_streams(struct wim_inode *inode)
411 if (inode->i_resolved) {
413 copy_hash(inode->i_hash, inode->i_lte->hash);
415 zero_out_hash(inode->i_hash);
417 for (u16 i = 0; i < inode->i_num_ads; i++) {
418 if (inode->i_ads_entries[i].lte)
419 copy_hash(inode->i_ads_entries[i].hash,
420 inode->i_ads_entries[i].lte->hash);
422 zero_out_hash(inode->i_ads_entries[i].hash);
424 inode->i_resolved = 0;
429 * Returns the lookup table entry for stream @stream_idx of the inode, where
430 * stream_idx = 0 means the default un-named file stream, and stream_idx >= 1
431 * corresponds to an alternate data stream.
433 * This works for both resolved and un-resolved inodes.
435 struct wim_lookup_table_entry *
436 inode_stream_lte(const struct wim_inode *inode, unsigned stream_idx,
437 const struct wim_lookup_table *table)
439 if (inode->i_resolved)
440 return inode_stream_lte_resolved(inode, stream_idx);
442 return inode_stream_lte_unresolved(inode, stream_idx, table);
445 struct wim_lookup_table_entry *
446 inode_unnamed_stream_resolved(const struct wim_inode *inode, u16 *stream_idx_ret)
448 wimlib_assert(inode->i_resolved);
449 for (unsigned i = 0; i <= inode->i_num_ads; i++) {
450 if (inode_stream_name_nbytes(inode, i) == 0 &&
451 !is_zero_hash(inode_stream_hash_resolved(inode, i)))
454 return inode_stream_lte_resolved(inode, i);
461 struct wim_lookup_table_entry *
462 inode_unnamed_lte_resolved(const struct wim_inode *inode)
465 return inode_unnamed_stream_resolved(inode, &stream_idx);
468 struct wim_lookup_table_entry *
469 inode_unnamed_lte_unresolved(const struct wim_inode *inode,
470 const struct wim_lookup_table *table)
472 wimlib_assert(!inode->i_resolved);
473 for (unsigned i = 0; i <= inode->i_num_ads; i++) {
474 if (inode_stream_name_nbytes(inode, i) == 0 &&
475 !is_zero_hash(inode_stream_hash_unresolved(inode, i)))
477 return inode_stream_lte_unresolved(inode, i, table);
483 /* Return the lookup table entry for the unnamed data stream of an inode, or
484 * NULL if there is none.
486 * You'd think this would be easier than it actually is, since the unnamed data
487 * stream should be the one referenced from the inode itself. Alas, if there
488 * are named data streams, Microsoft's "imagex.exe" program will put the unnamed
489 * data stream in one of the alternate data streams instead of inside the WIM
490 * dentry itself. So we need to check the alternate data streams too.
492 * Also, note that a dentry may appear to have more than one unnamed stream, but
493 * if the SHA1 message digest is all 0's then the corresponding stream does not
494 * really "count" (this is the case for the inode's own file stream when the
495 * file stream that should be there is actually in one of the alternate stream
496 * entries.). This is despite the fact that we may need to extract such a
497 * missing entry as an empty file or empty named data stream.
499 struct wim_lookup_table_entry *
500 inode_unnamed_lte(const struct wim_inode *inode,
501 const struct wim_lookup_table *table)
503 if (inode->i_resolved)
504 return inode_unnamed_lte_resolved(inode);
506 return inode_unnamed_lte_unresolved(inode, table);
509 /* Returns the SHA1 message digest of the unnamed data stream of a WIM inode, or
510 * 'zero_hash' if the unnamed data stream is missing has all zeroes in its SHA1
511 * message digest field. */
513 inode_unnamed_stream_hash(const struct wim_inode *inode)
517 for (unsigned i = 0; i <= inode->i_num_ads; i++) {
518 if (inode_stream_name_nbytes(inode, i) == 0) {
519 hash = inode_stream_hash(inode, i);
520 if (!is_zero_hash(hash))
527 /* Given an unhashed stream, get the pointer to it in an inode.
528 * As this is only for unhashed streams, there can only be one such pointer. */
529 struct wim_lookup_table_entry **
530 retrieve_lte_pointer(struct wim_lookup_table_entry *lte)
532 wimlib_assert(lte->unhashed);
533 struct wim_inode *inode = lte->back_inode;
534 u32 stream_id = lte->back_stream_id;
536 return &inode->i_lte;
538 for (u16 i = 0; i < inode->i_num_ads; i++)
539 if (inode->i_ads_entries[i].stream_id == stream_id)
540 return &inode->i_ads_entries[i].lte;
546 stream_not_found_error(const struct wim_inode *inode, const u8 *hash)
548 if (wimlib_print_errors) {
549 ERROR("\"%"TS"\": stream not found", inode_first_full_path(inode));
550 tfprintf(stderr, T(" SHA-1 message digest of missing stream:\n "));
551 print_hash(hash, stderr);
552 tputc(T('\n'), stderr);
554 return WIMLIB_ERR_RESOURCE_NOT_FOUND;
558 * Reads the alternate data stream entries of a WIM dentry.
561 * Pointer to buffer that starts with the first alternate stream entry.
564 * Inode to load the alternate data streams into. @inode->i_num_ads must
565 * have been set to the number of alternate data streams that are expected.
567 * @nbytes_remaining_p:
568 * Number of bytes of data remaining in the buffer pointed to by @p.
569 * On success this will be updated to point just past the ADS entries.
571 * On success, inode->i_ads_entries is set to an array of `struct
572 * wim_ads_entry's of length inode->i_num_ads. On failure, @inode is not
576 * WIMLIB_ERR_SUCCESS (0)
577 * WIMLIB_ERR_INVALID_METADATA_RESOURCE
581 read_ads_entries(const u8 * restrict p, struct wim_inode * restrict inode,
582 size_t *nbytes_remaining_p)
584 size_t nbytes_remaining = *nbytes_remaining_p;
586 struct wim_ads_entry *ads_entries;
589 BUILD_BUG_ON(sizeof(struct wim_ads_entry_on_disk) != WIM_ADS_ENTRY_DISK_SIZE);
591 /* Allocate an array for our in-memory representation of the alternate
592 * data stream entries. */
593 num_ads = inode->i_num_ads;
594 ads_entries = CALLOC(num_ads, sizeof(inode->i_ads_entries[0]));
595 if (ads_entries == NULL)
598 /* Read the entries into our newly allocated buffer. */
599 for (u16 i = 0; i < num_ads; i++) {
601 struct wim_ads_entry *cur_entry;
602 const struct wim_ads_entry_on_disk *disk_entry =
603 (const struct wim_ads_entry_on_disk*)p;
605 cur_entry = &ads_entries[i];
606 ads_entries[i].stream_id = i + 1;
608 /* Do we have at least the size of the fixed-length data we know
610 if (nbytes_remaining < sizeof(struct wim_ads_entry_on_disk))
613 /* Read the length field */
614 length = le64_to_cpu(disk_entry->length);
616 /* Make sure the length field is neither so small it doesn't
617 * include all the fixed-length data nor so large it overflows
618 * the metadata resource buffer. */
619 if (length < sizeof(struct wim_ads_entry_on_disk) ||
620 length > nbytes_remaining)
623 /* Read the rest of the fixed-length data. */
625 cur_entry->reserved = le64_to_cpu(disk_entry->reserved);
626 copy_hash(cur_entry->hash, disk_entry->hash);
627 cur_entry->stream_name_nbytes = le16_to_cpu(disk_entry->stream_name_nbytes);
629 /* If stream_name_nbytes != 0, this is a named stream.
630 * Otherwise this is an unnamed stream, or in some cases (bugs
631 * in Microsoft's software I guess) a meaningless entry
632 * distinguished from the real unnamed stream entry, if any, by
633 * the fact that the real unnamed stream entry has a nonzero
635 if (cur_entry->stream_name_nbytes) {
636 /* The name is encoded in UTF16-LE, which uses 2-byte
637 * coding units, so the length of the name had better be
638 * an even number of bytes... */
639 if (cur_entry->stream_name_nbytes & 1)
642 /* Add the length of the stream name to get the length
643 * we actually need to read. Make sure this isn't more
644 * than the specified length of the entry. */
645 if (sizeof(struct wim_ads_entry_on_disk) +
646 cur_entry->stream_name_nbytes > length)
649 cur_entry->stream_name = utf16le_dupz(disk_entry->stream_name,
650 cur_entry->stream_name_nbytes);
651 if (cur_entry->stream_name == NULL)
654 /* Mark inode as having weird stream entries. */
655 inode->i_canonical_streams = 0;
658 /* It's expected that the size of every ADS entry is a multiple
659 * of 8. However, to be safe, I'm allowing the possibility of
660 * an ADS entry at the very end of the metadata resource ending
661 * un-aligned. So although we still need to increment the input
662 * pointer by @length to reach the next ADS entry, it's possible
663 * that less than @length is actually remaining in the metadata
664 * resource. We should set the remaining bytes to 0 if this
666 length = (length + 7) & ~7;
668 if (nbytes_remaining < length)
669 nbytes_remaining = 0;
671 nbytes_remaining -= length;
673 inode->i_ads_entries = ads_entries;
674 inode->i_next_stream_id = inode->i_num_ads + 1;
675 *nbytes_remaining_p = nbytes_remaining;
679 ret = WIMLIB_ERR_NOMEM;
680 goto out_free_ads_entries;
682 ERROR("An alternate data stream entry is invalid");
683 ret = WIMLIB_ERR_INVALID_METADATA_RESOURCE;
684 out_free_ads_entries:
686 for (u16 i = 0; i < num_ads; i++)
687 destroy_ads_entry(&ads_entries[i]);
695 * Verify a WIM inode:
697 * - Check to make sure the security ID is valid
698 * - Check to make sure there is at most one unnamed stream
699 * - Check to make sure there is at most one DOS name.
702 * WIMLIB_ERR_SUCCESS (0)
705 verify_inode(struct wim_inode *inode, const struct wim_security_data *sd)
707 /* Check the security ID. -1 is valid and means "no security
708 * descriptor". Anything else has to be a valid index into the WIM
709 * image's security descriptors table. */
710 if (inode->i_security_id < -1 ||
711 (inode->i_security_id >= 0 &&
712 inode->i_security_id >= sd->num_entries))
714 WARNING("\"%"TS"\" has an invalid security ID (%d)",
715 inode_first_full_path(inode), inode->i_security_id);
716 inode->i_security_id = -1;
719 /* Make sure there is only one unnamed data stream. */
720 unsigned num_unnamed_streams = 0;
721 for (unsigned i = 0; i <= inode->i_num_ads; i++) {
723 hash = inode_stream_hash(inode, i);
724 if (inode_stream_name_nbytes(inode, i) == 0 && !is_zero_hash(hash))
725 num_unnamed_streams++;
727 if (num_unnamed_streams > 1) {
728 WARNING("\"%"TS"\" has multiple (%u) un-named streams",
729 inode_first_full_path(inode), num_unnamed_streams);
736 inode_ref_streams(struct wim_inode *inode)
738 for (unsigned i = 0; i <= inode->i_num_ads; i++) {
739 struct wim_lookup_table_entry *lte;
740 lte = inode_stream_lte_resolved(inode, i);
747 inode_unref_streams(struct wim_inode *inode,
748 struct wim_lookup_table *lookup_table)
750 struct wim_lookup_table_entry *lte;
753 for (i = 0; i <= inode->i_num_ads; i++) {
754 lte = inode_stream_lte(inode, i, lookup_table);
756 lte_decrement_refcnt(lte, lookup_table);
761 init_inode_table(struct wim_inode_table *table, size_t capacity)
763 table->array = CALLOC(capacity, sizeof(table->array[0]));
764 if (table->array == NULL) {
765 ERROR("Cannot initalize inode table: out of memory");
766 return WIMLIB_ERR_NOMEM;
768 table->num_entries = 0;
769 table->capacity = capacity;
770 INIT_LIST_HEAD(&table->extra_inodes);
775 destroy_inode_table(struct wim_inode_table *table)
780 static struct wim_inode *
781 inode_table_get_inode(struct wim_inode_table *table, u64 ino, u64 devno)
783 u64 hash = hash_u64(hash_u64(ino) + hash_u64(devno));
784 size_t pos = hash % table->capacity;
785 struct wim_inode *inode;
786 struct hlist_node *cur;
788 hlist_for_each_entry(inode, cur, &table->array[pos], i_hlist) {
789 if (inode->i_ino == ino && inode->i_devno == devno) {
790 DEBUG("Using existing inode {devno=%"PRIu64", ino=%"PRIu64"}",
796 inode = new_timeless_inode();
799 inode->i_devno = devno;
800 hlist_add_head(&inode->i_hlist, &table->array[pos]);
801 table->num_entries++;
807 /* Given a directory entry with the name @name for the file with the inode
808 * number @ino and device number @devno, create a new WIM dentry with an
809 * associated inode, where the inode is shared if an inode with the same @ino
810 * and @devno has already been created. On success, the new WIM dentry is
811 * written to *dentry_ret, and its inode has i_nlink > 1 if a previously
812 * existing inode was used.
815 inode_table_new_dentry(struct wim_inode_table *table, const tchar *name,
816 u64 ino, u64 devno, bool noshare,
817 struct wim_dentry **dentry_ret)
819 struct wim_dentry *dentry;
820 struct wim_inode *inode;
824 /* File that cannot be hardlinked--- Return a new inode with its
825 * inode and device numbers left at 0. */
826 ret = new_dentry_with_timeless_inode(name, &dentry);
829 list_add_tail(&dentry->d_inode->i_list, &table->extra_inodes);
831 /* File that can be hardlinked--- search the table for an
832 * existing inode matching the inode number and device;
833 * otherwise create a new inode. */
834 ret = new_dentry(name, &dentry);
837 inode = inode_table_get_inode(table, ino, devno);
840 return WIMLIB_ERR_NOMEM;
842 /* If using an existing inode, we need to gain a reference to
843 * each of its streams. */
844 if (inode->i_nlink > 1)
845 inode_ref_streams(inode);
846 dentry->d_inode = inode;
847 inode_add_dentry(dentry, inode);
849 *dentry_ret = dentry;
855 /* Assign consecutive inode numbers to a new set of inodes from the inode table,
856 * and append the inodes to a single list @head that contains the inodes already
857 * existing in the WIM image. */
859 inode_table_prepare_inode_list(struct wim_inode_table *table,
860 struct list_head *head)
862 struct wim_inode *inode, *tmp_inode;
863 struct hlist_node *cur, *tmp;
866 /* Re-assign inode numbers in the existing list to avoid duplicates. */
867 list_for_each_entry(inode, head, i_list)
868 inode->i_ino = cur_ino++;
870 /* Assign inode numbers to the new inodes and move them to the image's
872 for (size_t i = 0; i < table->capacity; i++) {
873 hlist_for_each_entry_safe(inode, cur, tmp, &table->array[i], i_hlist)
875 inode->i_ino = cur_ino++;
877 list_add_tail(&inode->i_list, head);
879 INIT_HLIST_HEAD(&table->array[i]);
881 list_for_each_entry_safe(inode, tmp_inode, &table->extra_inodes, i_list)
883 inode->i_ino = cur_ino++;
885 list_add_tail(&inode->i_list, head);
887 INIT_LIST_HEAD(&table->extra_inodes);
888 table->num_entries = 0;