From: Eric Biggers Date: Thu, 24 Jul 2014 06:20:38 +0000 (-0500) Subject: inode.c: cleanup X-Git-Tag: v1.7.1~50 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=321750354891a0968ca0c3664417eae73b9414aa inode.c: cleanup --- diff --git a/include/wimlib/inode.h b/include/wimlib/inode.h index 3b022299..03c9acd8 100644 --- a/include/wimlib/inode.h +++ b/include/wimlib/inode.h @@ -125,9 +125,10 @@ struct wim_inode { /* Corresponds to 'security_id' in `struct wim_dentry_on_disk': The * index of this inode's security descriptor in the WIM image's table of - * security descriptors, or -1. Note: in verify_inode(), called - * whenever a WIM image is loaded, out-of-bounds indices are set to -1, - * so the extraction code does not need to do bounds checks. */ + * security descriptors, or -1. Note: when a WIM image is loaded, + * wimlib sets out-of-bounds indices and values less than -1 in this + * field to -1. So the extraction code need not do an upper bound check + * after checking for -1 (or equivalently < 0). */ int32_t i_security_id; /* Identity of a reparse point. See @@ -355,6 +356,12 @@ extern void inode_remove_ads(struct wim_inode *inode, struct wim_ads_entry *entry, struct wim_lookup_table *lookup_table); +/* + * Does the specified alternate data stream entry correspond to a named stream? + * + * See inode_needs_dummy_stream() for explanation of why an alternate data + * stream entry might, in fact, not be named... + */ static inline bool ads_entry_is_named_stream(const struct wim_ads_entry *entry) { @@ -522,8 +529,8 @@ extern int read_ads_entries(const u8 * restrict p, struct wim_inode * restrict inode, size_t *nbytes_remaining_p); -extern int -verify_inode(struct wim_inode *inode, const struct wim_security_data *sd); +extern void +check_inode(struct wim_inode *inode, const struct wim_security_data *sd); extern void inode_ref_streams(struct wim_inode *inode); diff --git a/src/dentry.c b/src/dentry.c index 62283c18..fb268039 100644 --- a/src/dentry.c +++ b/src/dentry.c @@ -299,7 +299,7 @@ dentry_set_name_utf16le(struct wim_dentry *dentry, const utf16lechar *name, * indices. For dentries that are currently linked into the tree, use * rename_wim_path(). * - * Returns 0 or an error code resulting from string conversion. + * Returns 0 or an error code resulting from a failed string conversion. */ int dentry_set_name(struct wim_dentry *dentry, const tchar *name) @@ -472,7 +472,7 @@ for_dentry_in_tree_depth(struct wim_dentry *root, * Whenever possible, use dentry_full_path() instead of calling this and * accessing _full_path directly. * - * Returns 0 or an error code resulting from string conversion. + * Returns 0 or an error code resulting from a failed string conversion. */ int calculate_dentry_full_path(struct wim_dentry *dentry) @@ -896,7 +896,7 @@ get_parent_dentry(WIMStruct *wim, const tchar *path, * * On success, returns 0 and a pointer to the new, allocated dentry is stored in * *dentry_ret. On failure, returns WIMLIB_ERR_NOMEM or an error code resulting - * from string conversion. + * from a failed string conversion. */ int new_dentry(const tchar *name, struct wim_dentry **dentry_ret) diff --git a/src/inode.c b/src/inode.c index c9aa14b8..0111004a 100644 --- a/src/inode.c +++ b/src/inode.c @@ -1,9 +1,14 @@ /* * inode.c + * + * Functions that operate on WIM inodes. + * + * See dentry.c for a description of the relationship between WIM dentries and + * WIM inodes. */ /* - * Copyright (C) 2012, 2013 Eric Biggers + * Copyright (C) 2012, 2013, 2014 Eric Biggers * * This file is part of wimlib, a library for working with WIM files. * @@ -54,7 +59,6 @@ new_inode(void) return inode; } - /* Allocate a new inode. Leave the timestamps zeroed out. */ struct wim_inode * new_timeless_inode(void) @@ -79,9 +83,7 @@ put_inode(struct wim_inode *inode) wimlib_assert(inode->i_nlink != 0); if (--inode->i_nlink == 0) { /* If FUSE mounts are enabled, we must keep a unlinked inode - * around until all file descriptors to it have been closed. - * inode_put_fd() in mount_image.c handles dropping a file - * descriptor. */ + * around until all file descriptors to it have been closed. */ #ifdef WITH_FUSE if (inode->i_num_opened_fds == 0) #endif @@ -89,7 +91,7 @@ put_inode(struct wim_inode *inode) } } -/* De-allocate memory for an alternate data stream entry. */ +/* Free memory allocated within an alternate data stream entry. */ static void destroy_ads_entry(struct wim_ads_entry *ads_entry) { @@ -101,15 +103,15 @@ destroy_ads_entry(struct wim_ads_entry *ads_entry) void free_inode(struct wim_inode *inode) { - if (inode == NULL) + if (unlikely(!inode)) return; - if (inode->i_ads_entries) { + if (unlikely(inode->i_ads_entries)) { for (u16 i = 0; i < inode->i_num_ads; i++) destroy_ads_entry(&inode->i_ads_entries[i]); FREE(inode->i_ads_entries); } - if (inode->i_extra) + if (unlikely(inode->i_extra)) FREE(inode->i_extra); /* HACK: This may instead delete the inode from i_list, but hlist_del() * behaves the same as list_del(). */ @@ -195,17 +197,17 @@ do_inode_add_ads(struct wim_inode *inode, struct wim_ads_entry *new_entry; if (inode->i_num_ads >= 0xfffe) { - ERROR("Too many alternate data streams in one inode!"); + ERROR("File \"%"TS"\" has too many alternate data streams!", + inode_first_full_path(inode)); errno = EFBIG; return NULL; } num_ads = inode->i_num_ads + 1; ads_entries = REALLOC(inode->i_ads_entries, num_ads * sizeof(inode->i_ads_entries[0])); - if (ads_entries == NULL) { - ERROR("Failed to allocate memory for new alternate data stream"); + if (!ads_entries) return NULL; - } + inode->i_ads_entries = ads_entries; new_entry = &inode->i_ads_entries[num_ads - 1]; @@ -218,6 +220,12 @@ do_inode_add_ads(struct wim_inode *inode, return new_entry; } +/* + * Add an alternate data stream entry to a WIM inode (UTF-16LE version). On + * success, returns a pointer to the new entry. Note that this pointer might + * become invalid if another ADS entry is added to the inode. On failure, + * returns NULL and sets errno. + */ struct wim_ads_entry * inode_add_ads_utf16le(struct wim_inode *inode, const utf16lechar *stream_name, size_t stream_name_nbytes) @@ -238,8 +246,10 @@ inode_add_ads_utf16le(struct wim_inode *inode, } /* - * Add an alternate stream entry to a WIM inode. On success, returns a pointer - * to the new entry; on failure, returns NULL and sets errno. + * Add an alternate data stream entry to a WIM inode (tchar version). On + * success, returns a pointer to the new entry. Note that this pointer might + * become invalid if another ADS entry is added to the inode. On failure, + * returns NULL and sets errno. */ struct wim_ads_entry * inode_add_ads(struct wim_inode *inode, const tchar *stream_name) @@ -262,6 +272,14 @@ inode_add_ads(struct wim_inode *inode, const tchar *stream_name) return result; } +/* + * Add an data alternate stream entry to a WIM inode, where the contents of the + * new stream are specified in a data buffer. The inode must be resolved. + * + * On success, returns a pointer to the new alternate data stream entry. Note + * that this pointer might become invalid if another ADS entry is added to the + * inode. On failure, returns NULL and sets errno. + */ struct wim_ads_entry * inode_add_ads_with_data(struct wim_inode *inode, const tchar *name, const void *value, size_t size, @@ -277,12 +295,15 @@ inode_add_ads_with_data(struct wim_inode *inode, const tchar *name, new_entry->lte = new_stream_from_data_buffer(value, size, lookup_table); if (!new_entry->lte) { - inode_remove_ads(inode, new_entry, lookup_table); + inode_remove_ads(inode, new_entry, NULL); return NULL; } return new_entry; } +/* + * Does the inode have any named data streams? + */ bool inode_has_named_stream(const struct wim_inode *inode) { @@ -293,19 +314,21 @@ inode_has_named_stream(const struct wim_inode *inode) } /* Set the unnamed stream of a WIM inode, given a data buffer containing the - * stream contents. */ + * stream contents. The inode must be resolved and cannot have an unnamed + * stream specified already. */ int inode_set_unnamed_stream(struct wim_inode *inode, const void *data, size_t len, struct wim_lookup_table *lookup_table) { wimlib_assert(inode->i_resolved); + wimlib_assert(!inode->i_lte); inode->i_lte = new_stream_from_data_buffer(data, len, lookup_table); - if (inode->i_lte == NULL) + if (!inode->i_lte) return WIMLIB_ERR_NOMEM; return 0; } -/* Remove an alternate data stream from a WIM inode */ +/* Remove an alternate data stream from a WIM inode. */ void inode_remove_ads(struct wim_inode *inode, struct wim_ads_entry *entry, struct wim_lookup_table *lookup_table) @@ -329,103 +352,132 @@ inode_remove_ads(struct wim_inode *inode, struct wim_ads_entry *entry, } /* - * Resolve an inode's lookup table entries. + * Resolve an inode's single-instance streams. * - * This replaces the SHA1 hash fields (which are used to lookup an entry in the - * lookup table) with pointers directly to the lookup table entries. + * This takes each SHA-1 message digest stored in the inode or one of its ADS + * entries and replaces it with a pointer directly to the appropriate 'struct + * wim_lookup_table_entry' currently inserted into @table to represent the + * single-instance stream having that SHA-1 message digest. * * If @force is %false: - * If any needed SHA1 message digests are not found in the lookup table, - * WIMLIB_ERR_RESOURCE_NOT_FOUND is returned and the inode is left - * unmodified. + * If any of the needed single-instance streams do not exist in @table, + * return WIMLIB_ERR_RESOURCE_NOT_FOUND and leave the inode unmodified. * If @force is %true: - * If any needed SHA1 message digests are not found in the lookup table, - * new entries are allocated and inserted into the lookup table. + * If any of the needed single-instance streams do not exist in @table, + * allocate new entries for them and insert them into @table. This does + * not, of course, cause these streams to magically exist, but this is + * needed by the code for extraction from a pipe. + * + * If the inode is already resolved, this function does nothing. + * + * Returns 0 on success; WIMLIB_ERR_NOMEM if out of memory; or + * WIMLIB_ERR_RESOURCE_NOT_FOUND if @force is %false and at least one + * single-instance stream referenced by the inode was missing. */ int inode_resolve_streams(struct wim_inode *inode, struct wim_lookup_table *table, bool force) { const u8 *hash; + struct wim_lookup_table_entry *lte, *ads_lte; - if (!inode->i_resolved) { - struct wim_lookup_table_entry *lte, *ads_lte; + if (inode->i_resolved) + return 0; + + struct wim_lookup_table_entry *ads_ltes[inode->i_num_ads]; + + /* Resolve the default data stream */ + lte = NULL; + hash = inode->i_hash; + if (!is_zero_hash(hash)) { + lte = lookup_stream(table, hash); + if (!lte) { + if (force) { + lte = new_lookup_table_entry(); + if (!lte) + return WIMLIB_ERR_NOMEM; + copy_hash(lte->hash, hash); + lookup_table_insert(table, lte); + } else { + goto stream_not_found; + } + } + } + + /* Resolve the alternate data streams */ + for (u16 i = 0; i < inode->i_num_ads; i++) { + struct wim_ads_entry *cur_entry; - /* Resolve the default file stream */ - lte = NULL; - hash = inode->i_hash; + ads_lte = NULL; + cur_entry = &inode->i_ads_entries[i]; + hash = cur_entry->hash; if (!is_zero_hash(hash)) { - lte = lookup_stream(table, hash); - if (!lte) { + ads_lte = lookup_stream(table, hash); + if (!ads_lte) { if (force) { - lte = new_lookup_table_entry(); - if (!lte) + ads_lte = new_lookup_table_entry(); + if (!ads_lte) return WIMLIB_ERR_NOMEM; - copy_hash(lte->hash, hash); - lookup_table_insert(table, lte); + copy_hash(ads_lte->hash, hash); + lookup_table_insert(table, ads_lte); } else { goto stream_not_found; } } } - - /* Resolve the alternate data streams */ - struct wim_lookup_table_entry *ads_ltes[inode->i_num_ads]; - for (u16 i = 0; i < inode->i_num_ads; i++) { - struct wim_ads_entry *cur_entry; - - ads_lte = NULL; - cur_entry = &inode->i_ads_entries[i]; - hash = cur_entry->hash; - if (!is_zero_hash(hash)) { - ads_lte = lookup_stream(table, hash); - if (!ads_lte) { - if (force) { - ads_lte = new_lookup_table_entry(); - if (!ads_lte) - return WIMLIB_ERR_NOMEM; - copy_hash(ads_lte->hash, hash); - lookup_table_insert(table, ads_lte); - } else { - goto stream_not_found; - } - } - } - ads_ltes[i] = ads_lte; - } - inode->i_lte = lte; - for (u16 i = 0; i < inode->i_num_ads; i++) - inode->i_ads_entries[i].lte = ads_ltes[i]; - inode->i_resolved = 1; + ads_ltes[i] = ads_lte; } + inode->i_lte = lte; + for (u16 i = 0; i < inode->i_num_ads; i++) + inode->i_ads_entries[i].lte = ads_ltes[i]; + inode->i_resolved = 1; return 0; stream_not_found: return stream_not_found_error(inode, hash); } +/* + * Undo the effects of inode_resolve_streams(). + * + * If the inode is not resolved, this function does nothing. + */ void inode_unresolve_streams(struct wim_inode *inode) { - if (inode->i_resolved) { - if (inode->i_lte) - copy_hash(inode->i_hash, inode->i_lte->hash); + if (!inode->i_resolved) + return; + + if (inode->i_lte) + copy_hash(inode->i_hash, inode->i_lte->hash); + else + zero_out_hash(inode->i_hash); + + for (u16 i = 0; i < inode->i_num_ads; i++) { + if (inode->i_ads_entries[i].lte) + copy_hash(inode->i_ads_entries[i].hash, + inode->i_ads_entries[i].lte->hash); else - zero_out_hash(inode->i_hash); - - for (u16 i = 0; i < inode->i_num_ads; i++) { - if (inode->i_ads_entries[i].lte) - copy_hash(inode->i_ads_entries[i].hash, - inode->i_ads_entries[i].lte->hash); - else - zero_out_hash(inode->i_ads_entries[i].hash); - } - inode->i_resolved = 0; + zero_out_hash(inode->i_ads_entries[i].hash); } + inode->i_resolved = 0; +} + +int +stream_not_found_error(const struct wim_inode *inode, const u8 *hash) +{ + if (wimlib_print_errors) { + ERROR("\"%"TS"\": stream not found", inode_first_full_path(inode)); + tfprintf(wimlib_error_file, + T(" SHA-1 message digest of missing stream:\n ")); + print_hash(hash, wimlib_error_file); + tputc(T('\n'), wimlib_error_file); + } + return WIMLIB_ERR_RESOURCE_NOT_FOUND; } /* - * Returns the lookup table entry for stream @stream_idx of the inode, where + * Return the lookup table entry for stream @stream_idx of the inode, where * stream_idx = 0 means the default un-named file stream, and stream_idx >= 1 * corresponds to an alternate data stream. * @@ -441,6 +493,11 @@ inode_stream_lte(const struct wim_inode *inode, unsigned stream_idx, return inode_stream_lte_unresolved(inode, stream_idx, table); } +/* + * Return the lookup table entry for the unnamed data stream of a *resolved* + * inode, or NULL if there is none. Also return the 0-based index of the + * corresponding stream in *stream_idx_ret. + */ struct wim_lookup_table_entry * inode_unnamed_stream_resolved(const struct wim_inode *inode, u16 *stream_idx_ret) { @@ -457,6 +514,10 @@ inode_unnamed_stream_resolved(const struct wim_inode *inode, u16 *stream_idx_ret return NULL; } +/* + * Return the lookup table entry for the unnamed data stream of a *resolved* + * inode, or NULL if there is none. + */ struct wim_lookup_table_entry * inode_unnamed_lte_resolved(const struct wim_inode *inode) { @@ -464,6 +525,10 @@ inode_unnamed_lte_resolved(const struct wim_inode *inode) return inode_unnamed_stream_resolved(inode, &stream_idx); } +/* + * Return the lookup table entry for the unnamed data stream of an *unresolved* + * inode, or NULL if there is none. + */ struct wim_lookup_table_entry * inode_unnamed_lte_unresolved(const struct wim_inode *inode, const struct wim_lookup_table *table) @@ -479,7 +544,8 @@ inode_unnamed_lte_unresolved(const struct wim_inode *inode, return NULL; } -/* Return the lookup table entry for the unnamed data stream of an inode, or +/* + * Return the lookup table entry for the unnamed data stream of an inode, or * NULL if there is none. * * You'd think this would be easier than it actually is, since the unnamed data @@ -489,7 +555,7 @@ inode_unnamed_lte_unresolved(const struct wim_inode *inode, * dentry itself. So we need to check the alternate data streams too. * * Also, note that a dentry may appear to have more than one unnamed stream, but - * if the SHA1 message digest is all 0's then the corresponding stream does not + * if the SHA-1 message digest is all 0's then the corresponding stream does not * really "count" (this is the case for the inode's own file stream when the * file stream that should be there is actually in one of the alternate stream * entries.). This is despite the fact that we may need to extract such a @@ -505,9 +571,12 @@ inode_unnamed_lte(const struct wim_inode *inode, return inode_unnamed_lte_unresolved(inode, table); } -/* Returns the SHA1 message digest of the unnamed data stream of a WIM inode, or - * 'zero_hash' if the unnamed data stream is missing has all zeroes in its SHA1 - * message digest field. */ +/* + * Return the SHA-1 message digest of the unnamed data stream of a WIM inode. + * + * If inode does not have an unnamed data stream, this returns a void SHA-1 + * message digest containing all zero bytes. + */ const u8 * inode_unnamed_stream_hash(const struct wim_inode *inode) { @@ -523,8 +592,15 @@ inode_unnamed_stream_hash(const struct wim_inode *inode) return zero_hash; } -/* Given an unhashed stream, get the pointer to it in an inode. - * As this is only for unhashed streams, there can only be one such pointer. */ +/* + * Translate a single-instance stream entry into the pointer contained in the + * inode (or ads entry of an inode) that references it. + * + * This is only possible for "unhashed" streams, which are guaranteed to have + * only one reference, and that reference is guaranteed to be in a resolved + * inode. (It can't be in an unresolved inode, since that would imply the hash + * is known!) + */ struct wim_lookup_table_entry ** retrieve_lte_pointer(struct wim_lookup_table_entry *lte) { @@ -541,21 +617,8 @@ retrieve_lte_pointer(struct wim_lookup_table_entry *lte) return NULL; } -int -stream_not_found_error(const struct wim_inode *inode, const u8 *hash) -{ - if (wimlib_print_errors) { - ERROR("\"%"TS"\": stream not found", inode_first_full_path(inode)); - tfprintf(wimlib_error_file, - T(" SHA-1 message digest of missing stream:\n ")); - print_hash(hash, wimlib_error_file); - tputc(T('\n'), wimlib_error_file); - } - return WIMLIB_ERR_RESOURCE_NOT_FOUND; -} - /* - * Reads the alternate data stream entries of a WIM dentry. + * Read the alternate data stream entries of a WIM dentry. * * @p: * Pointer to buffer that starts with the first alternate stream entry. @@ -592,7 +655,7 @@ read_ads_entries(const u8 * restrict p, struct wim_inode * restrict inode, * data stream entries. */ num_ads = inode->i_num_ads; ads_entries = CALLOC(num_ads, sizeof(inode->i_ads_entries[0])); - if (ads_entries == NULL) + if (!ads_entries) goto out_of_memory; /* Read the entries into our newly allocated buffer. */ @@ -648,7 +711,7 @@ read_ads_entries(const u8 * restrict p, struct wim_inode * restrict inode, cur_entry->stream_name = utf16le_dupz(disk_entry->stream_name, cur_entry->stream_name_nbytes); - if (cur_entry->stream_name == NULL) + if (!cur_entry->stream_name) goto out_of_memory; } else { /* Mark inode as having weird stream entries. */ @@ -691,18 +754,9 @@ out: return ret; } -/* - * Verify a WIM inode: - * - * - Check to make sure the security ID is valid - * - Check to make sure there is at most one unnamed stream - * - Check to make sure there is at most one DOS name. - * - * Return values: - * WIMLIB_ERR_SUCCESS (0) - */ -int -verify_inode(struct wim_inode *inode, const struct wim_security_data *sd) +/* Check a WIM inode for unusual field values. */ +void +check_inode(struct wim_inode *inode, const struct wim_security_data *sd) { /* Check the security ID. -1 is valid and means "no security * descriptor". Anything else has to be a valid index into the WIM @@ -727,50 +781,56 @@ verify_inode(struct wim_inode *inode, const struct wim_security_data *sd) if (num_unnamed_streams > 1) { WARNING("\"%"TS"\" has multiple (%u) un-named streams", inode_first_full_path(inode), num_unnamed_streams); + /* We currently don't treat this as an error and will just end + * up using the first unnamed data stream in the inode. */ } - - return 0; } +/* Acquire another reference to each single-instance stream referenced by this + * inode. This is necessary when creating a hard link to this inode. + * + * The inode must be resolved. */ void inode_ref_streams(struct wim_inode *inode) { for (unsigned i = 0; i <= inode->i_num_ads; i++) { struct wim_lookup_table_entry *lte; + lte = inode_stream_lte_resolved(inode, i); if (lte) lte->refcnt++; } } +/* Drop a reference to each single-instance stream referenced by this inode. + * This is necessary when deleting a hard link to this inode. */ void inode_unref_streams(struct wim_inode *inode, struct wim_lookup_table *lookup_table) { - struct wim_lookup_table_entry *lte; - unsigned i; + for (unsigned i = 0; i <= inode->i_num_ads; i++) { + struct wim_lookup_table_entry *lte; - for (i = 0; i <= inode->i_num_ads; i++) { lte = inode_stream_lte(inode, i, lookup_table); if (lte) lte_decrement_refcnt(lte, lookup_table); } } +/* Initialize a hash table for hard link detection. */ int init_inode_table(struct wim_inode_table *table, size_t capacity) { table->array = CALLOC(capacity, sizeof(table->array[0])); - if (table->array == NULL) { - ERROR("Cannot initalize inode table: out of memory"); + if (!table->array) return WIMLIB_ERR_NOMEM; - } table->num_entries = 0; table->capacity = capacity; INIT_LIST_HEAD(&table->extra_inodes); return 0; } +/* Free the memory allocated by init_inode_table(). */ void destroy_inode_table(struct wim_inode_table *table) { @@ -785,14 +845,17 @@ inode_table_get_inode(struct wim_inode_table *table, u64 ino, u64 devno) struct wim_inode *inode; struct hlist_node *cur; + /* Search for an existing inode having the same inode number and device + * number. */ hlist_for_each_entry(inode, cur, &table->array[pos], i_hlist) { if (inode->i_ino == ino && inode->i_devno == devno) { - DEBUG("Using existing inode {devno=%"PRIu64", ino=%"PRIu64"}", - devno, ino); + /* Found; use the existing inode. */ inode->i_nlink++; return inode; } } + + /* Create a new inode and insert it into the table. */ inode = new_timeless_inode(); if (inode) { inode->i_ino = ino; @@ -803,13 +866,39 @@ inode_table_get_inode(struct wim_inode_table *table, u64 ino, u64 devno) return inode; } - -/* Given a directory entry with the name @name for the file with the inode - * number @ino and device number @devno, create a new WIM dentry with an - * associated inode, where the inode is shared if an inode with the same @ino - * and @devno has already been created. On success, the new WIM dentry is - * written to *dentry_ret, and its inode has i_nlink > 1 if a previously - * existing inode was used. +/* + * Allocate a new dentry, with hard link detection. + * + * @table + * The inode table being used for the current directory scan operation. It + * will contain the mapping from (ino, devno) pairs to inodes. + * + * @name + * The name to give the new dentry. + * + * @ino + * The inode number of the file, read from the filesystem. + * + * @devno + * The device number of the file, read from the filesystem. Proper setting + * of this parameter prevents cross-device hardlinks from being created. + * If this is not a problem (perhaps because the current directory scan + * operation is guaranteed to never traverse a filesystem boundary), then + * this parameter can just be a fixed value such as 0. + * + * @noshare + * If %true, the new dentry will not be hard linked to any existing inode, + * regardless of the values of @ino and @devno. If %false, normal hard + * link detection will be done. + * + * @dentry_ret + * On success, a pointer to the new dentry will be returned in this + * location. If i_nlink of the dentry's inode is greater than 1, then this + * function created a hard link to an existing inode rather than creating a + * new inode. + * + * On success, returns 0. On failure, returns WIMLIB_ERR_NOMEM or an error code + * resulting from a failed string conversion. */ int inode_table_new_dentry(struct wim_inode_table *table, const tchar *name, @@ -852,9 +941,12 @@ inode_table_new_dentry(struct wim_inode_table *table, const tchar *name, -/* Assign consecutive inode numbers to a new set of inodes from the inode table, - * and append the inodes to a single list @head that contains the inodes already - * existing in the WIM image. */ +/* + * Following the allocation of dentries with hard link detection using + * inode_table_new_dentry(), this function will assign consecutive inode numbers + * to the new set of inodes. It will also append the list of new inodes to the + * list @head, which must contain any inodes already existing in the WIM image. + */ void inode_table_prepare_inode_list(struct wim_inode_table *table, struct list_head *head) diff --git a/src/metadata_resource.c b/src/metadata_resource.c index 206c274a..ee3f80ca 100644 --- a/src/metadata_resource.c +++ b/src/metadata_resource.c @@ -112,11 +112,8 @@ read_metadata_resource(WIMStruct *wim, struct wim_image_metadata *imd) if (ret) goto out_free_dentry_tree; - image_for_each_inode(inode, imd) { - ret = verify_inode(inode, sd); - if (ret) - goto out_free_dentry_tree; - } + image_for_each_inode(inode, imd) + check_inode(inode, sd); /* Success; fill in the image_metadata structure. */ imd->root_dentry = root;