From 1530b6dab02a9e1e5faf81529ab502aee68d8cd2 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Mon, 31 Dec 2012 14:07:11 -0600 Subject: [PATCH] Various code cleanups * Improve comments * Prefix all inode fields with i_ * Rename dentry->inode_dentry_list to d_alias * Rename inode->dentry_list to i_dentry * Rename 'struct inode' to 'struct wim_inode' * Rename 'struct dentry' to 'struct wim_dentry' * Rename 'struct lookup_table_entry' to 'struct wim_lookup_table_entry' * Rename 'struct lookup_table' to 'struct wim_lookup_table' * Rename 'struct wimlib_fd' to 'struct wimfs_fd' * Remove seemingly unneeded hack from get_symlink_name() * Fix wrong pointer free in get_names() * Fix memory leaks in error cases of wimfs_rename() * Remove unneeded open_flags parameter to create_staging_file() * Specify O_EXCL instead of O_TRUNC in create_staging_file() * Don't check SHA1 message digest when extracting only part of a stream (this bug previously caused truncate() with length > 0 but less than the stream length to fail). * Fix format string in lzx_decompress() * In mounted WIM, return -ENOTDIR when component of path prefix is not a directory (rather than -ENOENT as was the case in most places). --- src/add_image.c | 72 +++--- src/compress.c | 3 +- src/decompress.c | 14 +- src/delete_image.c | 6 +- src/dentry.c | 468 +++++++++++++++++++-------------------- src/dentry.h | 193 ++++++++--------- src/export_image.c | 36 +-- src/extract_image.c | 159 +++++++------- src/hardlink.c | 300 +++++++++++++------------ src/integrity.c | 14 +- src/join.c | 21 +- src/list.h | 10 - src/lookup_table.c | 164 +++++++------- src/lookup_table.h | 154 ++++++------- src/lzx-decompress.c | 2 +- src/metadata_resource.c | 14 +- src/mount_image.c | 470 ++++++++++++++++++++-------------------- src/ntfs-apply.c | 104 ++++----- src/ntfs-capture.c | 54 ++--- src/resource.c | 50 +++-- src/security.c | 26 +-- src/sha1.c | 5 +- src/split.c | 19 +- src/symlink.c | 39 ++-- src/verify.c | 47 ++-- src/wim.c | 8 +- src/wimlib_internal.h | 56 ++--- src/write.c | 40 ++-- src/xml.c | 18 +- 29 files changed, 1282 insertions(+), 1284 deletions(-) diff --git a/src/add_image.c b/src/add_image.c index d10e5a33..4fc6c4a6 100644 --- a/src/add_image.c +++ b/src/add_image.c @@ -39,23 +39,13 @@ #define WIMLIB_ADD_IMAGE_FLAG_ROOT 0x80000000 /* - * Adds an image (given by its dentry tree) to the image metadata array of a WIM - * file, adds an entry to the lookup table for the image metadata, updates the - * image count in the header, and selects the new image. - * - * Does not update the XML data. - * - * On failure, WIMLIB_ERR_NOMEM is returned and no changes are made. Otherwise, - * 0 is returned and the image metadata array of @w is modified. - * - * @w: The WIMStruct for the WIM file. - * @root_dentry: The root of the directory tree for the image. - * @sd: The security data for the image. + * Adds the dentry tree and security data for a new image to the image metadata + * array of the WIMStruct. */ -int add_new_dentry_tree(WIMStruct *w, struct dentry *root_dentry, +int add_new_dentry_tree(WIMStruct *w, struct wim_dentry *root_dentry, struct wim_security_data *sd) { - struct lookup_table_entry *metadata_lte; + struct wim_lookup_table_entry *metadata_lte; struct image_metadata *imd; struct image_metadata *new_imd; @@ -101,11 +91,11 @@ err: /* - * Recursively builds a dentry tree from a directory tree on disk, outside the - * WIM file. + * build_dentry_tree: - Recursively builds a tree of `struct wim_dentry tree + * from an on-disk directory tree. * * @root_ret: Place to return a pointer to the root of the dentry tree. Only - * modified if successful. NULL if the file or directory was + * modified if successful. Set to NULL if the file or directory was * excluded from capture. * * @root_disk_path: The path to the root of the directory tree on disk. @@ -132,9 +122,9 @@ err: * the on-disk files during a call to wimlib_write() or * wimlib_overwrite(). */ -static int build_dentry_tree(struct dentry **root_ret, +static int build_dentry_tree(struct wim_dentry **root_ret, const char *root_disk_path, - struct lookup_table *lookup_table, + struct wim_lookup_table *lookup_table, struct wim_security_data *sd, const struct capture_config *config, int add_image_flags, @@ -144,9 +134,9 @@ static int build_dentry_tree(struct dentry **root_ret, struct stat root_stbuf; int ret = 0; int (*stat_fn)(const char *restrict, struct stat *restrict); - struct dentry *root; + struct wim_dentry *root; const char *filename; - struct inode *inode; + struct wim_inode *inode; if (exclude_path(root_disk_path, config, true)) { if (add_image_flags & WIMLIB_ADD_IMAGE_FLAG_ROOT) { @@ -226,29 +216,29 @@ static int build_dentry_tree(struct dentry **root_ret, inode = root->d_inode; #ifdef HAVE_STAT_NANOSECOND_PRECISION - inode->creation_time = timespec_to_wim_timestamp(&root_stbuf.st_mtim); - inode->last_write_time = timespec_to_wim_timestamp(&root_stbuf.st_mtim); - inode->last_access_time = timespec_to_wim_timestamp(&root_stbuf.st_atim); + inode->i_creation_time = timespec_to_wim_timestamp(&root_stbuf.st_mtim); + inode->i_last_write_time = timespec_to_wim_timestamp(&root_stbuf.st_mtim); + inode->i_last_access_time = timespec_to_wim_timestamp(&root_stbuf.st_atim); #else - inode->creation_time = unix_timestamp_to_wim(root_stbuf.st_mtime); - inode->last_write_time = unix_timestamp_to_wim(root_stbuf.st_mtime); - inode->last_access_time = unix_timestamp_to_wim(root_stbuf.st_atime); + inode->i_creation_time = unix_timestamp_to_wim(root_stbuf.st_mtime); + inode->i_last_write_time = unix_timestamp_to_wim(root_stbuf.st_mtime); + inode->i_last_access_time = unix_timestamp_to_wim(root_stbuf.st_atime); #endif if (sizeof(ino_t) >= 8) - inode->ino = (u64)root_stbuf.st_ino; + inode->i_ino = (u64)root_stbuf.st_ino; else - inode->ino = (u64)root_stbuf.st_ino | + inode->i_ino = (u64)root_stbuf.st_ino | ((u64)root_stbuf.st_dev << ((sizeof(ino_t) * 8) & 63)); add_image_flags &= ~WIMLIB_ADD_IMAGE_FLAG_ROOT; - inode->resolved = 1; + inode->i_resolved = 1; if (S_ISREG(root_stbuf.st_mode)) { /* Archiving a regular file */ - struct lookup_table_entry *lte; + struct wim_lookup_table_entry *lte; u8 hash[SHA1_HASH_SIZE]; - inode->attributes = FILE_ATTRIBUTE_NORMAL; + inode->i_attributes = FILE_ATTRIBUTE_NORMAL; /* Empty files do not have to have a lookup table entry. */ if (root_stbuf.st_size == 0) @@ -288,14 +278,14 @@ static int build_dentry_tree(struct dentry **root_ret, copy_hash(lte->hash, hash); lookup_table_insert(lookup_table, lte); } - root->d_inode->lte = lte; + root->d_inode->i_lte = lte; } else if (S_ISDIR(root_stbuf.st_mode)) { /* Archiving a directory */ - inode->attributes = FILE_ATTRIBUTE_DIRECTORY; + inode->i_attributes = FILE_ATTRIBUTE_DIRECTORY; DIR *dir; struct dirent entry, *result; - struct dentry *child; + struct wim_dentry *child; dir = opendir(root_disk_path); if (!dir) { @@ -339,8 +329,8 @@ static int build_dentry_tree(struct dentry **root_ret, } closedir(dir); } else { /* Archiving a symbolic link */ - inode->attributes = FILE_ATTRIBUTE_REPARSE_POINT; - inode->reparse_tag = WIM_IO_REPARSE_TAG_SYMLINK; + inode->i_attributes = FILE_ATTRIBUTE_REPARSE_POINT; + inode->i_reparse_tag = WIM_IO_REPARSE_TAG_SYMLINK; /* The idea here is to call readlink() to get the UNIX target of * the symbolic link, then turn the target into a reparse point @@ -372,7 +362,7 @@ static int build_dentry_tree(struct dentry **root_ret, if (stat(root_disk_path, &stbuf) == 0 && S_ISDIR(stbuf.st_mode)) { - inode->attributes |= FILE_ATTRIBUTE_DIRECTORY; + inode->i_attributes |= FILE_ATTRIBUTE_DIRECTORY; } } } else { @@ -629,14 +619,14 @@ WIMLIBAPI int wimlib_add_image(WIMStruct *w, const char *source, size_t config_len, int add_image_flags, wimlib_progress_func_t progress_func) { - int (*capture_tree)(struct dentry **, const char *, - struct lookup_table *, + int (*capture_tree)(struct wim_dentry **, const char *, + struct wim_lookup_table *, struct wim_security_data *, const struct capture_config *, int, wimlib_progress_func_t, void *); void *extra_arg; - struct dentry *root_dentry = NULL; + struct wim_dentry *root_dentry = NULL; struct wim_security_data *sd; struct capture_config config; struct image_metadata *imd; diff --git a/src/compress.c b/src/compress.c index f98a4416..c91eb502 100644 --- a/src/compress.c +++ b/src/compress.c @@ -168,7 +168,8 @@ static void huffman_tree_compute_path_lengths(HuffmanNode *node, u16 cur_len) } } -/* Creates a canonical Huffman code from an array of symbol frequencies. +/* make_canonical_huffman_code: - Creates a canonical Huffman code from an array + * of symbol frequencies. * * The algorithm used is similar to the well-known algorithm that builds a * Huffman tree using a minheap. In that algorithm, the leaf nodes are diff --git a/src/decompress.c b/src/decompress.c index e97aab5c..5c308b2d 100644 --- a/src/decompress.c +++ b/src/decompress.c @@ -27,11 +27,11 @@ #include /* - * Builds a fast huffman decoding table from an array that gives the length of - * the codeword for each symbol in the alphabet. Originally based on code - * written by David Tritscher (taken the original LZX decompression code); also - * heavily modified to add some optimizations used in the zlib code, as well as - * more comments. + * make_huffman_decode_table: - Builds a fast huffman decoding table from an + * array that gives the length of the codeword for each symbol in the alphabet. + * Originally based on code written by David Tritscher (taken the original LZX + * decompression code); also heavily modified to add some optimizations used in + * the zlib code, as well as more comments. * * @decode_table: The array in which to create the fast huffman decoding * table. It must have a length of at least @@ -282,8 +282,8 @@ int make_huffman_decode_table(u16 decode_table[], unsigned num_syms, return 0; } -/* Reads a Huffman-encoded symbol when it is known there are less than - * MAX_CODE_LEN bits remaining in the bitstream. */ +/* Reads a Huffman-encoded symbol from the bistream when the number of remaining + * bits is less than the maximum codeword length. */ int read_huffsym_near_end_of_input(struct input_bitstream *istream, const u16 decode_table[], const u8 lens[], diff --git a/src/delete_image.c b/src/delete_image.c index ecd80478..7d5e92b7 100644 --- a/src/delete_image.c +++ b/src/delete_image.c @@ -62,8 +62,8 @@ WIMLIBAPI int wimlib_delete_image(WIMStruct *w, int image) if (ret != 0) return ret; - /* Free the dentry tree, any lookup table entries that have their - * refcnt decremented to 0, and the security data. */ + /* Free the dentry tree, any lookup table entries that have their refcnt + * decremented to 0, and the security data. */ destroy_image_metadata(&w->image_metadata[image - 1], w->lookup_table); /* Get rid of the empty slot in the image metadata array. */ @@ -87,6 +87,6 @@ WIMLIBAPI int wimlib_delete_image(WIMStruct *w, int image) /* Remove the image from the XML information. */ xml_delete_image(&w->wim_info, image); - w->deletion_occurred = true; + w->deletion_occurred = 1; return 0; } diff --git a/src/dentry.c b/src/dentry.c index 3847fbb2..1165ed72 100644 --- a/src/dentry.c +++ b/src/dentry.c @@ -1,12 +1,11 @@ /* * dentry.c * - * A dentry (directory entry) contains the metadata for a file. In the WIM file - * format, the dentries are stored in the "metadata resource" section right - * after the security data. Each image in the WIM file has its own metadata - * resource with its own security data and dentry tree. Dentries in different - * images may share file resources by referring to the same lookup table - * entries. + * In the WIM file format, the dentries are stored in the "metadata resource" + * section right after the security data. Each image in the WIM file has its + * own metadata resource with its own security data and dentry tree. Dentries + * in different images may share file resources by referring to the same lookup + * table entries. */ /* @@ -32,6 +31,7 @@ #include "lookup_table.h" #include "timestamp.h" #include "wimlib_internal.h" +#include /* Calculates the unaligned length, in bytes, of an on-disk WIM dentry that has * a file name and short name that take the specified numbers of bytes. This @@ -51,7 +51,7 @@ static u64 __dentry_correct_length_unaligned(u16 file_name_len, * the file name length and short name length. Note that dentry->length is * ignored; also, this excludes any alternate data stream entries that may * follow the dentry. */ -static u64 dentry_correct_length_unaligned(const struct dentry *dentry) +static u64 dentry_correct_length_unaligned(const struct wim_dentry *dentry) { return __dentry_correct_length_unaligned(dentry->file_name_len, dentry->short_name_len); @@ -59,7 +59,7 @@ static u64 dentry_correct_length_unaligned(const struct dentry *dentry) /* Return the "correct" value to write in the length field of a WIM dentry, * based on the file name length and short name length. */ -static u64 dentry_correct_length(const struct dentry *dentry) +static u64 dentry_correct_length(const struct wim_dentry *dentry) { return (dentry_correct_length_unaligned(dentry) + 7) & ~7; } @@ -74,11 +74,12 @@ static inline bool ads_entry_has_name(const struct ads_entry *entry, return memcmp(entry->stream_name_utf8, name, name_len) == 0; } -/* Duplicates a UTF-8 name into UTF-8 and UTF-16 strings and returns the strings - * and their lengths in the pointer arguments */ -int get_names(char **name_utf16_ret, char **name_utf8_ret, - u16 *name_utf16_len_ret, u16 *name_utf8_len_ret, - const char *name) +/* Duplicates a UTF-8 string into UTF-8 and UTF-16 strings and returns the + * strings and their lengths in the pointer arguments. (Frees existing strings + * first.) */ +static int get_names(char **name_utf16_ret, char **name_utf8_ret, + u16 *name_utf16_len_ret, u16 *name_utf8_len_ret, + const char *name) { size_t utf8_len; size_t utf16_len; @@ -92,7 +93,7 @@ int get_names(char **name_utf16_ret, char **name_utf8_ret, name_utf8 = MALLOC(utf8_len + 1); if (!name_utf8) { - FREE(name_utf8); + FREE(name_utf16); return WIMLIB_ERR_NOMEM; } memcpy(name_utf8, name, utf8_len + 1); @@ -105,10 +106,8 @@ int get_names(char **name_utf16_ret, char **name_utf8_ret, return 0; } -/* Changes the name of a dentry to @new_name. Only changes the file_name and - * file_name_utf8 fields; does not change the short_name, short_name_utf8, or - * full_path_utf8 fields. Also recalculates its length. */ -static int change_dentry_name(struct dentry *dentry, const char *new_name) +/* Sets the name of a WIM dentry. */ +int set_dentry_name(struct wim_dentry *dentry, const char *new_name) { int ret; @@ -137,7 +136,7 @@ static int change_ads_name(struct ads_entry *entry, const char *new_name) /* Returns the total length of a WIM alternate data stream entry on-disk, * including the stream name, the null terminator, AND the padding after the - * entry to align the next one (or the next dentry) on an 8-byte boundary. */ + * entry to align the next ADS entry or dentry on an 8-byte boundary. */ static u64 ads_entry_total_length(const struct ads_entry *entry) { u64 len = WIM_ADS_ENTRY_DISK_SIZE; @@ -147,17 +146,17 @@ static u64 ads_entry_total_length(const struct ads_entry *entry) } -static u64 __dentry_total_length(const struct dentry *dentry, u64 length) +static u64 __dentry_total_length(const struct wim_dentry *dentry, u64 length) { - const struct inode *inode = dentry->d_inode; - for (u16 i = 0; i < inode->num_ads; i++) - length += ads_entry_total_length(&inode->ads_entries[i]); + const struct wim_inode *inode = dentry->d_inode; + for (u16 i = 0; i < inode->i_num_ads; i++) + length += ads_entry_total_length(&inode->i_ads_entries[i]); return (length + 7) & ~7; } /* Calculate the aligned *total* length of an on-disk WIM dentry. This includes * all alternate data streams. */ -u64 dentry_correct_total_length(const struct dentry *dentry) +u64 dentry_correct_total_length(const struct wim_dentry *dentry) { return __dentry_total_length(dentry, dentry_correct_length_unaligned(dentry)); @@ -165,30 +164,30 @@ u64 dentry_correct_total_length(const struct dentry *dentry) /* Like dentry_correct_total_length(), but use the existing dentry->length field * instead of calculating its "correct" value. */ -static u64 dentry_total_length(const struct dentry *dentry) +static u64 dentry_total_length(const struct wim_dentry *dentry) { return __dentry_total_length(dentry, dentry->length); } int for_dentry_in_rbtree(struct rb_node *root, - int (*visitor)(struct dentry *, void *), + int (*visitor)(struct wim_dentry *, void *), void *arg) { int ret; struct rb_node *node = root; LIST_HEAD(stack); - while (true) { + while (1) { if (node) { list_add(&rbnode_dentry(node)->tmp_list, &stack); node = node->rb_left; } else { struct list_head *next; - struct dentry *dentry; + struct wim_dentry *dentry; next = stack.next; if (next == &stack) return 0; - dentry = container_of(next, struct dentry, tmp_list); + dentry = container_of(next, struct wim_dentry, tmp_list); list_del(next); ret = visitor(dentry, arg); if (ret != 0) @@ -199,7 +198,7 @@ int for_dentry_in_rbtree(struct rb_node *root, } static int for_dentry_tree_in_rbtree_depth(struct rb_node *node, - int (*visitor)(struct dentry*, void*), + int (*visitor)(struct wim_dentry*, void*), void *arg) { int ret; @@ -223,7 +222,7 @@ static int for_dentry_tree_in_rbtree_depth(struct rb_node *node, #ifdef RECURSIVE_FOR_DENTRY_IN_TREE static int for_dentry_tree_in_rbtree(struct rb_node *node, - int (*visitor)(struct dentry*, void*), + int (*visitor)(struct wim_dentry*, void*), void *arg) { int ret; @@ -251,23 +250,23 @@ static int for_dentry_tree_in_rbtree(struct rb_node *node, * suggest because there is a separate red-black tree for each dentry that * contains its direct children. */ -int for_dentry_in_tree(struct dentry *root, - int (*visitor)(struct dentry*, void*), void *arg) +int for_dentry_in_tree(struct wim_dentry *root, + int (*visitor)(struct wim_dentry*, void*), void *arg) { #ifdef RECURSIVE_FOR_DENTRY_IN_TREE int ret = visitor(root, arg); if (ret != 0) return ret; - return for_dentry_tree_in_rbtree(root->d_inode->children.rb_node, visitor, arg); + return for_dentry_tree_in_rbtree(root->d_inode->i_children.rb_node, visitor, arg); #else int ret; struct list_head main_stack; struct list_head sibling_stack; struct list_head *sibling_stack_bottom; - struct dentry *main_dentry; + struct wim_dentry *main_dentry; struct rb_node *node; struct list_head *next_sibling; - struct dentry *dentry; + struct wim_dentry *dentry; ret = visitor(root, arg); if (ret != 0) @@ -279,7 +278,7 @@ int for_dentry_in_tree(struct dentry *root, INIT_LIST_HEAD(&sibling_stack); list_add(&root->tmp_list, &main_stack); - node = root->d_inode->children.rb_node; + node = root->d_inode->i_children.rb_node; while (1) { // Prepare for non-recursive in-order traversal of the red-black @@ -297,7 +296,7 @@ int for_dentry_in_tree(struct dentry *root, // Done with all siblings. Pop the main dentry to move // back up one level. main_dentry = container_of(main_stack.next, - struct dentry, + struct wim_dentry, tmp_list); list_del(&main_dentry->tmp_list); @@ -309,7 +308,7 @@ int for_dentry_in_tree(struct dentry *root, // Restore the just-popped main dentry's parent main_dentry->parent = container_of(main_stack.next, - struct dentry, + struct wim_dentry, tmp_list); // The next sibling to traverse in the previous level, @@ -322,7 +321,7 @@ int for_dentry_in_tree(struct dentry *root, // Pop a sibling from the stack. list_del(next_sibling); - dentry = container_of(next_sibling, struct dentry, tmp_list); + dentry = container_of(next_sibling, struct wim_dentry, tmp_list); // Visit the sibling. ret = visitor(dentry, arg); @@ -331,7 +330,7 @@ int for_dentry_in_tree(struct dentry *root, // dentries in the main stack list_for_each_entry(dentry, &main_stack, tmp_list) { dentry->parent = container_of(dentry->tmp_list.next, - struct dentry, + struct wim_dentry, tmp_list); } goto out; @@ -350,7 +349,7 @@ int for_dentry_in_tree(struct dentry *root, sibling_stack_bottom = sibling_stack.next; main_dentry = dentry; - node = main_dentry->d_inode->children.rb_node; + node = main_dentry->d_inode->i_children.rb_node; } else { node = dentry->rb_node.rb_right; } @@ -366,12 +365,12 @@ out: * Like for_dentry_in_tree(), but the visitor function is always called on a * dentry's children before on itself. */ -int for_dentry_in_tree_depth(struct dentry *root, - int (*visitor)(struct dentry*, void*), void *arg) +int for_dentry_in_tree_depth(struct wim_dentry *root, + int (*visitor)(struct wim_dentry*, void*), void *arg) { #if 1 int ret; - ret = for_dentry_tree_in_rbtree_depth(root->d_inode->children.rb_node, + ret = for_dentry_tree_in_rbtree_depth(root->d_inode->i_children.rb_node, visitor, arg); if (ret != 0) return ret; @@ -382,10 +381,10 @@ int for_dentry_in_tree_depth(struct dentry *root, struct list_head main_stack; struct list_head sibling_stack; struct list_head *sibling_stack_bottom; - struct dentry *main_dentry; + struct wim_dentry *main_dentry; struct rb_node *node; struct list_head *next_sibling; - struct dentry *dentry; + struct wim_dentry *dentry; main_dentry = root; sibling_stack_bottom = &sibling_stack; @@ -395,7 +394,7 @@ int for_dentry_in_tree_depth(struct dentry *root, list_add(&main_dentry->tmp_list, &main_stack); while (1) { - node = main_dentry->d_inode->children.rb_node; + node = main_dentry->d_inode->i_children.rb_node; while (1) { if (node->rb_left) { @@ -415,7 +414,7 @@ int for_dentry_in_tree_depth(struct dentry *root, next_sibling = sibling_stack.next; if (next_sibling == sibling_stack_bottom) { main_dentry = container_of(main_stack.next, - struct dentry, + struct wim_dentry, tmp_list); list_del(&main_dentry->tmp_list); @@ -428,7 +427,7 @@ int for_dentry_in_tree_depth(struct dentry *root, return ret; } else { main_dentry->parent = container_of(main_stack.next, - struct dentry, + struct wim_dentry, tmp_list); } @@ -438,7 +437,7 @@ int for_dentry_in_tree_depth(struct dentry *root, list_del(&root->tmp_list); list_for_each_entry(dentry, &main_stack, tmp_list) { dentry->parent = container_of(dentry->tmp_list.next, - struct dentry, + struct wim_dentry, tmp_list); } root->parent = root; @@ -448,7 +447,7 @@ int for_dentry_in_tree_depth(struct dentry *root, } else { list_del(next_sibling); - dentry = container_of(next_sibling, struct dentry, tmp_list); + dentry = container_of(next_sibling, struct wim_dentry, tmp_list); list_add(&dentry->tmp_list, &main_stack); @@ -465,7 +464,7 @@ int for_dentry_in_tree_depth(struct dentry *root, * Calculate the full path of @dentry, based on its parent's full path and on * its UTF-8 file name. */ -int calculate_dentry_full_path(struct dentry *dentry, void *ignore) +int calculate_dentry_full_path(struct wim_dentry *dentry, void *ignore) { char *full_path; u32 full_path_len; @@ -479,7 +478,7 @@ int calculate_dentry_full_path(struct dentry *dentry, void *ignore) } else { char *parent_full_path; u32 parent_full_path_len; - const struct dentry *parent = dentry->parent; + const struct wim_dentry *parent = dentry->parent; if (dentry_is_root(parent)) { parent_full_path = ""; @@ -511,13 +510,13 @@ oom: return WIMLIB_ERR_NOMEM; } -static int increment_subdir_offset(struct dentry *dentry, void *subdir_offset_p) +static int increment_subdir_offset(struct wim_dentry *dentry, void *subdir_offset_p) { *(u64*)subdir_offset_p += dentry_correct_total_length(dentry); return 0; } -static int call_calculate_subdir_offsets(struct dentry *dentry, +static int call_calculate_subdir_offsets(struct wim_dentry *dentry, void *subdir_offset_p) { calculate_subdir_offsets(dentry, subdir_offset_p); @@ -531,12 +530,12 @@ static int call_calculate_subdir_offsets(struct dentry *dentry, * @subdir_offset_p: The current subdirectory offset; i.e., the subdirectory * offset for @dentry. */ -void calculate_subdir_offsets(struct dentry *dentry, u64 *subdir_offset_p) +void calculate_subdir_offsets(struct wim_dentry *dentry, u64 *subdir_offset_p) { struct rb_node *node; dentry->subdir_offset = *subdir_offset_p; - node = dentry->d_inode->children.rb_node; + node = dentry->d_inode->i_children.rb_node; if (node) { /* Advance the subdir offset by the amount of space the children * of this dentry take up. */ @@ -570,19 +569,19 @@ static int compare_names(const char *name_1, u16 len_1, } } -static int dentry_compare_names(const struct dentry *d1, const struct dentry *d2) +static int dentry_compare_names(const struct wim_dentry *d1, const struct wim_dentry *d2) { return compare_names(d1->file_name_utf8, d1->file_name_utf8_len, d2->file_name_utf8, d2->file_name_utf8_len); } -static struct dentry * +static struct wim_dentry * get_rbtree_child_with_name(const struct rb_node *node, const char *name, size_t name_len) { do { - struct dentry *child = rbnode_dentry(node); + struct wim_dentry *child = rbnode_dentry(node); int result = compare_names(name, name_len, child->file_name_utf8, child->file_name_utf8_len); @@ -598,10 +597,10 @@ get_rbtree_child_with_name(const struct rb_node *node, /* Returns the child of @dentry that has the file name @name. * Returns NULL if no child has the name. */ -struct dentry *get_dentry_child_with_name(const struct dentry *dentry, - const char *name) +struct wim_dentry *get_dentry_child_with_name(const struct wim_dentry *dentry, + const char *name) { - struct rb_node *node = dentry->d_inode->children.rb_node; + struct rb_node *node = dentry->d_inode->i_children.rb_node; if (node) return get_rbtree_child_with_name(node, name, strlen(name)); else @@ -610,15 +609,15 @@ struct dentry *get_dentry_child_with_name(const struct dentry *dentry, /* Retrieves the dentry that has the UTF-8 @path relative to the dentry * @cur_dentry. Returns NULL if no dentry having the path is found. */ -static struct dentry *get_dentry_relative_path(struct dentry *cur_dentry, - const char *path) +static struct wim_dentry *get_dentry_relative_path(struct wim_dentry *cur_dentry, + const char *path) { if (*path == '\0') return cur_dentry; - struct rb_node *node = cur_dentry->d_inode->children.rb_node; + struct rb_node *node = cur_dentry->d_inode->i_children.rb_node; if (node) { - struct dentry *child; + struct wim_dentry *child; size_t base_len; const char *new_path; @@ -628,22 +627,29 @@ static struct dentry *get_dentry_relative_path(struct dentry *cur_dentry, if (child) return get_dentry_relative_path(child, new_path); } + /* errno is set to ENOTDIR if the lookup failed due to reaching a + * non-directory, or ENOENT if the lookup failed otherwise. This maybe + * should be factored out somehow. */ + if (dentry_is_directory(cur_dentry)) + errno = ENOENT; + else + errno = ENOTDIR; return NULL; } /* Returns the dentry corresponding to the UTF-8 @path, or NULL if there is no * such dentry. */ -struct dentry *get_dentry(WIMStruct *w, const char *path) +struct wim_dentry *get_dentry(WIMStruct *w, const char *path) { - struct dentry *root = wim_root_dentry(w); + struct wim_dentry *root = wim_root_dentry(w); while (*path == '/') path++; return get_dentry_relative_path(root, path); } -struct inode *wim_pathname_to_inode(WIMStruct *w, const char *path) +struct wim_inode *wim_pathname_to_inode(WIMStruct *w, const char *path) { - struct dentry *dentry; + struct wim_dentry *dentry; dentry = get_dentry(w, path); if (dentry) return dentry->d_inode; @@ -653,7 +659,7 @@ struct inode *wim_pathname_to_inode(WIMStruct *w, const char *path) /* Returns the dentry that corresponds to the parent directory of @path, or NULL * if the dentry is not found. */ -struct dentry *get_parent_dentry(WIMStruct *w, const char *path) +struct wim_dentry *get_parent_dentry(WIMStruct *w, const char *path) { size_t path_len = strlen(path); char buf[path_len + 1]; @@ -666,7 +672,7 @@ struct dentry *get_parent_dentry(WIMStruct *w, const char *path) } /* Prints the full path of a dentry. */ -int print_dentry_full_path(struct dentry *dentry, void *ignore) +int print_dentry_full_path(struct wim_dentry *dentry, void *ignore) { if (dentry->full_path_utf8) puts(dentry->full_path_utf8); @@ -700,36 +706,36 @@ struct file_attr_flag file_attr_flags[] = { /* Prints a directory entry. @lookup_table is a pointer to the lookup table, if * available. If the dentry is unresolved and the lookup table is NULL, the * lookup table entries will not be printed. Otherwise, they will be. */ -int print_dentry(struct dentry *dentry, void *lookup_table) +int print_dentry(struct wim_dentry *dentry, void *lookup_table) { const u8 *hash; - struct lookup_table_entry *lte; - const struct inode *inode = dentry->d_inode; + struct wim_lookup_table_entry *lte; + const struct wim_inode *inode = dentry->d_inode; char buf[50]; printf("[DENTRY]\n"); printf("Length = %"PRIu64"\n", dentry->length); - printf("Attributes = 0x%x\n", inode->attributes); + printf("Attributes = 0x%x\n", inode->i_attributes); for (size_t i = 0; i < ARRAY_LEN(file_attr_flags); i++) - if (file_attr_flags[i].flag & inode->attributes) + if (file_attr_flags[i].flag & inode->i_attributes) printf(" FILE_ATTRIBUTE_%s is set\n", file_attr_flags[i].name); - printf("Security ID = %d\n", inode->security_id); + printf("Security ID = %d\n", inode->i_security_id); printf("Subdir offset = %"PRIu64"\n", dentry->subdir_offset); - wim_timestamp_to_str(inode->creation_time, buf, sizeof(buf)); + wim_timestamp_to_str(inode->i_creation_time, buf, sizeof(buf)); printf("Creation Time = %s\n", buf); - wim_timestamp_to_str(inode->last_access_time, buf, sizeof(buf)); + wim_timestamp_to_str(inode->i_last_access_time, buf, sizeof(buf)); printf("Last Access Time = %s\n", buf); - wim_timestamp_to_str(inode->last_write_time, buf, sizeof(buf)); + wim_timestamp_to_str(inode->i_last_write_time, buf, sizeof(buf)); printf("Last Write Time = %s\n", buf); - printf("Reparse Tag = 0x%"PRIx32"\n", inode->reparse_tag); - printf("Hard Link Group = 0x%"PRIx64"\n", inode->ino); - printf("Hard Link Group Size = %"PRIu32"\n", inode->link_count); - printf("Number of Alternate Data Streams = %hu\n", inode->num_ads); + printf("Reparse Tag = 0x%"PRIx32"\n", inode->i_reparse_tag); + printf("Hard Link Group = 0x%"PRIx64"\n", inode->i_ino); + printf("Hard Link Group Size = %"PRIu32"\n", inode->i_nlink); + printf("Number of Alternate Data Streams = %hu\n", inode->i_num_ads); printf("Filename (UTF-8) = \"%s\"\n", dentry->file_name_utf8); /*printf("Filename (UTF-8) Length = %hu\n", dentry->file_name_utf8_len);*/ printf("Short Name (UTF-16LE) = \""); @@ -749,11 +755,11 @@ int print_dentry(struct dentry *dentry, void *lookup_table) putchar('\n'); } } - for (u16 i = 0; i < inode->num_ads; i++) { + for (u16 i = 0; i < inode->i_num_ads; i++) { printf("[Alternate Stream Entry %u]\n", i); - printf("Name = \"%s\"\n", inode->ads_entries[i].stream_name_utf8); + printf("Name = \"%s\"\n", inode->i_ads_entries[i].stream_name_utf8); printf("Name Length (UTF-16) = %u\n", - inode->ads_entries[i].stream_name_len); + inode->i_ads_entries[i].stream_name_len); hash = inode_stream_hash(inode, i + 1); if (hash) { printf("Hash = 0x"); @@ -766,40 +772,40 @@ int print_dentry(struct dentry *dentry, void *lookup_table) return 0; } -/* Initializations done on every `struct dentry'. */ -static void dentry_common_init(struct dentry *dentry) +/* Initializations done on every `struct wim_dentry'. */ +static void dentry_common_init(struct wim_dentry *dentry) { - memset(dentry, 0, sizeof(struct dentry)); + memset(dentry, 0, sizeof(struct wim_dentry)); dentry->refcnt = 1; } -static struct inode *new_timeless_inode() +static struct wim_inode *new_timeless_inode() { - struct inode *inode = CALLOC(1, sizeof(struct inode)); + struct wim_inode *inode = CALLOC(1, sizeof(struct wim_inode)); if (inode) { - inode->security_id = -1; - inode->link_count = 1; + inode->i_security_id = -1; + inode->i_nlink = 1; #ifdef WITH_FUSE - inode->next_stream_id = 1; + inode->i_next_stream_id = 1; if (pthread_mutex_init(&inode->i_mutex, NULL) != 0) { ERROR_WITH_ERRNO("Error initializing mutex"); FREE(inode); return NULL; } #endif - INIT_LIST_HEAD(&inode->dentry_list); + INIT_LIST_HEAD(&inode->i_dentry); } return inode; } -static struct inode *new_inode() +static struct wim_inode *new_inode() { - struct inode *inode = new_timeless_inode(); + struct wim_inode *inode = new_timeless_inode(); if (inode) { u64 now = get_wim_timestamp(); - inode->creation_time = now; - inode->last_access_time = now; - inode->last_write_time = now; + inode->i_creation_time = now; + inode->i_last_access_time = now; + inode->i_last_write_time = now; } return inode; } @@ -811,19 +817,16 @@ static struct inode *new_inode() * * Returns a pointer to the new dentry, or NULL if out of memory. */ -#ifndef WITH_FUSE -static -#endif -struct dentry *new_dentry(const char *name) +struct wim_dentry *new_dentry(const char *name) { - struct dentry *dentry; + struct wim_dentry *dentry; - dentry = MALLOC(sizeof(struct dentry)); + dentry = MALLOC(sizeof(struct wim_dentry)); if (!dentry) goto err; dentry_common_init(dentry); - if (change_dentry_name(dentry, name) != 0) + if (set_dentry_name(dentry, name) != 0) goto err; dentry->parent = dentry; @@ -836,9 +839,10 @@ err: } -static struct dentry *__new_dentry_with_inode(const char *name, bool timeless) +static struct wim_dentry * +__new_dentry_with_inode(const char *name, bool timeless) { - struct dentry *dentry; + struct wim_dentry *dentry; dentry = new_dentry(name); if (dentry) { if (timeless) @@ -855,12 +859,12 @@ static struct dentry *__new_dentry_with_inode(const char *name, bool timeless) return dentry; } -struct dentry *new_dentry_with_timeless_inode(const char *name) +struct wim_dentry *new_dentry_with_timeless_inode(const char *name) { return __new_dentry_with_inode(name, true); } -struct dentry *new_dentry_with_inode(const char *name) +struct wim_dentry *new_dentry_with_inode(const char *name) { return __new_dentry_with_inode(name, false); } @@ -883,34 +887,34 @@ static void destroy_ads_entry(struct ads_entry *ads_entry) /* Frees an inode. */ -void free_inode(struct inode *inode) +void free_inode(struct wim_inode *inode) { if (inode) { - if (inode->ads_entries) { - for (u16 i = 0; i < inode->num_ads; i++) - destroy_ads_entry(&inode->ads_entries[i]); - FREE(inode->ads_entries); + if (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); } #ifdef WITH_FUSE - wimlib_assert(inode->num_opened_fds == 0); - FREE(inode->fds); + wimlib_assert(inode->i_num_opened_fds == 0); + FREE(inode->i_fds); pthread_mutex_destroy(&inode->i_mutex); - if (inode->hlist.pprev) - hlist_safe_del(&inode->hlist); + if (inode->i_hlist.pprev) + hlist_del(&inode->i_hlist); #endif - FREE(inode->extracted_file); + FREE(inode->i_extracted_file); FREE(inode); } } /* Decrements link count on an inode and frees it if the link count reaches 0. * */ -static void put_inode(struct inode *inode) +static void put_inode(struct wim_inode *inode) { - wimlib_assert(inode->link_count != 0); - if (--inode->link_count == 0) { + wimlib_assert(inode->i_nlink != 0); + if (--inode->i_nlink == 0) { #ifdef WITH_FUSE - if (inode->num_opened_fds == 0) + if (inode->i_num_opened_fds == 0) #endif { free_inode(inode); @@ -920,9 +924,10 @@ static void put_inode(struct inode *inode) /* Frees a WIM dentry. * - * The inode is freed only if its link count is decremented to 0. + * The corresponding inode (if any) is freed only if its link count is + * decremented to 0. */ -void free_dentry(struct dentry *dentry) +void free_dentry(struct wim_dentry *dentry) { FREE(dentry->file_name); FREE(dentry->file_name_utf8); @@ -933,27 +938,25 @@ void free_dentry(struct dentry *dentry) FREE(dentry); } -void put_dentry(struct dentry *dentry) +void put_dentry(struct wim_dentry *dentry) { wimlib_assert(dentry->refcnt != 0); if (--dentry->refcnt == 0) free_dentry(dentry); } -/* - * This function is passed as an argument to for_dentry_in_tree_depth() in order - * to free a directory tree. __args is a pointer to a `struct free_dentry_args'. - */ -static int do_free_dentry(struct dentry *dentry, void *__lookup_table) +/* This function is passed as an argument to for_dentry_in_tree_depth() in order + * to free a directory tree. */ +static int do_free_dentry(struct wim_dentry *dentry, void *__lookup_table) { - struct lookup_table *lookup_table = __lookup_table; + struct wim_lookup_table *lookup_table = __lookup_table; unsigned i; if (lookup_table) { - struct lookup_table_entry *lte; - struct inode *inode = dentry->d_inode; - wimlib_assert(inode->link_count != 0); - for (i = 0; i <= inode->num_ads; i++) { + struct wim_lookup_table_entry *lte; + struct wim_inode *inode = dentry->d_inode; + wimlib_assert(inode->i_nlink != 0); + 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); @@ -973,13 +976,13 @@ static int do_free_dentry(struct dentry *dentry, void *__lookup_table) * table entries corresponding to the dentries will be * decremented. */ -void free_dentry_tree(struct dentry *root, struct lookup_table *lookup_table) +void free_dentry_tree(struct wim_dentry *root, struct wim_lookup_table *lookup_table) { if (root) for_dentry_in_tree_depth(root, do_free_dentry, lookup_table); } -int increment_dentry_refcnt(struct dentry *dentry, void *ignore) +int increment_dentry_refcnt(struct wim_dentry *dentry, void *ignore) { dentry->refcnt++; return 0; @@ -991,17 +994,17 @@ int increment_dentry_refcnt(struct dentry *dentry, void *ignore) * @dentry: The dentry to link. * @parent: The dentry that will be the parent of @dentry. */ -bool dentry_add_child(struct dentry * restrict parent, - struct dentry * restrict child) +bool dentry_add_child(struct wim_dentry * restrict parent, + struct wim_dentry * restrict child) { wimlib_assert(dentry_is_directory(parent)); - struct rb_root *root = &parent->d_inode->children; + struct rb_root *root = &parent->d_inode->i_children; struct rb_node **new = &(root->rb_node); struct rb_node *rb_parent = NULL; while (*new) { - struct dentry *this = rbnode_dentry(*new); + struct wim_dentry *this = rbnode_dentry(*new); int result = dentry_compare_names(child, this); rb_parent = *new; @@ -1025,37 +1028,34 @@ bool dentry_add_child(struct dentry * restrict parent, * * Note: This merely removes it from the in-memory tree structure. */ -void unlink_dentry(struct dentry *dentry) +void unlink_dentry(struct wim_dentry *dentry) { - struct dentry *parent = dentry->parent; + struct wim_dentry *parent = dentry->parent; if (parent == dentry) return; - rb_erase(&dentry->rb_node, &parent->d_inode->children); + rb_erase(&dentry->rb_node, &parent->d_inode->i_children); } #endif #ifdef WITH_FUSE /* Returns the alternate data stream entry belonging to @inode that has the * stream name @stream_name. */ -struct ads_entry *inode_get_ads_entry(struct inode *inode, +struct ads_entry *inode_get_ads_entry(struct wim_inode *inode, const char *stream_name, u16 *idx_ret) { - size_t stream_name_len; - if (!stream_name) - return NULL; - if (inode->num_ads) { + if (inode->i_num_ads != 0) { u16 i = 0; - stream_name_len = strlen(stream_name); + size_t stream_name_len = strlen(stream_name); do { - if (ads_entry_has_name(&inode->ads_entries[i], + if (ads_entry_has_name(&inode->i_ads_entries[i], stream_name, stream_name_len)) { if (idx_ret) *idx_ret = i; - return &inode->ads_entries[i]; + return &inode->i_ads_entries[i]; } - } while (++i != inode->num_ads); + } while (++i != inode->i_num_ads); } return NULL; } @@ -1066,7 +1066,7 @@ struct ads_entry *inode_get_ads_entry(struct inode *inode, * Add an alternate stream entry to an inode and return a pointer to it, or NULL * if memory could not be allocated. */ -struct ads_entry *inode_add_ads(struct inode *inode, const char *stream_name) +struct ads_entry *inode_add_ads(struct wim_inode *inode, const char *stream_name) { u16 num_ads; struct ads_entry *ads_entries; @@ -1074,42 +1074,42 @@ struct ads_entry *inode_add_ads(struct inode *inode, const char *stream_name) DEBUG("Add alternate data stream \"%s\"", stream_name); - if (inode->num_ads >= 0xfffe) { + if (inode->i_num_ads >= 0xfffe) { ERROR("Too many alternate data streams in one inode!"); return NULL; } - num_ads = inode->num_ads + 1; - ads_entries = REALLOC(inode->ads_entries, - num_ads * sizeof(inode->ads_entries[0])); + 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) { ERROR("Failed to allocate memory for new alternate data stream"); return NULL; } - inode->ads_entries = ads_entries; + inode->i_ads_entries = ads_entries; - new_entry = &inode->ads_entries[num_ads - 1]; + new_entry = &inode->i_ads_entries[num_ads - 1]; if (init_ads_entry(new_entry, stream_name) != 0) return NULL; #ifdef WITH_FUSE - new_entry->stream_id = inode->next_stream_id++; + new_entry->stream_id = inode->i_next_stream_id++; #endif - inode->num_ads = num_ads; + inode->i_num_ads = num_ads; return new_entry; } #endif #ifdef WITH_FUSE /* Remove an alternate data stream from the inode */ -void inode_remove_ads(struct inode *inode, u16 idx, - struct lookup_table *lookup_table) +void inode_remove_ads(struct wim_inode *inode, u16 idx, + struct wim_lookup_table *lookup_table) { struct ads_entry *ads_entry; - struct lookup_table_entry *lte; + struct wim_lookup_table_entry *lte; - wimlib_assert(idx < inode->num_ads); - wimlib_assert(inode->resolved); + wimlib_assert(idx < inode->i_num_ads); + wimlib_assert(inode->i_resolved); - ads_entry = &inode->ads_entries[idx]; + ads_entry = &inode->i_ads_entries[idx]; DEBUG("Remove alternate data stream \"%s\"", ads_entry->stream_name_utf8); @@ -1119,10 +1119,10 @@ void inode_remove_ads(struct inode *inode, u16 idx, destroy_ads_entry(ads_entry); - memcpy(&inode->ads_entries[idx], - &inode->ads_entries[idx + 1], - (inode->num_ads - idx - 1) * sizeof(inode->ads_entries[0])); - inode->num_ads--; + memcpy(&inode->i_ads_entries[idx], + &inode->i_ads_entries[idx + 1], + (inode->i_num_ads - idx - 1) * sizeof(inode->i_ads_entries[0])); + inode->i_num_ads--; } #endif @@ -1134,7 +1134,7 @@ void inode_remove_ads(struct inode *inode, u16 idx, * @p: Pointer to buffer that starts with the first alternate stream entry. * * @inode: Inode to load the alternate data streams into. - * @inode->num_ads must have been set to the number of + * @inode->i_num_ads must have been set to the number of * alternate data streams that are expected. * * @remaining_size: Number of bytes of data remaining in the buffer pointed @@ -1164,19 +1164,19 @@ void inode_remove_ads(struct inode *inode, u16 idx, * * In addition, the entries are 8-byte aligned. * - * Return 0 on success or nonzero on failure. On success, inode->ads_entries - * is set to an array of `struct ads_entry's of length inode->num_ads. On + * Return 0 on success or nonzero on failure. On success, inode->i_ads_entries + * is set to an array of `struct ads_entry's of length inode->i_num_ads. On * failure, @inode is not modified. */ -static int read_ads_entries(const u8 *p, struct inode *inode, +static int read_ads_entries(const u8 *p, struct wim_inode *inode, u64 remaining_size) { u16 num_ads; struct ads_entry *ads_entries; int ret; - num_ads = inode->num_ads; - ads_entries = CALLOC(num_ads, sizeof(inode->ads_entries[0])); + num_ads = inode->i_num_ads; + ads_entries = CALLOC(num_ads, sizeof(inode->i_ads_entries[0])); if (!ads_entries) { ERROR("Could not allocate memory for %"PRIu16" " "alternate data stream entries", num_ads); @@ -1279,9 +1279,9 @@ static int read_ads_entries(const u8 *p, struct inode *inode, else remaining_size -= total_length; } - inode->ads_entries = ads_entries; + inode->i_ads_entries = ads_entries; #ifdef WITH_FUSE - inode->next_stream_id = inode->num_ads + 1; + inode->i_next_stream_id = inode->i_num_ads + 1; #endif return 0; out_free_ads_entries: @@ -1298,7 +1298,7 @@ out_free_ads_entries: * @metadata_resource: Buffer containing the uncompressed metadata resource. * @metadata_resource_len: Length of the metadata resource. * @offset: Offset of this directory entry in the metadata resource. - * @dentry: A `struct dentry' that will be filled in by this function. + * @dentry: A `struct wim_dentry' that will be filled in by this function. * * Return 0 on success or nonzero on failure. On failure, @dentry will have * been modified, but it will not be left with pointers to any allocated @@ -1307,7 +1307,7 @@ out_free_ads_entries: * nonzero, this was a real dentry. */ int read_dentry(const u8 metadata_resource[], u64 metadata_resource_len, - u64 offset, struct dentry *dentry) + u64 offset, struct wim_dentry *dentry) { const u8 *p; u64 calculated_size; @@ -1318,7 +1318,7 @@ int read_dentry(const u8 metadata_resource[], u64 metadata_resource_len, u16 file_name_len; size_t file_name_utf8_len = 0; int ret; - struct inode *inode = NULL; + struct wim_inode *inode = NULL; dentry_common_init(dentry); @@ -1367,8 +1367,8 @@ int read_dentry(const u8 metadata_resource[], u64 metadata_resource_len, if (!inode) return WIMLIB_ERR_NOMEM; - p = get_u32(p, &inode->attributes); - p = get_u32(p, (u32*)&inode->security_id); + p = get_u32(p, &inode->i_attributes); + p = get_u32(p, (u32*)&inode->i_security_id); p = get_u64(p, &dentry->subdir_offset); /* 2 unused fields */ @@ -1376,11 +1376,11 @@ int read_dentry(const u8 metadata_resource[], u64 metadata_resource_len, /*p = get_u64(p, &dentry->unused1);*/ /*p = get_u64(p, &dentry->unused2);*/ - p = get_u64(p, &inode->creation_time); - p = get_u64(p, &inode->last_access_time); - p = get_u64(p, &inode->last_write_time); + p = get_u64(p, &inode->i_creation_time); + p = get_u64(p, &inode->i_last_access_time); + p = get_u64(p, &inode->i_last_write_time); - p = get_bytes(p, SHA1_HASH_SIZE, inode->hash); + p = get_bytes(p, SHA1_HASH_SIZE, inode->i_hash); /* * I don't know what's going on here. It seems like M$ screwed up the @@ -1388,20 +1388,20 @@ int read_dentry(const u8 metadata_resource[], u64 metadata_resource_len, * document it. The WIM_HDR_FLAG_RP_FIX flag in the WIM header might * have something to do with this, but it's not documented. */ - if (inode->attributes & FILE_ATTRIBUTE_REPARSE_POINT) { + if (inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT) { /* ??? */ p += 4; - p = get_u32(p, &inode->reparse_tag); + p = get_u32(p, &inode->i_reparse_tag); p += 4; } else { - p = get_u32(p, &inode->reparse_tag); - p = get_u64(p, &inode->ino); + p = get_u32(p, &inode->i_reparse_tag); + p = get_u64(p, &inode->i_ino); } /* By the way, the reparse_reserved field does not actually exist (at * least when the file is not a reparse point) */ - p = get_u16(p, &inode->num_ads); + p = get_u16(p, &inode->i_num_ads); p = get_u16(p, &short_name_len); p = get_u16(p, &file_name_len); @@ -1507,7 +1507,7 @@ int read_dentry(const u8 metadata_resource[], u64 metadata_resource_len, * aligned boundary, and the alternate data stream entries are NOT * included in the dentry->length field for some reason. */ - if (inode->num_ads != 0) { + if (inode->i_num_ads != 0) { /* Trying different lengths is just a hack to make sure we have * a chance of reading the ADS entries correctly despite the @@ -1568,7 +1568,7 @@ out_free_inode: * @metadata_resource_len: The length of the uncompressed metadata resource, in * bytes. * - * @dentry: A pointer to a `struct dentry' that is the root of the directory + * @dentry: A pointer to a `struct wim_dentry' that is the root of the directory * tree and has already been read from the metadata resource. It * does not need to be the real root because this procedure is * called recursively. @@ -1576,11 +1576,11 @@ out_free_inode: * @return: Zero on success, nonzero on failure. */ int read_dentry_tree(const u8 metadata_resource[], u64 metadata_resource_len, - struct dentry *dentry) + struct wim_dentry *dentry) { u64 cur_offset = dentry->subdir_offset; - struct dentry *child; - struct dentry cur_child; + struct wim_dentry *child; + struct wim_dentry cur_child; int ret; /* @@ -1607,14 +1607,14 @@ int read_dentry_tree(const u8 metadata_resource[], u64 metadata_resource_len, /* Not end of directory. Allocate this child permanently and * link it to the parent and previous child. */ - child = MALLOC(sizeof(struct dentry)); + child = MALLOC(sizeof(struct wim_dentry)); if (!child) { ERROR("Failed to allocate %zu bytes for new dentry", - sizeof(struct dentry)); + sizeof(struct wim_dentry)); ret = WIMLIB_ERR_NOMEM; break; } - memcpy(child, &cur_child, sizeof(struct dentry)); + memcpy(child, &cur_child, sizeof(struct wim_dentry)); dentry_add_child(dentry, child); inode_add_dentry(child, child->d_inode); @@ -1645,11 +1645,11 @@ int read_dentry_tree(const u8 metadata_resource[], u64 metadata_resource_len, * @return: Pointer to the byte after the last byte we wrote as part of the * dentry. */ -static u8 *write_dentry(const struct dentry *dentry, u8 *p) +static u8 *write_dentry(const struct wim_dentry *dentry, u8 *p) { u8 *orig_p = p; const u8 *hash; - const struct inode *inode = dentry->d_inode; + const struct wim_inode *inode = dentry->d_inode; /* We calculate the correct length of the dentry ourselves because the * dentry->length field may been set to an unexpected value from when we @@ -1658,30 +1658,30 @@ static u8 *write_dentry(const struct dentry *dentry, u8 *p) u64 length = dentry_correct_length(dentry); p = put_u64(p, length); - p = put_u32(p, inode->attributes); - p = put_u32(p, inode->security_id); + p = put_u32(p, inode->i_attributes); + p = put_u32(p, inode->i_security_id); p = put_u64(p, dentry->subdir_offset); p = put_u64(p, 0); /* unused1 */ p = put_u64(p, 0); /* unused2 */ - p = put_u64(p, inode->creation_time); - p = put_u64(p, inode->last_access_time); - p = put_u64(p, inode->last_write_time); + p = put_u64(p, inode->i_creation_time); + p = put_u64(p, inode->i_last_access_time); + p = put_u64(p, inode->i_last_write_time); hash = inode_stream_hash(inode, 0); p = put_bytes(p, SHA1_HASH_SIZE, hash); - if (inode->attributes & FILE_ATTRIBUTE_REPARSE_POINT) { + if (inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT) { p = put_zeroes(p, 4); - p = put_u32(p, inode->reparse_tag); + p = put_u32(p, inode->i_reparse_tag); p = put_zeroes(p, 4); } else { u64 link_group_id; p = put_u32(p, 0); - if (inode->link_count == 1) + if (inode->i_nlink == 1) link_group_id = 0; else - link_group_id = inode->ino; + link_group_id = inode->i_ino; p = put_u64(p, link_group_id); } - p = put_u16(p, inode->num_ads); + p = put_u16(p, inode->i_num_ads); p = put_u16(p, dentry->short_name_len); p = put_u16(p, dentry->file_name_len); if (dentry->file_name_len) { @@ -1700,15 +1700,15 @@ static u8 *write_dentry(const struct dentry *dentry, u8 *p) /* Write the alternate data streams, if there are any. Please see * read_ads_entries() for comments about the format of the on-disk * alternate data stream entries. */ - for (u16 i = 0; i < inode->num_ads; i++) { - p = put_u64(p, ads_entry_total_length(&inode->ads_entries[i])); + for (u16 i = 0; i < inode->i_num_ads; i++) { + p = put_u64(p, ads_entry_total_length(&inode->i_ads_entries[i])); p = put_u64(p, 0); /* Unused */ hash = inode_stream_hash(inode, i + 1); p = put_bytes(p, SHA1_HASH_SIZE, hash); - p = put_u16(p, inode->ads_entries[i].stream_name_len); - if (inode->ads_entries[i].stream_name_len) { - p = put_bytes(p, inode->ads_entries[i].stream_name_len, - (u8*)inode->ads_entries[i].stream_name); + p = put_u16(p, inode->i_ads_entries[i].stream_name_len); + if (inode->i_ads_entries[i].stream_name_len) { + p = put_bytes(p, inode->i_ads_entries[i].stream_name_len, + (u8*)inode->i_ads_entries[i].stream_name); p = put_u16(p, 0); } p = put_zeroes(p, (8 - (p - orig_p) % 8) % 8); @@ -1717,16 +1717,16 @@ static u8 *write_dentry(const struct dentry *dentry, u8 *p) return p; } -static int write_dentry_cb(struct dentry *dentry, void *_p) +static int write_dentry_cb(struct wim_dentry *dentry, void *_p) { u8 **p = _p; *p = write_dentry(dentry, *p); return 0; } -static u8 *write_dentry_tree_recursive(const struct dentry *parent, u8 *p); +static u8 *write_dentry_tree_recursive(const struct wim_dentry *parent, u8 *p); -static int write_dentry_tree_recursive_cb(struct dentry *dentry, void *_p) +static int write_dentry_tree_recursive_cb(struct wim_dentry *dentry, void *_p) { u8 **p = _p; *p = write_dentry_tree_recursive(dentry, *p); @@ -1735,7 +1735,7 @@ static int write_dentry_tree_recursive_cb(struct dentry *dentry, void *_p) /* Recursive function that writes a dentry tree rooted at @parent, not including * @parent itself, which has already been written. */ -static u8 *write_dentry_tree_recursive(const struct dentry *parent, u8 *p) +static u8 *write_dentry_tree_recursive(const struct wim_dentry *parent, u8 *p) { /* Nothing to do if this dentry has no children. */ if (parent->subdir_offset == 0) @@ -1747,13 +1747,13 @@ static u8 *write_dentry_tree_recursive(const struct dentry *parent, u8 *p) * recursively writing the directory trees rooted at each of the child * dentries, since the on-disk dentries for a dentry's children are * always located at consecutive positions in the metadata resource! */ - for_dentry_in_rbtree(parent->d_inode->children.rb_node, write_dentry_cb, &p); + for_dentry_in_rbtree(parent->d_inode->i_children.rb_node, write_dentry_cb, &p); /* write end of directory entry */ p = put_u64(p, 0); /* Recurse on children. */ - for_dentry_in_rbtree(parent->d_inode->children.rb_node, + for_dentry_in_rbtree(parent->d_inode->i_children.rb_node, write_dentry_tree_recursive_cb, &p); return p; } @@ -1765,7 +1765,7 @@ static u8 *write_dentry_tree_recursive(const struct dentry *parent, u8 *p) * * Returns pointer to the byte after the last byte we wrote. */ -u8 *write_dentry_tree(const struct dentry *root, u8 *p) +u8 *write_dentry_tree(const struct wim_dentry *root, u8 *p) { DEBUG("Writing dentry tree."); wimlib_assert(dentry_is_root(root)); diff --git a/src/dentry.h b/src/dentry.h index bf136191..5c1c1aad 100644 --- a/src/dentry.h +++ b/src/dentry.h @@ -13,14 +13,14 @@ #endif struct stat; -struct lookup_table; +struct wim_lookup_table; struct WIMStruct; -struct lookup_table_entry; -struct wimlib_fd; -struct inode; -struct dentry; +struct wim_lookup_table_entry; +struct wimfs_fd; +struct wim_inode; +struct wim_dentry; -/* Size of the struct dentry up to and including the file_name_len. */ +/* Size of the struct wim_dentry up to and including the file_name_len. */ #define WIM_DENTRY_DISK_SIZE 102 /* Size of on-disk WIM alternate data stream entry, in bytes, up to and @@ -71,7 +71,7 @@ struct ads_entry { /* The corresponding lookup table entry (only for resolved * streams) */ - struct lookup_table_entry *lte; + struct wim_lookup_table_entry *lte; }; /* Length of stream name (UTF-16). This is in bytes, not characters, @@ -117,7 +117,7 @@ static inline bool ads_entries_have_same_name(const struct ads_entry *entry_1, * information, such as file attributes, the security descriptor, and file * streams is replicated in each hard-linked dentry, even though this * information really is associated with an inode. In-memory, we fix up this - * flaw by allocating a `struct inode' for each dentry that contains some of + * flaw by allocating a `struct wim_inode' for each dentry that contains some of * this duplicated information, then combining the inodes for each hard link * group together. * @@ -131,11 +131,11 @@ static inline bool ads_entries_have_same_name(const struct ads_entry *entry_1, * conflicting fields to split up the hard link groups. (See fix_inodes() in * hardlink.c). */ -struct dentry { +struct wim_dentry { /* Byte 0 */ /* The inode for this dentry */ - struct inode *d_inode; + struct wim_inode *d_inode; /* Byte 8 */ @@ -170,10 +170,10 @@ struct dentry { /* Byte 64 */ /* List of dentries in the inode (hard link set) */ - struct list_head inode_dentry_list; + struct list_head d_alias; /* The parent of this directory entry. */ - struct dentry *parent; + struct wim_dentry *parent; /* * Size of directory entry on disk, in bytes. Typical size is around @@ -217,7 +217,7 @@ struct dentry { char *full_path_utf8; }; -#define rbnode_dentry(node) container_of(node, struct dentry, rb_node) +#define rbnode_dentry(node) container_of(node, struct wim_dentry, rb_node) /* * WIM inode. @@ -225,34 +225,34 @@ struct dentry { * As mentioned above, in the WIM file that is no on-disk analogue of a real * inode, as most of these fields are duplicated in the dentries. */ -struct inode { +struct wim_inode { /* Timestamps for the inode. The timestamps are the number of * 100-nanosecond intervals that have elapsed since 12:00 A.M., January * 1st, 1601, UTC. This is the same format used in NTFS inodes. */ - u64 creation_time; - u64 last_access_time; - u64 last_write_time; + u64 i_creation_time; + u64 i_last_access_time; + u64 i_last_write_time; /* The file attributes associated with this inode. This is a bitwise OR * of the FILE_ATTRIBUTE_* flags. */ - u32 attributes; + u32 i_attributes; /* The index of the security descriptor in the WIM image's table of * security descriptors that contains this file's security information. * If -1, no security information exists for this file. */ - int32_t security_id; + int32_t i_security_id; /* %true iff the inode's lookup table entries has been resolved (i.e. * the @lte field is valid, but the @hash field is not valid) * * (This is not an on-disk field.) */ - u8 resolved : 1; + u8 i_resolved : 1; /* %true iff verify_inode() has run on this inode. */ - u8 verified : 1; + u8 i_verified : 1; /* Number of alternate data streams associated with this inode */ - u16 num_ads; + u16 i_num_ads; /* A hash of the file's contents, or a pointer to the lookup table entry * for this dentry if the lookup table entries have been resolved. @@ -261,47 +261,47 @@ struct inode { * opposed to the alternate (named) file streams, which may have their * own lookup table entries. */ union { - u8 hash[SHA1_HASH_SIZE]; - struct lookup_table_entry *lte; + u8 i_hash[SHA1_HASH_SIZE]; + struct wim_lookup_table_entry *i_lte; }; /* Identity of a reparse point. See * http://msdn.microsoft.com/en-us/library/windows/desktop/aa365503(v=vs.85).aspx * for what a reparse point is. */ - u32 reparse_tag; + u32 i_reparse_tag; /* Number of dentries that reference this inode */ - u32 link_count; + u32 i_nlink; /* Alternate data stream entries. */ - struct ads_entry *ads_entries; + struct ads_entry *i_ads_entries; /* Inode number */ - u64 ino; + u64 i_ino; /* List of dentries that reference this inode (there should be * link_count of them) */ - struct list_head dentry_list; + struct list_head i_dentry; - struct hlist_node hlist; + struct hlist_node i_hlist; - struct list_head lte_inode_list; + struct list_head i_lte_inode_list; - char *extracted_file; + char *i_extracted_file; /* Root of a red-black tree storing the children of this inode (if * non-empty, implies the inode is a directory, although that is also * noted in the @attributes field.) */ - struct rb_root children; + struct rb_root i_children; #ifdef WITH_FUSE /* wimfs file descriptors table for the inode */ - u16 num_opened_fds; - u16 num_allocated_fds; - struct wimlib_fd **fds; + u16 i_num_opened_fds; + u16 i_num_allocated_fds; + struct wimfs_fd **i_fds; /* Next alternate data stream ID to be assigned */ - u32 next_stream_id; + u32 i_next_stream_id; /* This mutex protects the inode's file descriptors table during * read-only mounts. Read-write mounts are still restricted to 1 @@ -311,129 +311,126 @@ struct inode { }; #define inode_for_each_dentry(dentry, inode) \ - list_for_each_entry((dentry), &(inode)->dentry_list, inode_dentry_list) + list_for_each_entry((dentry), &(inode)->i_dentry, d_alias) #define inode_add_dentry(dentry, inode) \ - list_add_tail(&(dentry)->inode_dentry_list, &(inode)->dentry_list) + list_add_tail(&(dentry)->d_alias, &(inode)->i_dentry) + +static inline struct wim_dentry *inode_first_dentry(struct wim_inode *inode) +{ + return container_of(inode->i_dentry.next, struct wim_dentry, d_alias); +} -static inline bool dentry_is_first_in_inode(const struct dentry *dentry) +static inline bool dentry_is_first_in_inode(const struct wim_dentry *dentry) { - return container_of(dentry->d_inode->dentry_list.next, - struct dentry, - inode_dentry_list) == dentry; + return inode_first_dentry(dentry->d_inode) == dentry; } -extern u64 dentry_correct_total_length(const struct dentry *dentry); +extern u64 dentry_correct_total_length(const struct wim_dentry *dentry); -extern int for_dentry_in_tree(struct dentry *root, - int (*visitor)(struct dentry*, void*), +extern int for_dentry_in_tree(struct wim_dentry *root, + int (*visitor)(struct wim_dentry*, void*), void *args); extern int for_dentry_in_rbtree(struct rb_node *node, - int (*visitor)(struct dentry *, void *), + int (*visitor)(struct wim_dentry *, void *), void *arg); -extern int for_dentry_in_tree_depth(struct dentry *root, - int (*visitor)(struct dentry*, void*), +extern int for_dentry_in_tree_depth(struct wim_dentry *root, + int (*visitor)(struct wim_dentry*, void*), void *args); -extern int calculate_dentry_full_path(struct dentry *dentry, void *ignore); -extern void calculate_subdir_offsets(struct dentry *dentry, u64 *subdir_offset_p); -extern int get_names(char **name_utf16_ret, char **name_utf8_ret, - u16 *name_utf16_len_ret, u16 *name_utf8_len_ret, - const char *name); +extern int calculate_dentry_full_path(struct wim_dentry *dentry, void *ignore); +extern void calculate_subdir_offsets(struct wim_dentry *dentry, u64 *subdir_offset_p); +extern int set_dentry_name(struct wim_dentry *dentry, const char *new_name); -extern struct dentry *get_dentry(struct WIMStruct *w, const char *path); -extern struct inode *wim_pathname_to_inode(struct WIMStruct *w, +extern struct wim_dentry *get_dentry(struct WIMStruct *w, const char *path); +extern struct wim_inode *wim_pathname_to_inode(struct WIMStruct *w, const char *path); -extern struct dentry *get_dentry_child_with_name(const struct dentry *dentry, +extern struct wim_dentry *get_dentry_child_with_name(const struct wim_dentry *dentry, const char *name); -extern struct dentry *get_parent_dentry(struct WIMStruct *w, const char *path); +extern struct wim_dentry *get_parent_dentry(struct WIMStruct *w, const char *path); -extern int print_dentry(struct dentry *dentry, void *lookup_table); -extern int print_dentry_full_path(struct dentry *entry, void *ignore); - -#ifdef WITH_FUSE -extern struct dentry *new_dentry(const char *name); -#endif +extern int print_dentry(struct wim_dentry *dentry, void *lookup_table); +extern int print_dentry_full_path(struct wim_dentry *entry, void *ignore); -extern struct dentry *new_dentry_with_inode(const char *name); -extern struct dentry *new_dentry_with_timeless_inode(const char *name); +extern struct wim_dentry *new_dentry(const char *name); +extern struct wim_dentry *new_dentry_with_inode(const char *name); +extern struct wim_dentry *new_dentry_with_timeless_inode(const char *name); -extern void free_inode(struct inode *inode); -extern void free_dentry(struct dentry *dentry); -extern void put_dentry(struct dentry *dentry); +extern void free_inode(struct wim_inode *inode); +extern void free_dentry(struct wim_dentry *dentry); +extern void put_dentry(struct wim_dentry *dentry); -extern void free_dentry_tree(struct dentry *root, - struct lookup_table *lookup_table); -extern int increment_dentry_refcnt(struct dentry *dentry, void *ignore); +extern void free_dentry_tree(struct wim_dentry *root, + struct wim_lookup_table *lookup_table); +extern int increment_dentry_refcnt(struct wim_dentry *dentry, void *ignore); -extern void unlink_dentry(struct dentry *dentry); -extern bool dentry_add_child(struct dentry * restrict parent, - struct dentry * restrict child); +extern void unlink_dentry(struct wim_dentry *dentry); +extern bool dentry_add_child(struct wim_dentry * restrict parent, + struct wim_dentry * restrict child); -extern struct ads_entry *inode_get_ads_entry(struct inode *inode, +extern struct ads_entry *inode_get_ads_entry(struct wim_inode *inode, const char *stream_name, u16 *idx_ret); -extern struct ads_entry *inode_add_ads(struct inode *dentry, +extern struct ads_entry *inode_add_ads(struct wim_inode *dentry, const char *stream_name); -extern void inode_remove_ads(struct inode *inode, u16 idx, - struct lookup_table *lookup_table); +extern void inode_remove_ads(struct wim_inode *inode, u16 idx, + struct wim_lookup_table *lookup_table); extern int read_dentry(const u8 metadata_resource[], u64 metadata_resource_len, - u64 offset, struct dentry *dentry); + u64 offset, struct wim_dentry *dentry); extern int read_dentry_tree(const u8 metadata_resource[], - u64 metadata_resource_len, struct dentry *dentry); + u64 metadata_resource_len, struct wim_dentry *dentry); -extern u8 *write_dentry_tree(const struct dentry *tree, u8 *p); +extern u8 *write_dentry_tree(const struct wim_dentry *tree, u8 *p); -static inline bool dentry_is_root(const struct dentry *dentry) +static inline bool dentry_is_root(const struct wim_dentry *dentry) { return dentry->parent == dentry; } -static inline bool inode_is_directory(const struct inode *inode) +static inline bool inode_is_directory(const struct wim_inode *inode) { - return (inode->attributes & FILE_ATTRIBUTE_DIRECTORY) - && !(inode->attributes & FILE_ATTRIBUTE_REPARSE_POINT); + return (inode->i_attributes & FILE_ATTRIBUTE_DIRECTORY) + && !(inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT); } -static inline bool dentry_is_directory(const struct dentry *dentry) +static inline bool dentry_is_directory(const struct wim_dentry *dentry) { return inode_is_directory(dentry->d_inode); } /* For our purposes, we consider "real" symlinks and "junction points" to both * be symlinks. */ -static inline bool inode_is_symlink(const struct inode *inode) +static inline bool inode_is_symlink(const struct wim_inode *inode) { - return (inode->attributes & FILE_ATTRIBUTE_REPARSE_POINT) - && ((inode->reparse_tag == WIM_IO_REPARSE_TAG_SYMLINK) || - inode->reparse_tag == WIM_IO_REPARSE_TAG_MOUNT_POINT); + return (inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT) + && ((inode->i_reparse_tag == WIM_IO_REPARSE_TAG_SYMLINK) || + inode->i_reparse_tag == WIM_IO_REPARSE_TAG_MOUNT_POINT); } -static inline bool inode_is_regular_file(const struct inode *inode) +static inline bool inode_is_regular_file(const struct wim_inode *inode) { return !inode_is_directory(inode) && !inode_is_symlink(inode); } -static inline bool dentry_is_regular_file(const struct dentry *dentry) +static inline bool dentry_is_regular_file(const struct wim_dentry *dentry) { return inode_is_regular_file(dentry->d_inode); } -static inline bool inode_has_children(const struct inode *inode) +static inline bool inode_has_children(const struct wim_inode *inode) { - return inode->children.rb_node != NULL; + return inode->i_children.rb_node != NULL; } -static inline bool dentry_is_empty_directory(const struct dentry *dentry) +static inline bool dentry_has_children(const struct wim_dentry *dentry) { - const struct inode *inode = dentry->d_inode; - return inode_is_directory(inode) && !inode_has_children(inode); + return inode_has_children(dentry->d_inode); } #endif diff --git a/src/export_image.c b/src/export_image.c index 58d6057a..1cbb52d7 100644 --- a/src/export_image.c +++ b/src/export_image.c @@ -26,16 +26,16 @@ #include "lookup_table.h" #include "xml.h" -static int inode_allocate_needed_ltes(struct inode *inode, - struct lookup_table *src_lookup_table, - struct lookup_table *dest_lookup_table, +static int inode_allocate_needed_ltes(struct wim_inode *inode, + struct wim_lookup_table *src_lookup_table, + struct wim_lookup_table *dest_lookup_table, struct list_head *lte_list_head) { - struct lookup_table_entry *src_lte, *dest_lte; + struct wim_lookup_table_entry *src_lte, *dest_lte; unsigned i; inode_unresolve_ltes(inode); - for (i = 0; i <= inode->num_ads; i++) { + for (i = 0; i <= inode->i_num_ads; i++) { src_lte = inode_stream_lte_unresolved(inode, i, src_lookup_table); if (src_lte && src_lte->out_refcnt == 0) { @@ -53,19 +53,19 @@ static int inode_allocate_needed_ltes(struct inode *inode, return 0; } -static void inode_move_ltes_to_table(struct inode *inode, - struct lookup_table *src_lookup_table, - struct lookup_table *dest_lookup_table, +static void inode_move_ltes_to_table(struct wim_inode *inode, + struct wim_lookup_table *src_lookup_table, + struct wim_lookup_table *dest_lookup_table, struct list_head *lte_list_head) { - struct lookup_table_entry *src_lte, *dest_lte; + struct wim_lookup_table_entry *src_lte, *dest_lte; unsigned i; - struct dentry *dentry; + struct wim_dentry *dentry; inode_for_each_dentry(dentry, inode) dentry->refcnt++; - for (i = 0; i <= inode->num_ads; i++) { + for (i = 0; i <= inode->i_num_ads; i++) { src_lte = inode_stream_lte_unresolved(inode, i, src_lookup_table); if (src_lte) { dest_lte = inode_stream_lte_unresolved(inode, i, @@ -77,14 +77,14 @@ static void inode_move_ltes_to_table(struct inode *inode, next = lte_list_head->next; list_del(next); dest_lte = container_of(next, - struct lookup_table_entry, + struct wim_lookup_table_entry, staging_list); dest_lte->part_number = 1; dest_lte->refcnt = 0; wimlib_assert(hashes_equal(dest_lte->hash, src_lte->hash)); lookup_table_insert(dest_lookup_table, dest_lte); } - dest_lte->refcnt += inode->link_count; + dest_lte->refcnt += inode->i_nlink; } } } @@ -104,11 +104,11 @@ WIMLIBAPI int wimlib_export_image(WIMStruct *src_wim, { int ret; struct wim_security_data *sd; - struct lookup_table *joined_tab, *src_wim_tab_save; + struct wim_lookup_table *joined_tab, *src_wim_tab_save; struct image_metadata *src_imd; struct hlist_node *cur_node; struct list_head lte_list_head; - struct inode *inode; + struct wim_inode *inode; if (dest_wim->hdr.total_parts != 1) { ERROR("Exporting an image to a split WIM is " @@ -212,7 +212,7 @@ WIMLIBAPI int wimlib_export_image(WIMStruct *src_wim, for_lookup_table_entry(src_wim->lookup_table, lte_zero_out_refcnt, NULL); src_imd = wim_get_current_image_metadata(src_wim); - hlist_for_each_entry(inode, cur_node, &src_imd->inode_list, hlist) { + hlist_for_each_entry(inode, cur_node, &src_imd->inode_list, i_hlist) { ret = inode_allocate_needed_ltes(inode, src_wim->lookup_table, dest_wim->lookup_table, @@ -243,7 +243,7 @@ WIMLIBAPI int wimlib_export_image(WIMStruct *src_wim, * the lookup table of the destination WIM and the boot index, if * needed. */ sd->refcnt++; - hlist_for_each_entry(inode, cur_node, &src_imd->inode_list, hlist) { + hlist_for_each_entry(inode, cur_node, &src_imd->inode_list, i_hlist) { inode_move_ltes_to_table(inode, src_wim->lookup_table, dest_wim->lookup_table, @@ -259,7 +259,7 @@ out_xml_delete_image: xml_delete_image(&dest_wim->wim_info, dest_wim->hdr.image_count); out_free_ltes: { - struct lookup_table_entry *lte, *tmp; + struct wim_lookup_table_entry *lte, *tmp; list_for_each_entry_safe(lte, tmp, <e_list_head, staging_list) free_lookup_table_entry(lte); } diff --git a/src/extract_image.c b/src/extract_image.c index d9912c7b..0d1db2c0 100644 --- a/src/extract_image.c +++ b/src/extract_image.c @@ -54,10 +54,10 @@ #include #endif -static int extract_regular_file_linked(struct dentry *dentry, +static int extract_regular_file_linked(struct wim_dentry *dentry, const char *output_path, struct apply_args *args, - struct lookup_table_entry *lte) + struct wim_lookup_table_entry *lte) { /* This mode overrides the normal hard-link extraction and * instead either symlinks or hardlinks *all* identical files in @@ -114,44 +114,44 @@ static int extract_regular_file_linked(struct dentry *dentry, return 0; } -static int extract_regular_file_unlinked(struct dentry *dentry, +static int extract_regular_file_unlinked(struct wim_dentry *dentry, struct apply_args *args, const char *output_path, - struct lookup_table_entry *lte) + struct wim_lookup_table_entry *lte) { /* Normal mode of extraction. Regular files and hard links are * extracted in the way that they appear in the WIM. */ int out_fd; int ret; - struct inode *inode = dentry->d_inode; + struct wim_inode *inode = dentry->d_inode; if (!((args->extract_flags & WIMLIB_EXTRACT_FLAG_MULTI_IMAGE) && (args->extract_flags & (WIMLIB_EXTRACT_FLAG_SYMLINK | WIMLIB_EXTRACT_FLAG_HARDLINK)))) { - /* If the dentry is one of a hard link set of at least 2 + /* If the dentry is part of a hard link set of at least 2 * dentries and one of the other dentries has already been * extracted, make a hard link to the file corresponding to this - * already-extracted directory. Otherwise, extract the file, - * and set the inode->extracted_file field so that other - * dentries in the hard link group can link to it. */ - if (inode->link_count > 1) { - if (inode->extracted_file) { + * already-extracted directory. Otherwise, extract the file and + * set the inode->i_extracted_file field so that other dentries + * in the hard link group can link to it. */ + if (inode->i_nlink > 1) { + if (inode->i_extracted_file) { DEBUG("Extracting hard link `%s' => `%s'", - output_path, inode->extracted_file); - if (link(inode->extracted_file, output_path) != 0) { + output_path, inode->i_extracted_file); + if (link(inode->i_extracted_file, output_path) != 0) { ERROR_WITH_ERRNO("Failed to hard link " "`%s' to `%s'", output_path, - inode->extracted_file); + inode->i_extracted_file); return WIMLIB_ERR_LINK; } return 0; } - FREE(inode->extracted_file); - inode->extracted_file = STRDUP(output_path); - if (!inode->extracted_file) { + FREE(inode->i_extracted_file); + inode->i_extracted_file = STRDUP(output_path); + if (!inode->i_extracted_file) { ERROR("Failed to allocate memory for filename"); return WIMLIB_ERR_NOMEM; } @@ -188,15 +188,12 @@ out: return ret; } -/* - * Extracts a regular file from the WIM archive. - */ -static int extract_regular_file(struct dentry *dentry, +static int extract_regular_file(struct wim_dentry *dentry, struct apply_args *args, const char *output_path) { - struct lookup_table_entry *lte; - const struct inode *inode = dentry->d_inode; + struct wim_lookup_table_entry *lte; + const struct wim_inode *inode = dentry->d_inode; lte = inode_unnamed_lte_resolved(inode); @@ -214,14 +211,14 @@ static int extract_regular_file(struct dentry *dentry, return extract_regular_file_unlinked(dentry, args, output_path, lte); } -static int extract_symlink(struct dentry *dentry, +static int extract_symlink(struct wim_dentry *dentry, struct apply_args *args, const char *output_path) { char target[4096]; ssize_t ret = inode_readlink(dentry->d_inode, target, sizeof(target), args->w, 0); - struct lookup_table_entry *lte; + struct wim_lookup_table_entry *lte; if (ret <= 0) { ERROR("Could not read the symbolic link from dentry `%s'", @@ -239,13 +236,6 @@ static int extract_symlink(struct dentry *dentry, return 0; } -/* - * Extracts a directory from the WIM archive. - * - * @dentry: The directory entry for the directory. - * @output_path: The path to which the directory is to be extracted to. - * @return: True on success, false on failure. - */ static int extract_directory(const char *output_path, bool is_root) { int ret; @@ -266,7 +256,6 @@ static int extract_directory(const char *output_path, bool is_root) return WIMLIB_ERR_STAT; } } - /* Compute the output path directory to the directory. */ if (mkdir(output_path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) != 0) { ERROR_WITH_ERRNO("Cannot create directory `%s'", @@ -276,14 +265,11 @@ static int extract_directory(const char *output_path, bool is_root) return 0; } -/* - * Extracts a file, directory, or symbolic link from the WIM archive. For use - * in for_dentry_in_tree(). - */ -static int apply_dentry_normal(struct dentry *dentry, void *arg) +/* Extracts a file, directory, or symbolic link from the WIM archive. */ +static int apply_dentry_normal(struct wim_dentry *dentry, void *arg) { struct apply_args *args = arg; - struct inode *inode = dentry->d_inode; + struct wim_inode *inode = dentry->d_inode; size_t len; len = strlen(args->target); @@ -300,22 +286,24 @@ static int apply_dentry_normal(struct dentry *dentry, void *arg) return extract_regular_file(dentry, args, output_path); } -/* Apply timestamp to extracted file */ -static int apply_dentry_timestamps_normal(struct dentry *dentry, void *arg) +/* Apply timestamps to an extracted file or directory */ +static int apply_dentry_timestamps_normal(struct wim_dentry *dentry, void *arg) { struct apply_args *args = arg; size_t len = strlen(args->target); char output_path[len + dentry->full_path_utf8_len + 1]; - const struct inode *inode = dentry->d_inode; + const struct wim_inode *inode = dentry->d_inode; int ret; memcpy(output_path, args->target, len); memcpy(output_path + len, dentry->full_path_utf8, dentry->full_path_utf8_len); output_path[len + dentry->full_path_utf8_len] = '\0'; + /* Convert the WIM timestamps, which are accurate to 100 nanoseconds, + * into struct timeval's. */ struct timeval tv[2]; - wim_timestamp_to_timeval(inode->last_access_time, &tv[0]); - wim_timestamp_to_timeval(inode->last_write_time, &tv[1]); + wim_timestamp_to_timeval(inode->i_last_access_time, &tv[0]); + wim_timestamp_to_timeval(inode->i_last_write_time, &tv[1]); #ifdef HAVE_LUTIMES ret = lutimes(output_path, tv); #else @@ -326,8 +314,8 @@ static int apply_dentry_timestamps_normal(struct dentry *dentry, void *arg) #ifdef HAVE_UTIME if (errno == ENOSYS) { struct utimbuf buf; - buf.actime = wim_timestamp_to_unix(inode->last_access_time); - buf.modtime = wim_timestamp_to_unix(inode->last_write_time); + buf.actime = wim_timestamp_to_unix(inode->i_last_access_time); + buf.modtime = wim_timestamp_to_unix(inode->i_last_write_time); if (utime(output_path, &buf) == 0) return 0; } @@ -341,7 +329,9 @@ static int apply_dentry_timestamps_normal(struct dentry *dentry, void *arg) return 0; } -static int maybe_apply_dentry(struct dentry *dentry, void *arg) +/* Extract a dentry if it hasn't already been extracted, and either the dentry + * has no streams or WIMLIB_EXTRACT_FLAG_NO_STREAMS is not specified. */ +static int maybe_apply_dentry(struct wim_dentry *dentry, void *arg) { struct apply_args *args = arg; int ret; @@ -367,9 +357,9 @@ static int maybe_apply_dentry(struct dentry *dentry, void *arg) static int cmp_streams_by_wim_position(const void *p1, const void *p2) { - const struct lookup_table_entry *lte1, *lte2; - lte1 = *(const struct lookup_table_entry**)p1; - lte2 = *(const struct lookup_table_entry**)p2; + const struct wim_lookup_table_entry *lte1, *lte2; + lte1 = *(const struct wim_lookup_table_entry**)p1; + lte2 = *(const struct wim_lookup_table_entry**)p2; if (lte1->resource_entry.offset < lte2->resource_entry.offset) return -1; else if (lte1->resource_entry.offset > lte2->resource_entry.offset) @@ -382,7 +372,7 @@ static int sort_stream_list_by_wim_position(struct list_head *stream_list) { struct list_head *cur; size_t num_streams; - struct lookup_table_entry **array; + struct wim_lookup_table_entry **array; size_t i; size_t array_size; @@ -398,7 +388,7 @@ static int sort_stream_list_by_wim_position(struct list_head *stream_list) } cur = stream_list->next; for (i = 0; i < num_streams; i++) { - array[i] = container_of(cur, struct lookup_table_entry, staging_list); + array[i] = container_of(cur, struct wim_lookup_table_entry, staging_list); cur = cur->next; } @@ -415,7 +405,7 @@ static void calculate_bytes_to_extract(struct list_head *stream_list, int extract_flags, union wimlib_progress_info *progress) { - struct lookup_table_entry *lte; + struct wim_lookup_table_entry *lte; u64 total_bytes = 0; u64 num_streams = 0; @@ -442,7 +432,7 @@ static void calculate_bytes_to_extract(struct list_head *stream_list, progress->extract.completed_bytes = 0; } -static void maybe_add_stream_for_extraction(struct lookup_table_entry *lte, +static void maybe_add_stream_for_extraction(struct wim_lookup_table_entry *lte, struct list_head *stream_list) { if (++lte->out_refcnt == 1) { @@ -451,30 +441,29 @@ static void maybe_add_stream_for_extraction(struct lookup_table_entry *lte, } } -static void inode_find_streams_for_extraction(struct inode *inode, +static void inode_find_streams_for_extraction(struct wim_inode *inode, struct list_head *stream_list, int extract_flags) { - struct lookup_table_entry *lte; + struct wim_lookup_table_entry *lte; bool inode_added = false; lte = inode_unnamed_lte_resolved(inode); - if (lte) { maybe_add_stream_for_extraction(lte, stream_list); - list_add_tail(&inode->lte_inode_list, <e->inode_list); + list_add_tail(&inode->i_lte_inode_list, <e->inode_list); inode_added = true; } #ifdef WITH_NTFS_3G if (extract_flags & WIMLIB_EXTRACT_FLAG_NTFS) { - for (unsigned i = 0; i < inode->num_ads; i++) { - if (inode->ads_entries[i].stream_name_len != 0) { - lte = inode->ads_entries[i].lte; + for (unsigned i = 0; i < inode->i_num_ads; i++) { + if (inode->i_ads_entries[i].stream_name_len != 0) { + lte = inode->i_ads_entries[i].lte; if (lte) { maybe_add_stream_for_extraction(lte, stream_list); if (!inode_added) { - list_add_tail(&inode->lte_inode_list, + list_add_tail(&inode->i_lte_inode_list, <e->inode_list); inode_added = true; } @@ -487,17 +476,17 @@ static void inode_find_streams_for_extraction(struct inode *inode, static void find_streams_for_extraction(struct hlist_head *inode_list, struct list_head *stream_list, - struct lookup_table *lookup_table, + struct wim_lookup_table *lookup_table, int extract_flags) { - struct inode *inode; + struct wim_inode *inode; struct hlist_node *cur; - struct dentry *dentry; + struct wim_dentry *dentry; for_lookup_table_entry(lookup_table, lte_zero_out_refcnt, NULL); INIT_LIST_HEAD(stream_list); - hlist_for_each_entry(inode, cur, inode_list, hlist) { - if (!inode->resolved) + hlist_for_each_entry(inode, cur, inode_list, i_hlist) { + if (!inode->i_resolved) inode_resolve_ltes(inode, lookup_table); inode_for_each_dentry(dentry, inode) dentry->is_extracted = 0; @@ -507,8 +496,8 @@ static void find_streams_for_extraction(struct hlist_head *inode_list, } struct apply_operations { - int (*apply_dentry)(struct dentry *dentry, void *arg); - int (*apply_dentry_timestamps)(struct dentry *dentry, void *arg); + int (*apply_dentry)(struct wim_dentry *dentry, void *arg); + int (*apply_dentry_timestamps)(struct wim_dentry *dentry, void *arg); }; static const struct apply_operations normal_apply_operations = { @@ -530,9 +519,9 @@ static int apply_stream_list(struct list_head *stream_list, { uint64_t bytes_per_progress = args->progress.extract.total_bytes / 100; uint64_t next_progress = bytes_per_progress; - struct lookup_table_entry *lte; - struct inode *inode; - struct dentry *dentry; + struct wim_lookup_table_entry *lte; + struct wim_inode *inode; + struct wim_dentry *dentry; int ret; /* This complicated loop is essentially looping through the dentries, @@ -546,7 +535,7 @@ static int apply_stream_list(struct list_head *stream_list, /* For each distinct stream to be extracted */ list_for_each_entry(lte, stream_list, staging_list) { /* For each inode that contains the stream */ - list_for_each_entry(inode, <e->inode_list, lte_inode_list) { + list_for_each_entry(inode, <e->inode_list, i_lte_inode_list) { /* For each dentry that points to the inode */ inode_for_each_dentry(dentry, inode) { /* Extract the dentry if it was not already @@ -576,6 +565,8 @@ static int apply_stream_list(struct list_head *stream_list, return 0; } +/* Extracts the image @image from the WIM @w to the directory or NTFS volume + * @target. */ static int extract_single_image(WIMStruct *w, int image, const char *target, int extract_flags, wimlib_progress_func_t progress_func) @@ -591,7 +582,6 @@ static int extract_single_image(WIMStruct *w, int image, args.target = target; args.extract_flags = extract_flags; args.num_lutimes_warnings = 0; - args.target = target; args.stream_list = &stream_list; args.progress_func = progress_func; @@ -622,9 +612,11 @@ static int extract_single_image(WIMStruct *w, int image, inode_list = &w->image_metadata[image - 1].inode_list; + /* Build a list of the streams that need to be extracted */ find_streams_for_extraction(inode_list, &stream_list, w->lookup_table, extract_flags); + /* Calculate the number of bytes of data that will be extracted */ calculate_bytes_to_extract(&stream_list, extract_flags, &args.progress); @@ -633,6 +625,9 @@ static int extract_single_image(WIMStruct *w, int image, &args.progress); } + /* If a sequential extraction was specified, sort the streams to be + * extracted by their position in the WIM file, so that the WIM file can + * be read sequentially. */ if (extract_flags & WIMLIB_EXTRACT_FLAG_SEQUENTIAL) { ret = sort_stream_list_by_wim_position(&stream_list); if (ret != 0) { @@ -646,6 +641,7 @@ static int extract_single_image(WIMStruct *w, int image, &args.progress); } + /* Make the directory structure and extract empty files */ args.extract_flags |= WIMLIB_EXTRACT_FLAG_NO_STREAMS; args.apply_dentry = ops->apply_dentry; ret = for_dentry_in_tree(wim_root_dentry(w), maybe_apply_dentry, &args); @@ -658,6 +654,7 @@ static int extract_single_image(WIMStruct *w, int image, &args.progress); } + /* Extract non-empty files */ ret = apply_stream_list(&stream_list, &args, ops, progress_func); if (ret != 0) goto out; @@ -667,6 +664,7 @@ static int extract_single_image(WIMStruct *w, int image, &args.progress); } + /* Apply timestamps */ ret = for_dentry_in_tree_depth(wim_root_dentry(w), ops->apply_dentry_timestamps, &args); if (ret != 0) @@ -678,6 +676,7 @@ static int extract_single_image(WIMStruct *w, int image, } out: #ifdef WITH_NTFS_3G + /* Unmount the NTFS volume */ if (extract_flags & WIMLIB_EXTRACT_FLAG_NTFS) { if (ntfs_umount(args.vol, FALSE) != 0) { ERROR_WITH_ERRNO("Failed to unmount NTFS volume `%s'", args.target); @@ -690,8 +689,8 @@ out: } -/* Extracts all images from the WIM to @output_dir, with the images placed in - * subdirectories named by their image names. */ +/* Extracts all images from the WIM to the directory @target, with the images + * placed in subdirectories named by their image names. */ static int extract_all_images(WIMStruct *w, const char *target, int extract_flags, wimlib_progress_func_t progress_func) @@ -725,15 +724,17 @@ static int extract_all_images(WIMStruct *w, const char *target, return 0; } -/* Extracts a single image or all images from a WIM file. */ -WIMLIBAPI int wimlib_extract_image(WIMStruct *w, int image, +/* Extracts a single image or all images from a WIM file to a directory or NTFS + * volume. */ +WIMLIBAPI int wimlib_extract_image(WIMStruct *w, + int image, const char *target, int extract_flags, WIMStruct **additional_swms, unsigned num_additional_swms, wimlib_progress_func_t progress_func) { - struct lookup_table *joined_tab, *w_tab_save; + struct wim_lookup_table *joined_tab, *w_tab_save; int ret; if (!target) diff --git a/src/hardlink.c b/src/hardlink.c index 93030d8f..ed605d67 100644 --- a/src/hardlink.c +++ b/src/hardlink.c @@ -1,9 +1,7 @@ /* * hardlink.c * - * Code to deal with hard links in WIMs. Essentially, the WIM dentries are put - * into a hash table indexed by the inode ID field, then for each hard - * inode, a linked list is made to connect the dentries. + * Code to deal with hard links in WIMs. */ /* @@ -35,25 +33,25 @@ * dentry | | * / \ ----------- ----------- * | dentry<---| struct | | struct |---> dentry - * \ / | inode | | inode | + * \ / | wim_inode| | wim_inode| * dentry ------------ ------------ * ^ ^ * | | * | | dentry * ----------- ----------- / \ * dentry<---| struct | | struct |---> dentry dentry - * / | inode | | inode | \ / + * / | wim_inode| | wim_inode| \ / * dentry ------------ ------------ dentry * ^ ^ * | | * ----------------- - * inode_table->array | idx 0 | idx 1 | + * wim_inode_table->array | idx 0 | idx 1 | * ----------------- */ /* Hash table to find inodes, identified by their inode ID. * */ -struct inode_table { +struct wim_inode_table { /* Fields for the hash table */ struct hlist_head *array; u64 num_entries; @@ -73,12 +71,12 @@ struct inode_table { struct hlist_head extra_inodes; }; -static inline void destroy_inode_table(struct inode_table *table) +static inline void destroy_inode_table(struct wim_inode_table *table) { FREE(table->array); } -static int init_inode_table(struct inode_table *table, size_t capacity) +static int init_inode_table(struct wim_inode_table *table, size_t capacity) { table->array = CALLOC(capacity, sizeof(table->array[0])); if (!table->array) { @@ -91,69 +89,54 @@ static int init_inode_table(struct inode_table *table, size_t capacity) return 0; } -static inline size_t inode_link_count(const struct inode *inode) +static inline size_t inode_link_count(const struct wim_inode *inode) { const struct list_head *cur; size_t size = 0; - list_for_each(cur, &inode->dentry_list) + list_for_each(cur, &inode->i_dentry) size++; return size; } -/* - * Insert a dentry into the inode table based on its inode - * ID. - * - * If there is already a dentry in the table having the same inode ID, - * and the inode ID is not 0, the dentry is added to the circular - * linked list for that inode. - * - * If the inode ID is 0, this indicates a dentry that's in a hard link - * inode by itself (has a link count of 1). We can't insert it into the hash - * table itself because we don't know what inode numbers are available to - * give it (this could be kept track of but would be more difficult). Instead - * we keep a linked list of the single dentries, and assign them inode - * numbers later. - */ -static int inode_table_insert(struct dentry *dentry, void *__table) +/* Insert a dentry into the inode table based on the inode number of the + * attached inode (which came from the hard link group ID field of the on-disk + * WIM dentry) */ +static int inode_table_insert(struct wim_dentry *dentry, void *__table) { - struct inode_table *table = __table; - struct inode *d_inode = dentry->d_inode; - - if (d_inode->ino == 0) { - /* Single inode--- Add to the list of extra inodes (we can't put - * it in the table itself because all the singles have a link - * inode ID of 0) */ - hlist_add_head(&d_inode->hlist, &table->extra_inodes); - - wimlib_assert(d_inode->dentry_list.next == &dentry->inode_dentry_list); - wimlib_assert(d_inode->dentry_list.prev == &dentry->inode_dentry_list); - wimlib_assert(d_inode->link_count == 1); + struct wim_inode_table *table = __table; + struct wim_inode *d_inode = dentry->d_inode; + + if (d_inode->i_ino == 0) { + /* A dentry with a hard link group ID of 0 indicates that it's + * in a hard link group by itself. Add it to the list of extra + * inodes rather than inserting it into the hash lists. */ + hlist_add_head(&d_inode->i_hlist, &table->extra_inodes); + + wimlib_assert(d_inode->i_dentry.next == &dentry->d_alias); + wimlib_assert(d_inode->i_dentry.prev == &dentry->d_alias); + wimlib_assert(d_inode->i_nlink == 1); } else { - /* Inode that may have multiple corresponding dentries (the code - * will work even if the inode actually contains only 1 dentry - * though) */ - size_t pos; - struct inode *inode; + struct wim_inode *inode; struct hlist_node *cur; - /* Try adding to existing inode */ - pos = d_inode->ino % table->capacity; - hlist_for_each_entry(inode, cur, &table->array[pos], hlist) { - if (inode->ino == d_inode->ino) { + /* Try adding this dentry to an existing inode */ + pos = d_inode->i_ino % table->capacity; + hlist_for_each_entry(inode, cur, &table->array[pos], i_hlist) { + if (inode->i_ino == d_inode->i_ino) { inode_add_dentry(dentry, inode); - inode->link_count++; + inode->i_nlink++; return 0; } } - /* Add new inode to the table */ - hlist_add_head(&d_inode->hlist, &table->array[pos]); + /* No inode in the table has the same number as this one, so add + * it to the table. */ + hlist_add_head(&d_inode->i_hlist, &table->array[pos]); - wimlib_assert(d_inode->dentry_list.next == &dentry->inode_dentry_list); - wimlib_assert(d_inode->dentry_list.prev == &dentry->inode_dentry_list); - wimlib_assert(d_inode->link_count == 1); + wimlib_assert(d_inode->i_dentry.next == &dentry->d_alias); + wimlib_assert(d_inode->i_dentry.prev == &dentry->d_alias); + wimlib_assert(d_inode->i_nlink == 1); /* XXX Make the table grow when too many entries have been * inserted. */ @@ -162,30 +145,14 @@ static int inode_table_insert(struct dentry *dentry, void *__table) return 0; } -/* Assign the inode numbers to dentries in a inode table, and return the - * next available inode ID. */ -u64 assign_inode_numbers(struct hlist_head *inode_list) -{ - DEBUG("Assigning inode numbers"); - struct inode *inode; - struct hlist_node *cur; - u64 cur_ino = 1; - hlist_for_each_entry(inode, cur, inode_list, hlist) { - inode->ino = cur_ino; - cur_ino++; - } - return cur_ino; -} - - -static void print_inode_dentries(const struct inode *inode) +static void print_inode_dentries(const struct wim_inode *inode) { - struct dentry *dentry; + struct wim_dentry *dentry; inode_for_each_dentry(dentry, inode) printf("`%s'\n", dentry->full_path_utf8); } -static void inconsistent_inode(const struct inode *inode) +static void inconsistent_inode(const struct wim_inode *inode) { ERROR("An inconsistent hard link group that cannot be corrected has " "been detected"); @@ -195,81 +162,81 @@ static void inconsistent_inode(const struct inode *inode) #endif } -static bool ref_inodes_consistent(const struct inode * restrict ref_inode_1, - const struct inode * restrict ref_inode_2) +static bool ref_inodes_consistent(const struct wim_inode * restrict ref_inode_1, + const struct wim_inode * restrict ref_inode_2) { wimlib_assert(ref_inode_1 != ref_inode_2); - if (ref_inode_1->num_ads != ref_inode_2->num_ads) + if (ref_inode_1->i_num_ads != ref_inode_2->i_num_ads) return false; - if (ref_inode_1->security_id != ref_inode_2->security_id - || ref_inode_1->attributes != ref_inode_2->attributes) + if (ref_inode_1->i_security_id != ref_inode_2->i_security_id + || ref_inode_1->i_attributes != ref_inode_2->i_attributes) return false; - for (unsigned i = 0; i <= ref_inode_1->num_ads; i++) { + for (unsigned i = 0; i <= ref_inode_1->i_num_ads; i++) { const u8 *ref_1_hash, *ref_2_hash; ref_1_hash = inode_stream_hash(ref_inode_1, i); ref_2_hash = inode_stream_hash(ref_inode_2, i); if (!hashes_equal(ref_1_hash, ref_2_hash)) return false; - if (i && !ads_entries_have_same_name(&ref_inode_1->ads_entries[i - 1], - &ref_inode_2->ads_entries[i - 1])) + if (i && !ads_entries_have_same_name(&ref_inode_1->i_ads_entries[i - 1], + &ref_inode_2->i_ads_entries[i - 1])) return false; } return true; } -static bool inodes_consistent(const struct inode * restrict ref_inode, - const struct inode * restrict inode) +static bool inodes_consistent(const struct wim_inode * restrict ref_inode, + const struct wim_inode * restrict inode) { wimlib_assert(ref_inode != inode); - if (ref_inode->num_ads != inode->num_ads && - inode->num_ads != 0) + if (ref_inode->i_num_ads != inode->i_num_ads && + inode->i_num_ads != 0) return false; - if (ref_inode->security_id != inode->security_id - || ref_inode->attributes != inode->attributes) + if (ref_inode->i_security_id != inode->i_security_id + || ref_inode->i_attributes != inode->i_attributes) return false; - for (unsigned i = 0; i <= min(ref_inode->num_ads, inode->num_ads); i++) { + for (unsigned i = 0; i <= min(ref_inode->i_num_ads, inode->i_num_ads); i++) { const u8 *ref_hash, *hash; ref_hash = inode_stream_hash(ref_inode, i); hash = inode_stream_hash(inode, i); if (!hashes_equal(ref_hash, hash) && !is_zero_hash(hash)) return false; - if (i && !ads_entries_have_same_name(&ref_inode->ads_entries[i - 1], - &inode->ads_entries[i - 1])) + if (i && !ads_entries_have_same_name(&ref_inode->i_ads_entries[i - 1], + &inode->i_ads_entries[i - 1])) return false; } return true; } /* Fix up a "true" inode and check for inconsistencies */ -static int fix_true_inode(struct inode *inode, struct hlist_head *inode_list) +static int fix_true_inode(struct wim_inode *inode, struct hlist_head *inode_list) { - struct dentry *dentry; - struct dentry *ref_dentry = NULL; - struct inode *ref_inode; + struct wim_dentry *dentry; + struct wim_dentry *ref_dentry = NULL; + struct wim_inode *ref_inode; u64 last_ctime = 0; u64 last_mtime = 0; u64 last_atime = 0; inode_for_each_dentry(dentry, inode) { - if (!ref_dentry || dentry->d_inode->num_ads > ref_dentry->d_inode->num_ads) + if (!ref_dentry || dentry->d_inode->i_num_ads > ref_dentry->d_inode->i_num_ads) ref_dentry = dentry; - if (dentry->d_inode->creation_time > last_ctime) - last_ctime = dentry->d_inode->creation_time; - if (dentry->d_inode->last_write_time > last_mtime) - last_mtime = dentry->d_inode->last_write_time; - if (dentry->d_inode->last_access_time > last_atime) - last_atime = dentry->d_inode->last_access_time; + if (dentry->d_inode->i_creation_time > last_ctime) + last_ctime = dentry->d_inode->i_creation_time; + if (dentry->d_inode->i_last_write_time > last_mtime) + last_mtime = dentry->d_inode->i_last_write_time; + if (dentry->d_inode->i_last_access_time > last_atime) + last_atime = dentry->d_inode->i_last_access_time; } ref_inode = ref_dentry->d_inode; - ref_inode->link_count = 1; - hlist_add_head(&ref_inode->hlist, inode_list); + ref_inode->i_nlink = 1; + hlist_add_head(&ref_inode->i_hlist, inode_list); - list_del(&inode->dentry_list); - list_add(&ref_inode->dentry_list, &ref_dentry->inode_dentry_list); + list_del(&inode->i_dentry); + list_add(&ref_inode->i_dentry, &ref_dentry->d_alias); inode_for_each_dentry(dentry, ref_inode) { if (dentry != ref_dentry) { @@ -277,44 +244,44 @@ static int fix_true_inode(struct inode *inode, struct hlist_head *inode_list) inconsistent_inode(ref_inode); return WIMLIB_ERR_INVALID_DENTRY; } - /* Free the unneeded `struct inode'. */ - dentry->d_inode->hlist.next = NULL; - dentry->d_inode->hlist.pprev = NULL; + /* Free the unneeded `struct wim_inode'. */ + dentry->d_inode->i_hlist.next = NULL; + dentry->d_inode->i_hlist.pprev = NULL; free_inode(dentry->d_inode); dentry->d_inode = ref_inode; - ref_inode->link_count++; + ref_inode->i_nlink++; } } - ref_inode->creation_time = last_ctime; - ref_inode->last_write_time = last_mtime; - ref_inode->last_access_time = last_atime; - wimlib_assert(inode_link_count(ref_inode) == ref_inode->link_count); + ref_inode->i_creation_time = last_ctime; + ref_inode->i_last_write_time = last_mtime; + ref_inode->i_last_access_time = last_atime; + wimlib_assert(inode_link_count(ref_inode) == ref_inode->i_nlink); return 0; } /* * Fixes up a nominal inode. * - * By a nominal inode we mean a group of two or more dentries that share - * the same hard link group ID. + * By a nominal inode we mean a group of two or more dentries that share the + * same hard link group ID. * * If dentries in the inode are found to be inconsistent, we may split the inode * into several "true" inodes. * * After splitting up each nominal inode into the "true" inodes we will * canonicalize the link group by getting rid of all the unnecessary `struct - * inodes'. There will be just one `struct inode' for each hard link group - * remaining. + * wim_inode's. There will be just one `struct wim_inode' for each hard link + * group remaining. */ -static int fix_nominal_inode(struct inode *inode, +static int fix_nominal_inode(struct wim_inode *inode, struct hlist_head *inode_list) { - struct dentry *dentry; + struct wim_dentry *dentry; struct hlist_node *cur, *tmp; int ret; size_t num_true_inodes; - wimlib_assert(inode->link_count == inode_link_count(inode)); + wimlib_assert(inode->i_nlink == inode_link_count(inode)); LIST_HEAD(dentries_with_data_streams); LIST_HEAD(dentries_with_no_data_streams); @@ -324,7 +291,7 @@ static int fix_nominal_inode(struct inode *inode, * least one data stream with a non-zero hash, and another list that * contains the dentries that have a zero hash for all data streams. */ inode_for_each_dentry(dentry, inode) { - for (unsigned i = 0; i <= dentry->d_inode->num_ads; i++) { + for (unsigned i = 0; i <= dentry->d_inode->i_num_ads; i++) { const u8 *hash; hash = inode_stream_hash(dentry->d_inode, i); if (!is_zero_hash(hash)) { @@ -343,9 +310,9 @@ static int fix_nominal_inode(struct inode *inode, * inode to be a true inode */ if (list_empty(&dentries_with_data_streams)) { #ifdef ENABLE_DEBUG - if (inode->link_count > 1) { + if (inode->i_nlink > 1) { DEBUG("Found link group of size %u without " - "any data streams:", inode->link_count); + "any data streams:", inode->i_nlink); print_inode_dentries(inode); DEBUG("We are going to interpret it as true " "link group, provided that the dentries " @@ -364,16 +331,16 @@ static int fix_nominal_inode(struct inode *inode, * add this dentry to it. Or, if none of the true inodes are * consistent with this dentry, add a new one (if that happens, * we have split the hard link group). */ - hlist_for_each_entry(inode, cur, &true_inodes, hlist) { + hlist_for_each_entry(inode, cur, &true_inodes, i_hlist) { if (ref_inodes_consistent(inode, dentry->d_inode)) { inode_add_dentry(dentry, inode); goto next_dentry_2; } } num_true_inodes++; - INIT_LIST_HEAD(&dentry->d_inode->dentry_list); + INIT_LIST_HEAD(&dentry->d_inode->i_dentry); inode_add_dentry(dentry, dentry->d_inode); - hlist_add_head(&dentry->d_inode->hlist, &true_inodes); + hlist_add_head(&dentry->d_inode->i_hlist, &true_inodes); next_dentry_2: ; } @@ -387,13 +354,13 @@ next_dentry_2: if (num_true_inodes != 1) { ERROR("Hard inode ambiguity detected!"); ERROR("We split up inode 0x%"PRIx64" due to " - "inconsistencies,", inode->ino); + "inconsistencies,", inode->i_ino); ERROR("but dentries with no stream information remained. " "We don't know which inode"); ERROR("to assign them to."); return WIMLIB_ERR_INVALID_DENTRY; } - inode = container_of(true_inodes.first, struct inode, hlist); + inode = container_of(true_inodes.first, struct wim_inode, i_hlist); /* Assign the streamless dentries to the one and only true * inode. */ list_for_each_entry(dentry, &dentries_with_no_data_streams, tmp_list) @@ -401,14 +368,14 @@ next_dentry_2: } #ifdef ENABLE_DEBUG if (num_true_inodes != 1) { - inode = container_of(true_inodes.first, struct inode, hlist); + inode = container_of(true_inodes.first, struct wim_inode, i_hlist); printf("Split nominal inode 0x%"PRIx64" into %zu " "inodes:\n", - inode->ino, num_true_inodes); + inode->i_ino, num_true_inodes); puts("------------------------------------------------------------------------------"); size_t i = 1; - hlist_for_each_entry(inode, cur, &true_inodes, hlist) { + hlist_for_each_entry(inode, cur, &true_inodes, i_hlist) { printf("[Split inode %zu]\n", i++); print_inode_dentries(inode); putchar('\n'); @@ -417,7 +384,7 @@ next_dentry_2: } #endif - hlist_for_each_entry_safe(inode, cur, tmp, &true_inodes, hlist) { + hlist_for_each_entry_safe(inode, cur, tmp, &true_inodes, i_hlist) { ret = fix_true_inode(inode, inode_list); if (ret != 0) return ret; @@ -425,29 +392,15 @@ next_dentry_2: return 0; } -/* - * Goes through each hard link group (dentries sharing the same hard link group - * ID field) that's been inserted into the inode table and shares the `struct - * inode's among members of each hard link group. - * - * In the process, the dentries belonging to each inode are checked for - * consistency. If they contain data features that indicate they cannot really - * correspond to the same inode, this should be an error, but in reality this - * case needs to be handled, so we split the dentries into different inodes. - * - * After this function returns, the inodes are no longer in the inode table, and - * the inode table should be destroyed. A list of the inodes, including all - * split inodes as well as the inodes that were good before, is returned in the - * list @inode_list. - */ -static int fix_inodes(struct inode_table *table, struct hlist_head *inode_list) +static int fix_inodes(struct wim_inode_table *table, + struct hlist_head *inode_list) { - struct inode *inode; + struct wim_inode *inode; struct hlist_node *cur, *tmp; int ret; INIT_HLIST_HEAD(inode_list); for (u64 i = 0; i < table->capacity; i++) { - hlist_for_each_entry_safe(inode, cur, tmp, &table->array[i], hlist) { + hlist_for_each_entry_safe(inode, cur, tmp, &table->array[i], i_hlist) { ret = fix_nominal_inode(inode, inode_list); if (ret != 0) return ret; @@ -458,9 +411,37 @@ static int fix_inodes(struct inode_table *table, struct hlist_head *inode_list) return 0; } -int dentry_tree_fix_inodes(struct dentry *root, struct hlist_head *inode_list) +/* + * dentry_tree_fix_inodes(): + * + * This function takes as input a tree of WIM dentries that has a different + * inode associated with every dentry. Sets of dentries that share the same + * inode (a.k.a. hard link groups) are built using the i_ino field of each + * inode, then the link count and alias list for one inode in each set is set + * correctly and the unnecessary struct wim_inode's freed. The effect is to + * correctly associate exactly one struct wim_inode with each original inode, + * regardless of how many dentries are aliases for that inode. + * + * The special inode number of 0 indicates that the dentry is in a hard link + * group by itself, and therefore has a 'struct wim_inode' with i_nlink=1 to + * itself. + * + * This function also checks the dentries in each hard link group for + * consistency. In some WIMs, such as install.wim for some versions of Windows + * 7, dentries can share the same hard link group ID but not actually be hard + * linked to each other (e.g. to having different data streams). This should be + * an error, but this case needs be handled. So, each "nominal" inode (the + * inode based on the inode numbers provided in the WIM) is examined for + * consistency and may be split into multiple "true" inodes that are maximally + * sized consistent sets of dentries. + * + * Return 0 on success; WIMLIB_ERR_NOMEM or WIMLIB_ERR_INVALID_DENTRY on + * failure. On success, the list of "true" inodes, linked by the i_hlist field, + * is returned in the hlist @inode_list. + */ +int dentry_tree_fix_inodes(struct wim_dentry *root, struct hlist_head *inode_list) { - struct inode_table inode_tab; + struct wim_inode_table inode_tab; int ret; DEBUG("Inserting dentries into inode table"); @@ -475,3 +456,18 @@ int dentry_tree_fix_inodes(struct dentry *root, struct hlist_head *inode_list) destroy_inode_table(&inode_tab); return ret; } + +/* Assign inode numbers to a list of inode, and return the next available + * number. */ +u64 assign_inode_numbers(struct hlist_head *inode_list) +{ + DEBUG("Assigning inode numbers"); + struct wim_inode *inode; + struct hlist_node *cur; + u64 cur_ino = 1; + hlist_for_each_entry(inode, cur, inode_list, i_hlist) { + inode->i_ino = cur_ino; + cur_ino++; + } + return cur_ino; +} diff --git a/src/integrity.c b/src/integrity.c index 837a1d8d..f427c3af 100644 --- a/src/integrity.c +++ b/src/integrity.c @@ -3,7 +3,7 @@ * * WIM files can optionally contain a table of SHA1 message digests at the end, * one digest for each chunk of the file of some specified size (often 10 MB). - * This file implements the checking and writing this table. + * This file implements the checking and writing of this table. */ /* @@ -86,7 +86,7 @@ static int calculate_chunk_sha1(FILE *fp, size_t this_chunk_size, /* - * Reads the integrity table from a WIM file. + * read_integrity_table: - Reads the integrity table from a WIM file. * * @res_entry: * The resource entry that specifies the location of the integrity table. @@ -199,6 +199,8 @@ out: } /* + * calculate_integrity_table(): + * * Calculates an integrity table for the data in a file beginning at offset 208 * (WIM_HEADER_DISK_SIZE). * @@ -210,7 +212,7 @@ out: * Offset of byte after the last byte to be checked. * * @old_table: - * If non-NULL, a pointer to the table containing previously contained + * If non-NULL, a pointer to the table containing the previously calculated * integrity data for a prefix of this file. * * @old_check_end: @@ -317,6 +319,8 @@ static int calculate_integrity_table(FILE *fp, } /* + * write_integrity_table(): + * * Writes a WIM integrity table (a list of SHA1 message digests of raw 10 MiB * chunks of the file). * @@ -426,6 +430,8 @@ out_free_old_table: } /* + * verify_integrity(): + * * Checks a WIM for consistency with the integrity table. * * @fp: @@ -496,6 +502,8 @@ static int verify_integrity(FILE *fp, const char *filename, /* + * check_wim_integrity(): + * * Verifies the integrity of the WIM by making sure the SHA1 message digests of * ~10 MiB chunks of the WIM match up with the values given in the integrity * table. diff --git a/src/join.c b/src/join.c index 054e347d..f6b8d2ca 100644 --- a/src/join.c +++ b/src/join.c @@ -28,22 +28,22 @@ #include "xml.h" #include -static int move_lte_to_table(struct lookup_table_entry *lte, +static int move_lte_to_table(struct wim_lookup_table_entry *lte, void *other_tab) { hlist_del(<e->hash_list); - lookup_table_insert((struct lookup_table*)other_tab, lte); + lookup_table_insert((struct wim_lookup_table*)other_tab, lte); return 0; } -static int lookup_table_join(struct lookup_table *table, - struct lookup_table *new) +static int lookup_table_join(struct wim_lookup_table *table, + struct wim_lookup_table *new) { return for_lookup_table_entry(new, move_lte_to_table, table); } /* - * Joins lookup tables from the parts of a split WIM. + * new_joined_lookup_table: - Join lookup tables from the parts of a split WIM. * * @w specifies the first part, while @additional_swms and @num_additional_swms * specify an array of pointers to the WIMStruct's for additional split WIM parts. @@ -53,18 +53,15 @@ static int lookup_table_join(struct lookup_table *table, * On success, 0 is returned on a pointer to the joined lookup table is returned * in @table_ret. * - * The reason we join the lookup tables is so: - * - We only have to search one lookup table to find the location of a - * resource in the entire split WIM. - * - Each lookup table entry will have a pointer to its split WIM part (and - * a part number field, although we don't really use it). + * The reason we join the lookup tables is so we only have to search one lookup + * table to find the location of a resource in the entire WIM. */ int new_joined_lookup_table(WIMStruct *w, WIMStruct **additional_swms, unsigned num_additional_swms, - struct lookup_table **table_ret) + struct wim_lookup_table **table_ret) { - struct lookup_table *table; + struct wim_lookup_table *table; int ret; unsigned i; diff --git a/src/list.h b/src/list.h index ce2dad2c..82f08e5f 100644 --- a/src/list.h +++ b/src/list.h @@ -195,16 +195,6 @@ static inline void hlist_del(struct hlist_node *n) next->pprev = pprev; } -static inline void hlist_safe_del(struct hlist_node *n) -{ - struct hlist_node *next = n->next; - struct hlist_node **pprev = n->pprev; - if (pprev) - *pprev = next; - if (next) - next->pprev = pprev; -} - static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h) { struct hlist_node *first = h->first; diff --git a/src/lookup_table.c b/src/lookup_table.c index f6d4244a..43f9ca09 100644 --- a/src/lookup_table.c +++ b/src/lookup_table.c @@ -33,12 +33,12 @@ #include #endif -struct lookup_table *new_lookup_table(size_t capacity) +struct wim_lookup_table *new_lookup_table(size_t capacity) { - struct lookup_table *table; + struct wim_lookup_table *table; struct hlist_head *array; - table = MALLOC(sizeof(struct lookup_table)); + table = MALLOC(sizeof(struct wim_lookup_table)); if (table) { array = CALLOC(capacity, sizeof(array[0])); if (array) { @@ -55,26 +55,27 @@ struct lookup_table *new_lookup_table(size_t capacity) return table; } -struct lookup_table_entry *new_lookup_table_entry() +struct wim_lookup_table_entry * +new_lookup_table_entry() { - struct lookup_table_entry *lte; + struct wim_lookup_table_entry *lte; - lte = CALLOC(1, sizeof(struct lookup_table_entry)); + lte = CALLOC(1, sizeof(struct wim_lookup_table_entry)); if (lte) { lte->part_number = 1; lte->refcnt = 1; } else { ERROR("Out of memory (tried to allocate %zu bytes for " "lookup table entry)", - sizeof(struct lookup_table_entry)); + sizeof(struct wim_lookup_table_entry)); } return lte; } -struct lookup_table_entry * -clone_lookup_table_entry(const struct lookup_table_entry *old) +struct wim_lookup_table_entry * +clone_lookup_table_entry(const struct wim_lookup_table_entry *old) { - struct lookup_table_entry *new; + struct wim_lookup_table_entry *new; new = MALLOC(sizeof(*new)); if (!new) @@ -85,8 +86,8 @@ clone_lookup_table_entry(const struct lookup_table_entry *old) switch (new->resource_location) { case RESOURCE_IN_STAGING_FILE: case RESOURCE_IN_FILE_ON_DISK: - wimlib_assert((void*)&old->file_on_disk == - (void*)&old->staging_file_name); + BUILD_BUG_ON((void*)&old->file_on_disk != + (void*)&old->staging_file_name); new->staging_file_name = STRDUP(old->staging_file_name); if (!new->staging_file_name) goto out_free; @@ -130,17 +131,17 @@ out_free: return NULL; } -void free_lookup_table_entry(struct lookup_table_entry *lte) +void free_lookup_table_entry(struct wim_lookup_table_entry *lte) { if (lte) { switch (lte->resource_location) { case RESOURCE_IN_STAGING_FILE: case RESOURCE_IN_ATTACHED_BUFFER: case RESOURCE_IN_FILE_ON_DISK: - wimlib_assert(((void*)<e->file_on_disk == - (void*)<e->staging_file_name) - && ((void*)<e->file_on_disk == - (void*)<e->attached_buffer)); + BUILD_BUG_ON((void*)<e->file_on_disk != + (void*)<e->staging_file_name); + BUILD_BUG_ON((void*)<e->file_on_disk != + (void*)<e->attached_buffer); FREE(lte->file_on_disk); break; #ifdef WITH_NTFS_3G @@ -159,7 +160,7 @@ void free_lookup_table_entry(struct lookup_table_entry *lte) } } -static int do_free_lookup_table_entry(struct lookup_table_entry *entry, +static int do_free_lookup_table_entry(struct wim_lookup_table_entry *entry, void *ignore) { free_lookup_table_entry(entry); @@ -167,7 +168,7 @@ static int do_free_lookup_table_entry(struct lookup_table_entry *entry, } -void free_lookup_table(struct lookup_table *table) +void free_lookup_table(struct wim_lookup_table *table) { DEBUG2("Freeing lookup table"); if (table) { @@ -187,8 +188,8 @@ void free_lookup_table(struct lookup_table *table) * @table: A pointer to the lookup table. * @entry: A pointer to the entry to insert. */ -void lookup_table_insert(struct lookup_table *table, - struct lookup_table_entry *lte) +void lookup_table_insert(struct wim_lookup_table *table, + struct wim_lookup_table_entry *lte) { size_t i = lte->hash_short % table->capacity; hlist_add_head(<e->hash_list, &table->array[i]); @@ -197,7 +198,7 @@ void lookup_table_insert(struct lookup_table *table, table->num_entries++; } -static void finalize_lte(struct lookup_table_entry *lte) +static void finalize_lte(struct wim_lookup_table_entry *lte) { #ifdef WITH_FUSE if (lte->resource_location == RESOURCE_IN_STAGING_FILE) { @@ -212,8 +213,8 @@ static void finalize_lte(struct lookup_table_entry *lte) * reference count reaches 0, it is unlinked from the lookup table. If, * furthermore, the entry has no opened file descriptors associated with it, the * entry is freed. */ -void lte_decrement_refcnt(struct lookup_table_entry *lte, - struct lookup_table *table) +void lte_decrement_refcnt(struct wim_lookup_table_entry *lte, + struct wim_lookup_table *table) { wimlib_assert(lte != NULL); wimlib_assert(lte->refcnt != 0); @@ -227,7 +228,7 @@ void lte_decrement_refcnt(struct lookup_table_entry *lte, } #ifdef WITH_FUSE -void lte_decrement_num_opened_fds(struct lookup_table_entry *lte) +void lte_decrement_num_opened_fds(struct wim_lookup_table_entry *lte) { if (lte->num_opened_fds != 0) if (--lte->num_opened_fds == 0 && lte->refcnt == 0) @@ -235,15 +236,13 @@ void lte_decrement_num_opened_fds(struct lookup_table_entry *lte) } #endif -/* - * Calls a function on all the entries in the lookup table. Stop early and - * return nonzero if any call to the function returns nonzero. - */ -int for_lookup_table_entry(struct lookup_table *table, - int (*visitor)(struct lookup_table_entry *, void *), +/* Calls a function on all the entries in the WIM lookup table. Stop early and + * return nonzero if any call to the function returns nonzero. */ +int for_lookup_table_entry(struct wim_lookup_table *table, + int (*visitor)(struct wim_lookup_table_entry *, void *), void *arg) { - struct lookup_table_entry *lte; + struct wim_lookup_table_entry *lte; struct hlist_node *pos, *tmp; int ret; @@ -268,8 +267,8 @@ int read_lookup_table(WIMStruct *w) u64 num_entries; u8 buf[WIM_LOOKUP_TABLE_ENTRY_DISK_SIZE]; int ret; - struct lookup_table *table; - struct lookup_table_entry *cur_entry = NULL, *duplicate_entry; + struct wim_lookup_table *table; + struct wim_lookup_table_entry *cur_entry = NULL, *duplicate_entry; if (resource_is_compressed(&w->hdr.lookup_table_res_entry)) { ERROR("Didn't expect a compressed lookup table!"); @@ -391,7 +390,7 @@ out: /* * Writes a lookup table entry to the output file. */ -int write_lookup_table_entry(struct lookup_table_entry *lte, void *__out) +int write_lookup_table_entry(struct wim_lookup_table_entry *lte, void *__out) { FILE *out; u8 buf[WIM_LOOKUP_TABLE_ENTRY_DISK_SIZE]; @@ -420,7 +419,7 @@ int write_lookup_table_entry(struct lookup_table_entry *lte, void *__out) } /* Writes the lookup table to the output file. */ -int write_lookup_table(struct lookup_table *table, FILE *out, +int write_lookup_table(struct wim_lookup_table *table, FILE *out, struct resource_entry *out_res_entry) { off_t start_offset, end_offset; @@ -447,19 +446,19 @@ int write_lookup_table(struct lookup_table *table, FILE *out, } -int lte_zero_real_refcnt(struct lookup_table_entry *lte, void *ignore) +int lte_zero_real_refcnt(struct wim_lookup_table_entry *lte, void *ignore) { lte->real_refcnt = 0; return 0; } -int lte_zero_out_refcnt(struct lookup_table_entry *lte, void *ignore) +int lte_zero_out_refcnt(struct wim_lookup_table_entry *lte, void *ignore) { lte->out_refcnt = 0; return 0; } -int lte_free_extracted_file(struct lookup_table_entry *lte, void *ignore) +int lte_free_extracted_file(struct wim_lookup_table_entry *lte, void *ignore) { if (lte->extracted_file != NULL) { FREE(lte->extracted_file); @@ -468,7 +467,7 @@ int lte_free_extracted_file(struct lookup_table_entry *lte, void *ignore) return 0; } -void print_lookup_table_entry(const struct lookup_table_entry *lte) +void print_lookup_table_entry(const struct wim_lookup_table_entry *lte) { if (!lte) { putchar('\n'); @@ -515,7 +514,7 @@ void print_lookup_table_entry(const struct lookup_table_entry *lte) putchar('\n'); } -static int do_print_lookup_table_entry(struct lookup_table_entry *lte, +static int do_print_lookup_table_entry(struct wim_lookup_table_entry *lte, void *ignore) { print_lookup_table_entry(lte); @@ -532,14 +531,13 @@ WIMLIBAPI void wimlib_print_lookup_table(WIMStruct *w) NULL); } -/* - * Looks up an entry in the lookup table. - */ -struct lookup_table_entry * -__lookup_resource(const struct lookup_table *table, const u8 hash[]) +/* Given a SHA1 message digest, return the corresponding entry in the WIM's + * lookup table, or NULL if there is none. */ +struct wim_lookup_table_entry * +__lookup_resource(const struct wim_lookup_table *table, const u8 hash[]) { size_t i; - struct lookup_table_entry *lte; + struct wim_lookup_table_entry *lte; struct hlist_node *pos; wimlib_assert(table != NULL); @@ -561,15 +559,15 @@ __lookup_resource(const struct lookup_table *table, const u8 hash[]) */ int lookup_resource(WIMStruct *w, const char *path, int lookup_flags, - struct dentry **dentry_ret, - struct lookup_table_entry **lte_ret, + struct wim_dentry **dentry_ret, + struct wim_lookup_table_entry **lte_ret, u16 *stream_idx_ret) { - struct dentry *dentry; - struct lookup_table_entry *lte; + struct wim_dentry *dentry; + struct wim_lookup_table_entry *lte; u16 stream_idx; const char *stream_name = NULL; - struct inode *inode; + struct wim_inode *inode; char *p = NULL; if (lookup_flags & LOOKUP_FLAG_ADS_OK) { @@ -588,7 +586,7 @@ int lookup_resource(WIMStruct *w, const char *path, inode = dentry->d_inode; - wimlib_assert(inode->resolved); + wimlib_assert(inode->i_resolved); if (!(lookup_flags & LOOKUP_FLAG_DIRECTORY_OK) && inode_is_directory(inode)) @@ -607,7 +605,7 @@ int lookup_resource(WIMStruct *w, const char *path, return -ENOENT; } } else { - lte = inode->lte; + lte = inode->i_lte; stream_idx = 0; } out: @@ -630,41 +628,41 @@ out: * This function always succeeds; unresolved lookup table entries are given a * NULL pointer. */ -void inode_resolve_ltes(struct inode *inode, struct lookup_table *table) +void inode_resolve_ltes(struct wim_inode *inode, struct wim_lookup_table *table) { - if (!inode->resolved) { - struct lookup_table_entry *lte; + if (!inode->i_resolved) { + struct wim_lookup_table_entry *lte; /* Resolve the default file stream */ - lte = __lookup_resource(table, inode->hash); - inode->lte = lte; - inode->resolved = 1; + lte = __lookup_resource(table, inode->i_hash); + inode->i_lte = lte; + inode->i_resolved = 1; /* Resolve the alternate data streams */ - for (u16 i = 0; i < inode->num_ads; i++) { - struct ads_entry *cur_entry = &inode->ads_entries[i]; + for (u16 i = 0; i < inode->i_num_ads; i++) { + struct ads_entry *cur_entry = &inode->i_ads_entries[i]; lte = __lookup_resource(table, cur_entry->hash); cur_entry->lte = lte; } } } -void inode_unresolve_ltes(struct inode *inode) +void inode_unresolve_ltes(struct wim_inode *inode) { - if (inode->resolved) { - if (inode->lte) - copy_hash(inode->hash, inode->lte->hash); + if (inode->i_resolved) { + if (inode->i_lte) + copy_hash(inode->i_hash, inode->i_lte->hash); else - zero_out_hash(inode->hash); + zero_out_hash(inode->i_hash); - for (u16 i = 0; i < inode->num_ads; i++) { - if (inode->ads_entries[i].lte) - copy_hash(inode->ads_entries[i].hash, - inode->ads_entries[i].lte->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->ads_entries[i].hash); + zero_out_hash(inode->i_ads_entries[i].hash); } - inode->resolved = 0; + inode->i_resolved = 0; } } @@ -675,11 +673,11 @@ void inode_unresolve_ltes(struct inode *inode) * * This works for both resolved and un-resolved dentries. */ -struct lookup_table_entry * -inode_stream_lte(const struct inode *inode, unsigned stream_idx, - const struct lookup_table *table) +struct wim_lookup_table_entry * +inode_stream_lte(const struct wim_inode *inode, unsigned stream_idx, + const struct wim_lookup_table *table) { - if (inode->resolved) + if (inode->i_resolved) return inode_stream_lte_resolved(inode, stream_idx); else return inode_stream_lte_unresolved(inode, stream_idx, table); @@ -702,24 +700,24 @@ inode_stream_lte(const struct inode *inode, unsigned stream_idx, * entries.). This is despite the fact that we may need to extract such a * missing entry as an empty file or empty named data stream. */ -struct lookup_table_entry * -inode_unnamed_lte(const struct inode *inode, - const struct lookup_table *table) +struct wim_lookup_table_entry * +inode_unnamed_lte(const struct wim_inode *inode, + const struct wim_lookup_table *table) { - if (inode->resolved) + if (inode->i_resolved) return inode_unnamed_lte_resolved(inode); else return inode_unnamed_lte_unresolved(inode, table); } -static int lte_add_stream_size(struct lookup_table_entry *lte, +static int lte_add_stream_size(struct wim_lookup_table_entry *lte, void *total_bytes_p) { *(u64*)total_bytes_p += lte->resource_entry.size; return 0; } -u64 lookup_table_total_stream_size(struct lookup_table *table) +u64 lookup_table_total_stream_size(struct wim_lookup_table *table) { u64 total_size = 0; for_lookup_table_entry(table, lte_add_stream_size, &total_size); diff --git a/src/lookup_table.h b/src/lookup_table.h index abd0ccbf..242e2c1b 100644 --- a/src/lookup_table.h +++ b/src/lookup_table.h @@ -18,7 +18,7 @@ /* A lookup table that is used to translate the hash codes of dentries into the * offsets and sizes of uncompressed or compressed file resources. It is * implemented as a hash table. */ -struct lookup_table { +struct wim_lookup_table { struct hlist_head *array; u64 num_entries; u64 capacity; @@ -84,7 +84,7 @@ enum resource_location { * The lookup_table_entry for a given dentry or alternate stream entry in the * WIM is found using the SHA1 message digest field. */ -struct lookup_table_entry { +struct wim_lookup_table_entry { /* List of lookup table entries in this hash bucket */ struct hlist_node hash_list; @@ -168,7 +168,7 @@ struct lookup_table_entry { /* Pointer to inode that contains the opened file descriptors to * this stream (valid iff resource_location == * RESOURCE_IN_STAGING_FILE) */ - struct inode *lte_inode; + struct wim_inode *lte_inode; }; /* When a WIM file is written, out_refcnt starts at 0 and is incremented @@ -204,19 +204,19 @@ struct lookup_table_entry { }; static inline u64 -wim_resource_size(const struct lookup_table_entry *lte) +wim_resource_size(const struct wim_lookup_table_entry *lte) { return lte->resource_entry.original_size; } static inline u64 -wim_resource_chunks(const struct lookup_table_entry *lte) +wim_resource_chunks(const struct wim_lookup_table_entry *lte) { return (wim_resource_size(lte) + WIM_CHUNK_SIZE - 1) / WIM_CHUNK_SIZE; } static inline u64 -wim_resource_compressed_size(const struct lookup_table_entry *lte) +wim_resource_compressed_size(const struct wim_lookup_table_entry *lte) { return lte->resource_entry.size; } @@ -226,7 +226,7 @@ wim_resource_compressed_size(const struct lookup_table_entry *lte) * entry */ static inline int -wim_resource_compression_type(const struct lookup_table_entry *lte) +wim_resource_compression_type(const struct wim_lookup_table_entry *lte) { if (!(lte->resource_entry.flags & WIM_RESHDR_FLAG_COMPRESSED) || lte->resource_location != RESOURCE_IN_WIM) @@ -235,79 +235,79 @@ wim_resource_compression_type(const struct lookup_table_entry *lte) } -extern struct lookup_table * +extern struct wim_lookup_table * new_lookup_table(size_t capacity); extern int read_lookup_table(WIMStruct *w); extern int -write_lookup_table(struct lookup_table *table, FILE *out, +write_lookup_table(struct wim_lookup_table *table, FILE *out, struct resource_entry *out_res_entry); extern void -free_lookup_table(struct lookup_table *table); +free_lookup_table(struct wim_lookup_table *table); extern void -lookup_table_insert(struct lookup_table *table, struct lookup_table_entry *lte); +lookup_table_insert(struct wim_lookup_table *table, struct wim_lookup_table_entry *lte); /* Unlinks a lookup table entry from the table; does not free it. */ static inline void -lookup_table_unlink(struct lookup_table *table, struct lookup_table_entry *lte) +lookup_table_unlink(struct wim_lookup_table *table, struct wim_lookup_table_entry *lte) { hlist_del(<e->hash_list); table->num_entries--; } -extern struct lookup_table_entry * +extern struct wim_lookup_table_entry * new_lookup_table_entry(); -extern struct lookup_table_entry * -clone_lookup_table_entry(const struct lookup_table_entry *lte); +extern struct wim_lookup_table_entry * +clone_lookup_table_entry(const struct wim_lookup_table_entry *lte); extern void -print_lookup_table_entry(const struct lookup_table_entry *entry); +print_lookup_table_entry(const struct wim_lookup_table_entry *entry); extern void -free_lookup_table_entry(struct lookup_table_entry *lte); +free_lookup_table_entry(struct wim_lookup_table_entry *lte); extern int -for_lookup_table_entry(struct lookup_table *table, - int (*visitor)(struct lookup_table_entry *, void *), +for_lookup_table_entry(struct wim_lookup_table *table, + int (*visitor)(struct wim_lookup_table_entry *, void *), void *arg); -extern struct lookup_table_entry * -__lookup_resource(const struct lookup_table *table, const u8 hash[]); +extern struct wim_lookup_table_entry * +__lookup_resource(const struct wim_lookup_table *table, const u8 hash[]); extern int lookup_resource(WIMStruct *w, const char *path, - int lookup_flags, struct dentry **dentry_ret, - struct lookup_table_entry **lte_ret, u16 *stream_idx_ret); + int lookup_flags, struct wim_dentry **dentry_ret, + struct wim_lookup_table_entry **lte_ret, u16 *stream_idx_ret); extern void -lte_decrement_refcnt(struct lookup_table_entry *lte, - struct lookup_table *table); +lte_decrement_refcnt(struct wim_lookup_table_entry *lte, + struct wim_lookup_table *table); #ifdef WITH_FUSE extern void -lte_decrement_num_opened_fds(struct lookup_table_entry *lte); +lte_decrement_num_opened_fds(struct wim_lookup_table_entry *lte); #endif extern int -lte_zero_out_refcnt(struct lookup_table_entry *entry, void *ignore); +lte_zero_out_refcnt(struct wim_lookup_table_entry *entry, void *ignore); extern int -lte_zero_real_refcnt(struct lookup_table_entry *entry, void *ignore); +lte_zero_real_refcnt(struct wim_lookup_table_entry *entry, void *ignore); extern int -lte_free_extracted_file(struct lookup_table_entry *lte, void *ignore); +lte_free_extracted_file(struct wim_lookup_table_entry *lte, void *ignore); extern void -inode_resolve_ltes(struct inode *inode, struct lookup_table *table); +inode_resolve_ltes(struct wim_inode *inode, struct wim_lookup_table *table); extern void -inode_unresolve_ltes(struct inode *inode); +inode_unresolve_ltes(struct wim_inode *inode); extern int -write_lookup_table_entry(struct lookup_table_entry *lte, void *__out); +write_lookup_table_entry(struct wim_lookup_table_entry *lte, void *__out); static inline struct resource_entry* wim_metadata_resource_entry(WIMStruct *w) @@ -316,53 +316,53 @@ wim_metadata_resource_entry(WIMStruct *w) w->current_image - 1].metadata_lte->resource_entry; } -static inline struct lookup_table_entry * -inode_stream_lte_resolved(const struct inode *inode, unsigned stream_idx) +static inline struct wim_lookup_table_entry * +inode_stream_lte_resolved(const struct wim_inode *inode, unsigned stream_idx) { - wimlib_assert(inode->resolved); - wimlib_assert(stream_idx <= inode->num_ads); + wimlib_assert(inode->i_resolved); + wimlib_assert(stream_idx <= inode->i_num_ads); if (stream_idx == 0) - return inode->lte; + return inode->i_lte; else - return inode->ads_entries[stream_idx - 1].lte; + return inode->i_ads_entries[stream_idx - 1].lte; } -static inline struct lookup_table_entry * -inode_stream_lte_unresolved(const struct inode *inode, unsigned stream_idx, - const struct lookup_table *table) +static inline struct wim_lookup_table_entry * +inode_stream_lte_unresolved(const struct wim_inode *inode, unsigned stream_idx, + const struct wim_lookup_table *table) { - wimlib_assert(!inode->resolved); - wimlib_assert(stream_idx <= inode->num_ads); + wimlib_assert(!inode->i_resolved); + wimlib_assert(stream_idx <= inode->i_num_ads); if (!table) return NULL; if (stream_idx == 0) - return __lookup_resource(table, inode->hash); + return __lookup_resource(table, inode->i_hash); else return __lookup_resource(table, - inode->ads_entries[ + inode->i_ads_entries[ stream_idx - 1].hash); } -extern struct lookup_table_entry * -inode_stream_lte(const struct inode *inode, unsigned stream_idx, - const struct lookup_table *table); +extern struct wim_lookup_table_entry * +inode_stream_lte(const struct wim_inode *inode, unsigned stream_idx, + const struct wim_lookup_table *table); static inline const u8 * -inode_stream_hash_unresolved(const struct inode *inode, unsigned stream_idx) +inode_stream_hash_unresolved(const struct wim_inode *inode, unsigned stream_idx) { - wimlib_assert(!inode->resolved); - wimlib_assert(stream_idx <= inode->num_ads); + wimlib_assert(!inode->i_resolved); + wimlib_assert(stream_idx <= inode->i_num_ads); if (stream_idx == 0) - return inode->hash; + return inode->i_hash; else - return inode->ads_entries[stream_idx - 1].hash; + return inode->i_ads_entries[stream_idx - 1].hash; } static inline const u8 * -inode_stream_hash_resolved(const struct inode *inode, unsigned stream_idx) +inode_stream_hash_resolved(const struct wim_inode *inode, unsigned stream_idx) { - struct lookup_table_entry *lte; + struct wim_lookup_table_entry *lte; lte = inode_stream_lte_resolved(inode, stream_idx); if (lte) return lte->hash; @@ -378,51 +378,57 @@ inode_stream_hash_resolved(const struct inode *inode, unsigned stream_idx) * This works for both resolved and un-resolved dentries. */ static inline const u8 * -inode_stream_hash(const struct inode *inode, unsigned stream_idx) +inode_stream_hash(const struct wim_inode *inode, unsigned stream_idx) { - if (inode->resolved) + if (inode->i_resolved) return inode_stream_hash_resolved(inode, stream_idx); else return inode_stream_hash_unresolved(inode, stream_idx); } static inline u16 -inode_stream_name_len(const struct inode *inode, unsigned stream_idx) +inode_stream_name_len(const struct wim_inode *inode, unsigned stream_idx) { - wimlib_assert(stream_idx <= inode->num_ads); + wimlib_assert(stream_idx <= inode->i_num_ads); if (stream_idx == 0) return 0; else - return inode->ads_entries[stream_idx - 1].stream_name_len; + return inode->i_ads_entries[stream_idx - 1].stream_name_len; } -static inline struct lookup_table_entry * -inode_unnamed_lte_resolved(const struct inode *inode) +static inline struct wim_lookup_table_entry * +inode_unnamed_lte_resolved(const struct wim_inode *inode) { - wimlib_assert(inode->resolved); - for (unsigned i = 0; i <= inode->num_ads; i++) + wimlib_assert(inode->i_resolved); + for (unsigned i = 0; i <= inode->i_num_ads; i++) { if (inode_stream_name_len(inode, i) == 0 && - !is_zero_hash(inode_stream_hash_resolved(inode, i))) + !is_zero_hash(inode_stream_hash_resolved(inode, i))) + { return inode_stream_lte_resolved(inode, i); + } + } return NULL; } -static inline struct lookup_table_entry * -inode_unnamed_lte_unresolved(const struct inode *inode, - const struct lookup_table *table) +static inline struct wim_lookup_table_entry * +inode_unnamed_lte_unresolved(const struct wim_inode *inode, + const struct wim_lookup_table *table) { - wimlib_assert(!inode->resolved); - for (unsigned i = 0; i <= inode->num_ads; i++) + wimlib_assert(!inode->i_resolved); + for (unsigned i = 0; i <= inode->i_num_ads; i++) { if (inode_stream_name_len(inode, i) == 0 && - !is_zero_hash(inode_stream_hash_unresolved(inode, i))) + !is_zero_hash(inode_stream_hash_unresolved(inode, i))) + { return inode_stream_lte_unresolved(inode, i, table); + } + } return NULL; } -extern struct lookup_table_entry * -inode_unnamed_lte(const struct inode *inode, const struct lookup_table *table); +extern struct wim_lookup_table_entry * +inode_unnamed_lte(const struct wim_inode *inode, const struct wim_lookup_table *table); extern u64 -lookup_table_total_stream_size(struct lookup_table *table); +lookup_table_total_stream_size(struct wim_lookup_table *table); #endif diff --git a/src/lzx-decompress.c b/src/lzx-decompress.c index e0f3b85a..2b3c0f90 100644 --- a/src/lzx-decompress.c +++ b/src/lzx-decompress.c @@ -873,7 +873,7 @@ int lzx_decompress(const void *compressed_data, unsigned compressed_len, LZX_DEBUG("LZX_BLOCKTYPE_UNCOMPRESSED"); if (istream.data_bytes_left < block_size) { ERROR("Unexpected end of input when " - "reading %zu bytes from LZX bitstream " + "reading %u bytes from LZX bitstream " "(only have %u bytes left)", block_size, istream.data_bytes_left); return -1; diff --git a/src/metadata_resource.c b/src/metadata_resource.c index 726deb54..db395d2e 100644 --- a/src/metadata_resource.c +++ b/src/metadata_resource.c @@ -47,8 +47,8 @@ int read_metadata_resource(WIMStruct *w, struct image_metadata *imd) u8 *buf; u32 dentry_offset; int ret; - struct dentry *dentry; - const struct lookup_table_entry *metadata_lte; + struct wim_dentry *dentry; + const struct wim_lookup_table_entry *metadata_lte; u64 metadata_len; struct hlist_head inode_list; @@ -118,10 +118,10 @@ int read_metadata_resource(WIMStruct *w, struct image_metadata *imd) DEBUG("Reading root dentry"); /* Allocate memory for the root dentry and read it into memory */ - dentry = MALLOC(sizeof(struct dentry)); + dentry = MALLOC(sizeof(struct wim_dentry)); if (!dentry) { ERROR("Failed to allocate %zu bytes for root dentry", - sizeof(struct dentry)); + sizeof(struct wim_dentry)); ret = WIMLIB_ERR_NOMEM; goto out_free_security_data; } @@ -203,7 +203,7 @@ static int write_wim_resource_from_buffer(const u8 *buf, u64 buf_size, { /* Set up a temporary lookup table entry to provide to * write_wim_resource(). */ - struct lookup_table_entry lte; + struct wim_lookup_table_entry lte; int ret; lte.resource_entry.flags = 0; lte.resource_entry.original_size = buf_size; @@ -227,8 +227,8 @@ int write_metadata_resource(WIMStruct *w) u8 *p; int ret; u64 subdir_offset; - struct dentry *root; - struct lookup_table_entry *lte; + struct wim_dentry *root; + struct wim_lookup_table_entry *lte; u64 metadata_original_size; struct wim_security_data *sd; diff --git a/src/mount_image.c b/src/mount_image.c index 090a8280..80976223 100644 --- a/src/mount_image.c +++ b/src/mount_image.c @@ -57,9 +57,9 @@ #define MSG_BREAK_LOOP -2 /* File descriptor to a file open on the WIM filesystem. */ -struct wimlib_fd { - struct inode *f_inode; - struct lookup_table_entry *f_lte; +struct wimfs_fd { + struct wim_inode *f_inode; + struct wim_lookup_table_entry *f_lte; int staging_fd; u16 idx; u32 stream_id; @@ -80,23 +80,28 @@ struct wimfs_context { /* Flags passed to wimlib_mount(). */ int mount_flags; + /* Default flags to use when looking up a WIM dentry (depends on whether + * the Windows interface to alternate data streams is being used or + * not). */ int default_lookup_flags; - /* Next inode number to be assigned. */ + /* Next inode number to be assigned. Note: I didn't bother with a + * bitmap of free inode numbers since this isn't even a "real" + * filesystem anyway. */ u64 next_ino; - /* List of lookup table entries in the staging directory */ + /* List of lookup table entries for files in the staging directory */ struct list_head staging_list; /* List of inodes in the mounted image */ struct hlist_head *image_inode_list; - /* Name and message queue descriptors for message queues between the filesystem - * daemon process and the unmount process. These are used when the filesystem - * is unmounted and the process running wimlib_mount() (i.e. the `imagex - * unmount' command) needs to communicate with the filesystem daemon running - * fuse_main() (i.e. that spawned by the `imagex mount' or `imagex mountrw' - * commands */ + /* Name and message queue descriptors for message queues between the + * filesystem daemon process and the unmount process. These are used + * when the filesystem is unmounted and the process running + * wimlib_unmount_image() (i.e. the `imagex unmount' command) needs to + * communicate with the filesystem daemon running fuse_main() (i.e. the + * daemon created by the `imagex mount' or `imagex mountrw' commands */ char *unmount_to_daemon_mq_name; char *daemon_to_unmount_mq_name; mqd_t unmount_to_daemon_mq; @@ -148,11 +153,11 @@ static inline int flags_writable(int open_flags) * * Return 0 iff successful or error code if unsuccessful. */ -static int alloc_wimlib_fd(struct inode *inode, - u32 stream_id, - struct lookup_table_entry *lte, - struct wimlib_fd **fd_ret, - bool readonly) +static int alloc_wimfs_fd(struct wim_inode *inode, + u32 stream_id, + struct wim_lookup_table_entry *lte, + struct wimfs_fd **fd_ret, + bool readonly) { static const u16 fds_per_alloc = 8; static const u16 max_fds = 0xffff; @@ -161,35 +166,35 @@ static int alloc_wimlib_fd(struct inode *inode, pthread_mutex_lock(&inode->i_mutex); DEBUG("Allocating fd for stream ID %u from inode %lx (open = %u, allocated = %u)", - stream_id, inode->ino, inode->num_opened_fds, - inode->num_allocated_fds); + stream_id, inode->i_ino, inode->i_num_opened_fds, + inode->i_num_allocated_fds); - if (inode->num_opened_fds == inode->num_allocated_fds) { - struct wimlib_fd **fds; + if (inode->i_num_opened_fds == inode->i_num_allocated_fds) { + struct wimfs_fd **fds; u16 num_new_fds; - if (inode->num_allocated_fds == max_fds) { + if (inode->i_num_allocated_fds == max_fds) { ret = -EMFILE; goto out; } num_new_fds = min(fds_per_alloc, - max_fds - inode->num_allocated_fds); + max_fds - inode->i_num_allocated_fds); - fds = REALLOC(inode->fds, - (inode->num_allocated_fds + num_new_fds) * - sizeof(inode->fds[0])); + fds = REALLOC(inode->i_fds, + (inode->i_num_allocated_fds + num_new_fds) * + sizeof(inode->i_fds[0])); if (!fds) { ret = -ENOMEM; goto out; } - memset(&fds[inode->num_allocated_fds], 0, + memset(&fds[inode->i_num_allocated_fds], 0, num_new_fds * sizeof(fds[0])); - inode->fds = fds; - inode->num_allocated_fds += num_new_fds; + inode->i_fds = fds; + inode->i_num_allocated_fds += num_new_fds; } for (u16 i = 0; ; i++) { - if (!inode->fds[i]) { - struct wimlib_fd *fd = CALLOC(1, sizeof(*fd)); + if (!inode->i_fds[i]) { + struct wimfs_fd *fd = CALLOC(1, sizeof(*fd)); if (!fd) { ret = -ENOMEM; break; @@ -200,8 +205,8 @@ static int alloc_wimlib_fd(struct inode *inode, fd->idx = i; fd->stream_id = stream_id; *fd_ret = fd; - inode->fds[i] = fd; - inode->num_opened_fds++; + inode->i_fds[i] = fd; + inode->i_num_opened_fds++; if (lte && !readonly) lte->num_opened_fds++; DEBUG("Allocated fd (idx = %u)", fd->idx); @@ -214,20 +219,20 @@ out: return ret; } -static void inode_put_fd(struct inode *inode, struct wimlib_fd *fd) +static void inode_put_fd(struct wim_inode *inode, struct wimfs_fd *fd) { wimlib_assert(inode != NULL); pthread_mutex_lock(&inode->i_mutex); wimlib_assert(fd->f_inode == inode); - wimlib_assert(inode->num_opened_fds != 0); - wimlib_assert(fd->idx < inode->num_allocated_fds); - wimlib_assert(inode->fds[fd->idx] == fd); + wimlib_assert(inode->i_num_opened_fds != 0); + wimlib_assert(fd->idx < inode->i_num_allocated_fds); + wimlib_assert(inode->i_fds[fd->idx] == fd); - inode->fds[fd->idx] = NULL; + inode->i_fds[fd->idx] = NULL; FREE(fd); - if (--inode->num_opened_fds == 0 && inode->link_count == 0) { + if (--inode->i_num_opened_fds == 0 && inode->i_nlink == 0) { pthread_mutex_unlock(&inode->i_mutex); free_inode(inode); } else { @@ -235,7 +240,7 @@ static void inode_put_fd(struct inode *inode, struct wimlib_fd *fd) } } -static int lte_put_fd(struct lookup_table_entry *lte, struct wimlib_fd *fd) +static int lte_put_fd(struct wim_lookup_table_entry *lte, struct wimfs_fd *fd) { wimlib_assert(fd->f_lte == lte); @@ -257,12 +262,12 @@ static int lte_put_fd(struct lookup_table_entry *lte, struct wimlib_fd *fd) } /* Close a file descriptor. */ -static int close_wimlib_fd(struct wimlib_fd *fd) +static int close_wimfs_fd(struct wimfs_fd *fd) { int ret; DEBUG("Closing fd (inode = %lu, opened = %u, allocated = %u)", - fd->f_inode->ino, fd->f_inode->num_opened_fds, - fd->f_inode->num_allocated_fds); + fd->f_inode->i_ino, fd->f_inode->i_num_opened_fds, + fd->f_inode->i_num_allocated_fds); ret = lte_put_fd(fd->f_lte, fd); if (ret != 0) return ret; @@ -271,16 +276,25 @@ static int close_wimlib_fd(struct wimlib_fd *fd) return 0; } +/* + * Add a new dentry with a new inode to a WIM image. + * + * @ctx: Context for the mounted WIM image. + * @path: Path to create the dentry at. + * @dentry_ret: Return the pointer to the dentry if successful. + * + * Returns 0 on success, or negative error number on failure. + */ static int create_dentry(struct wimfs_context *ctx, const char *path, - struct dentry **dentry_ret) + struct wim_dentry **dentry_ret) { - struct dentry *parent; - struct dentry *new; + struct wim_dentry *parent; + struct wim_dentry *new; const char *basename; parent = get_parent_dentry(ctx->wim, path); if (!parent) - return -ENOENT; + return -errno; if (!dentry_is_directory(parent)) return -ENOTDIR; @@ -293,15 +307,16 @@ static int create_dentry(struct wimfs_context *ctx, const char *path, if (!new) return -errno; - new->d_inode->resolved = 1; - new->d_inode->ino = ctx->next_ino++; + new->d_inode->i_resolved = 1; + new->d_inode->i_ino = ctx->next_ino++; dentry_add_child(parent, new); - hlist_add_head(&new->d_inode->hlist, ctx->image_inode_list); + hlist_add_head(&new->d_inode->i_hlist, ctx->image_inode_list); *dentry_ret = new; return 0; } -/* Remove a dentry; i.e. remove a reference to the corresponding inode. +/* Remove a dentry from a mounted WIM image; i.e. remove an alias for the + * corresponding inode. * * If there are no remaining references to the inode either through dentries or * open file descriptors, the inode is freed. Otherwise, the inode is not @@ -309,17 +324,17 @@ static int create_dentry(struct wimfs_context *ctx, const char *path, * * Either way, all lookup table entries referenced by the inode have their * reference count decremented. If a lookup table entry has no open file - * descriptors and no references remaining, it is freed, and the staging file is - * unlinked. + * descriptors and no references remaining, it is freed, and the corresponding + * staging file is unlinked. */ -static void remove_dentry(struct dentry *dentry, - struct lookup_table *lookup_table) +static void remove_dentry(struct wim_dentry *dentry, + struct wim_lookup_table *lookup_table) { - struct inode *inode = dentry->d_inode; - struct lookup_table_entry *lte; + struct wim_inode *inode = dentry->d_inode; + struct wim_lookup_table_entry *lte; unsigned i; - for (i = 0; i <= inode->num_ads; i++) { + for (i = 0; i <= inode->i_num_ads; i++) { lte = inode_stream_lte_resolved(inode, i); if (lte) lte_decrement_refcnt(lte, lookup_table); @@ -328,13 +343,14 @@ static void remove_dentry(struct dentry *dentry, put_dentry(dentry); } -/* Transfers file attributes from a struct inode to a `stat' buffer. +/* Transfers file attributes from a struct wim_inode to a `stat' buffer. * * The lookup table entry tells us which stream in the inode we are statting. * For a named data stream, everything returned is the same as the unnamed data * stream except possibly the size and block count. */ -static int inode_to_stbuf(const struct inode *inode, - struct lookup_table_entry *lte, struct stat *stbuf) +static int inode_to_stbuf(const struct wim_inode *inode, + const struct wim_lookup_table_entry *lte, + struct stat *stbuf) { if (inode_is_symlink(inode)) stbuf->st_mode = S_IFLNK | 0777; @@ -343,8 +359,8 @@ static int inode_to_stbuf(const struct inode *inode, else stbuf->st_mode = S_IFREG | 0755; - stbuf->st_ino = (ino_t)inode->ino; - stbuf->st_nlink = inode->link_count; + stbuf->st_ino = (ino_t)inode->i_ino; + stbuf->st_nlink = inode->i_nlink; stbuf->st_uid = getuid(); stbuf->st_gid = getgid(); @@ -364,9 +380,9 @@ static int inode_to_stbuf(const struct inode *inode, stbuf->st_size = 0; } - stbuf->st_atime = wim_timestamp_to_unix(inode->last_access_time); - stbuf->st_mtime = wim_timestamp_to_unix(inode->last_write_time); - stbuf->st_ctime = wim_timestamp_to_unix(inode->creation_time); + stbuf->st_atime = wim_timestamp_to_unix(inode->i_last_access_time); + stbuf->st_mtime = wim_timestamp_to_unix(inode->i_last_write_time); + stbuf->st_ctime = wim_timestamp_to_unix(inode->i_creation_time); stbuf->st_blocks = (stbuf->st_size + 511) / 512; return 0; } @@ -375,12 +391,15 @@ static int inode_to_stbuf(const struct inode *inode, * writing. * * @name_ret: A location into which the a pointer to the newly allocated name of - * the staging file is stored. - * @return: The file descriptor for the new file. Returns -1 and sets errno on - * error, for any reason possible from the creat() function. + * the staging file is stored. + * + * @ctx: Context for the WIM filesystem; this provides the name of the + * staging directory. + * + * On success, returns the file descriptor for the staging file, opened for + * writing. On failure, returns -1 and sets errno. */ -static int create_staging_file(char **name_ret, int open_flags, - struct wimfs_context *ctx) +static int create_staging_file(char **name_ret, struct wimfs_context *ctx) { size_t name_len; char *name; @@ -388,7 +407,9 @@ static int create_staging_file(char **name_ret, int open_flags, int fd; int errno_save; - name_len = ctx->staging_dir_name_len + 1 + SHA1_HASH_SIZE; + static const size_t STAGING_FILE_NAME_LEN = 20; + + name_len = ctx->staging_dir_name_len + 1 + STAGING_FILE_NAME_LEN; name = MALLOC(name_len + 1); if (!name) { errno = ENOMEM; @@ -400,7 +421,7 @@ static int create_staging_file(char **name_ret, int open_flags, memcpy(name, ctx->staging_dir_name, ctx->staging_dir_name_len); name[ctx->staging_dir_name_len] = '/'; randomize_char_array_with_alnum(name + ctx->staging_dir_name_len + 1, - SHA1_HASH_SIZE); + STAGING_FILE_NAME_LEN); name[name_len] = '\0'; @@ -408,15 +429,14 @@ static int create_staging_file(char **name_ret, int open_flags, * existing file, and try again if so */ } while (stat(name, &stbuf) == 0); - if (errno != ENOENT) - /* other error! */ + if (errno != ENOENT) /* other error?! */ return -1; /* doesn't exist--- ok */ DEBUG("Creating staging file `%s'", name); - fd = open(name, open_flags | O_CREAT | O_TRUNC, 0600); + fd = open(name, O_WRONLY | O_CREAT | O_EXCL, 0600); if (fd == -1) { errno_save = errno; FREE(name); @@ -446,20 +466,20 @@ static int create_staging_file(char **name_ret, int open_flags, * * Returns 0 on success or a negative error code on failure. */ -static int extract_resource_to_staging_dir(struct inode *inode, +static int extract_resource_to_staging_dir(struct wim_inode *inode, u32 stream_id, - struct lookup_table_entry **lte, + struct wim_lookup_table_entry **lte, off_t size, struct wimfs_context *ctx) { char *staging_file_name; int ret; int fd; - struct lookup_table_entry *old_lte, *new_lte; + struct wim_lookup_table_entry *old_lte, *new_lte; off_t extract_size; DEBUG("Extracting resource to staging dir: inode %"PRIu64", " - "stream id %"PRIu32, inode->ino, stream_id); + "stream id %"PRIu32, inode->i_ino, stream_id); old_lte = *lte; @@ -467,7 +487,7 @@ static int extract_resource_to_staging_dir(struct inode *inode, old_lte->resource_location != RESOURCE_IN_STAGING_FILE); /* Create the staging file */ - fd = create_staging_file(&staging_file_name, O_WRONLY, ctx); + fd = create_staging_file(&staging_file_name, ctx); if (fd == -1) return -errno; @@ -500,7 +520,7 @@ static int extract_resource_to_staging_dir(struct inode *inode, /* Now deal with the lookup table entries. We may be able to re-use the * existing entry, but we may have to create a new one instead. */ - if (old_lte && inode->link_count == old_lte->refcnt) { + if (old_lte && inode->i_nlink == old_lte->refcnt) { /* The reference count of the existing lookup table entry is the * same as the link count of the inode that contains the stream * we're opening. Therefore, ALL the references to the lookup @@ -516,10 +536,10 @@ static int extract_resource_to_staging_dir(struct inode *inode, * the inode containing a stream we're opening. * Therefore, we need to split the lookup table entry. */ - wimlib_assert(old_lte->refcnt > inode->link_count); + wimlib_assert(old_lte->refcnt > inode->i_nlink); DEBUG("Splitting lookup table entry " - "(inode->link_count = %u, old_lte->refcnt = %u)", - inode->link_count, old_lte->refcnt); + "(inode->i_nlink = %u, old_lte->refcnt = %u)", + inode->i_nlink, old_lte->refcnt); } new_lte = new_lookup_table_entry(); @@ -539,8 +559,8 @@ static int extract_resource_to_staging_dir(struct inode *inode, * file descriptors to the new lookup table entry. If there's * an old lookup table entry, this number needs to be subtracted * from the fd's opened to the old entry. */ - for (u16 i = 0, j = 0; j < inode->num_opened_fds; i++) { - struct wimlib_fd *fd = inode->fds[i]; + for (u16 i = 0, j = 0; j < inode->i_num_opened_fds; i++) { + struct wimfs_fd *fd = inode->i_fds[i]; if (fd) { if (fd->stream_id == stream_id) { wimlib_assert(fd->f_lte == old_lte); @@ -560,22 +580,22 @@ static int extract_resource_to_staging_dir(struct inode *inode, new_lte->num_opened_fds); if (old_lte) { old_lte->num_opened_fds -= new_lte->num_opened_fds; - old_lte->refcnt -= inode->link_count; + old_lte->refcnt -= inode->i_nlink; } } - new_lte->refcnt = inode->link_count; + new_lte->refcnt = inode->i_nlink; new_lte->resource_location = RESOURCE_IN_STAGING_FILE; new_lte->staging_file_name = staging_file_name; new_lte->lte_inode = inode; random_hash(new_lte->hash); if (stream_id == 0) - inode->lte = new_lte; + inode->i_lte = new_lte; else - for (u16 i = 0; i < inode->num_ads; i++) - if (inode->ads_entries[i].stream_id == stream_id) - inode->ads_entries[i].lte = new_lte; + for (u16 i = 0; i < inode->i_num_ads; i++) + if (inode->i_ads_entries[i].stream_id == stream_id) + inode->i_ads_entries[i].lte = new_lte; lookup_table_insert(ctx->wim->lookup_table, new_lte); list_add(&new_lte->staging_list, &ctx->staging_list); @@ -583,7 +603,7 @@ static int extract_resource_to_staging_dir(struct inode *inode, return 0; out_revert_fd_changes: for (u16 i = 0, j = 0; j < new_lte->num_opened_fds; i++) { - struct wimlib_fd *fd = inode->fds[i]; + struct wimfs_fd *fd = inode->i_fds[i]; if (fd && fd->stream_id == stream_id && fd->f_lte == new_lte) { fd->f_lte = old_lte; if (fd->staging_fd != -1) { @@ -693,26 +713,26 @@ static int delete_staging_dir(struct wimfs_context *ctx) return ret; } -static void inode_update_lte_ptr(struct inode *inode, - struct lookup_table_entry *old_lte, - struct lookup_table_entry *new_lte) +static void inode_update_lte_ptr(struct wim_inode *inode, + struct wim_lookup_table_entry *old_lte, + struct wim_lookup_table_entry *new_lte) { - if (inode->lte == old_lte) { - inode->lte = new_lte; + if (inode->i_lte == old_lte) { + inode->i_lte = new_lte; } else { - for (unsigned i = 0; i < inode->num_ads; i++) { - if (inode->ads_entries[i].lte == old_lte) { - inode->ads_entries[i].lte = new_lte; + for (unsigned i = 0; i < inode->i_num_ads; i++) { + if (inode->i_ads_entries[i].lte == old_lte) { + inode->i_ads_entries[i].lte = new_lte; break; } } } } -static int update_lte_of_staging_file(struct lookup_table_entry *lte, - struct lookup_table *table) +static int update_lte_of_staging_file(struct wim_lookup_table_entry *lte, + struct wim_lookup_table *table) { - struct lookup_table_entry *duplicate_lte; + struct wim_lookup_table_entry *duplicate_lte; int ret; u8 hash[SHA1_HASH_SIZE]; struct stat stbuf; @@ -749,14 +769,14 @@ static int update_lte_of_staging_file(struct lookup_table_entry *lte, return 0; } -static int inode_close_fds(struct inode *inode) +static int inode_close_fds(struct wim_inode *inode) { - u16 num_opened_fds = inode->num_opened_fds; + u16 num_opened_fds = inode->i_num_opened_fds; for (u16 i = 0, j = 0; j < num_opened_fds; i++) { - struct wimlib_fd *fd = inode->fds[i]; + struct wimfs_fd *fd = inode->i_fds[i]; if (fd) { wimlib_assert(fd->f_inode == inode); - int ret = close_wimlib_fd(fd); + int ret = close_wimfs_fd(fd); if (ret != 0) return ret; j++; @@ -770,7 +790,7 @@ static int rebuild_wim(struct wimfs_context *ctx, int write_flags, wimlib_progress_func_t progress_func) { int ret; - struct lookup_table_entry *lte, *tmp; + struct wim_lookup_table_entry *lte, *tmp; WIMStruct *w = ctx->wim; DEBUG("Closing all staging file descriptors."); @@ -1448,9 +1468,9 @@ static int wimfs_access(const char *path, int mask) static int wimfs_chmod(const char *path, mode_t mask) { - struct dentry *dentry; + struct wim_dentry *dentry; struct wimfs_context *ctx = wimfs_get_context(); - struct inode *inode; + struct wim_inode *inode; struct stat stbuf; int ret; @@ -1489,7 +1509,7 @@ static void wimfs_destroy(void *p) static int wimfs_fallocate(const char *path, int mode, off_t offset, off_t len, struct fuse_file_info *fi) { - struct wimlib_fd *fd = (struct wimlib_fd*)(uintptr_t)fi->fh; + struct wimfs_fd *fd = (struct wimfs_fd*)(uintptr_t)fi->fh; wimlib_assert(fd->staging_fd != -1); return fallocate(fd->staging_fd, mode, offset, len); } @@ -1499,14 +1519,14 @@ static int wimfs_fallocate(const char *path, int mode, static int wimfs_fgetattr(const char *path, struct stat *stbuf, struct fuse_file_info *fi) { - struct wimlib_fd *fd = (struct wimlib_fd*)(uintptr_t)fi->fh; + struct wimfs_fd *fd = (struct wimfs_fd*)(uintptr_t)fi->fh; return inode_to_stbuf(fd->f_inode, fd->f_lte, stbuf); } static int wimfs_ftruncate(const char *path, off_t size, struct fuse_file_info *fi) { - struct wimlib_fd *fd = (struct wimlib_fd*)(uintptr_t)fi->fh; + struct wimfs_fd *fd = (struct wimfs_fd*)(uintptr_t)fi->fh; int ret = ftruncate(fd->staging_fd, size); if (ret != 0) return -errno; @@ -1520,8 +1540,8 @@ static int wimfs_ftruncate(const char *path, off_t size, */ static int wimfs_getattr(const char *path, struct stat *stbuf) { - struct dentry *dentry; - struct lookup_table_entry *lte; + struct wim_dentry *dentry; + struct wim_lookup_table_entry *lte; int ret; struct wimfs_context *ctx = wimfs_get_context(); @@ -1539,10 +1559,10 @@ static int wimfs_getxattr(const char *path, const char *name, char *value, size_t size) { int ret; - struct inode *inode; + struct wim_inode *inode; struct ads_entry *ads_entry; size_t res_size; - struct lookup_table_entry *lte; + struct wim_lookup_table_entry *lte; struct wimfs_context *ctx = wimfs_get_context(); if (!(ctx->mount_flags & WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_XATTR)) @@ -1554,7 +1574,7 @@ static int wimfs_getxattr(const char *path, const char *name, char *value, inode = wim_pathname_to_inode(ctx->wim, path); if (!inode) - return -ENOENT; + return -errno; ads_entry = inode_get_ads_entry(inode, name, NULL); if (!ads_entry) @@ -1581,21 +1601,21 @@ static int wimfs_getxattr(const char *path, const char *name, char *value, /* Create a hard link */ static int wimfs_link(const char *to, const char *from) { - struct dentry *from_dentry, *from_dentry_parent; + struct wim_dentry *from_dentry, *from_dentry_parent; const char *link_name; - struct inode *inode; - struct lookup_table_entry *lte; + struct wim_inode *inode; + struct wim_lookup_table_entry *lte; WIMStruct *w = wimfs_get_WIMStruct(); u16 i; inode = wim_pathname_to_inode(w, to); if (!inode) - return -ENOENT; + return -errno; - if (inode->attributes & FILE_ATTRIBUTE_REPARSE_POINT) + if (inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT) return -EEXIST; - if (inode->attributes & FILE_ATTRIBUTE_DIRECTORY) + if (inode->i_attributes & FILE_ATTRIBUTE_DIRECTORY) return -EPERM; from_dentry_parent = get_parent_dentry(w, from); @@ -1613,9 +1633,9 @@ static int wimfs_link(const char *to, const char *from) inode_add_dentry(from_dentry, inode); from_dentry->d_inode = inode; - inode->link_count++; + inode->i_nlink++; - for (i = 0; i <= inode->num_ads; i++) { + for (i = 0; i <= inode->i_num_ads; i++) { lte = inode_stream_lte_resolved(inode, i); if (lte) lte->refcnt++; @@ -1628,7 +1648,7 @@ static int wimfs_link(const char *to, const char *from) static int wimfs_listxattr(const char *path, char *list, size_t size) { size_t needed_size; - struct inode *inode; + struct wim_inode *inode; struct wimfs_context *ctx = wimfs_get_context(); u16 i; char *p; @@ -1640,21 +1660,21 @@ static int wimfs_listxattr(const char *path, char *list, size_t size) inode = wim_pathname_to_inode(ctx->wim, path); if (!inode) - return -ENOENT; + return -errno; if (size == 0) { needed_size = 0; - for (i = 0; i < inode->num_ads; i++) - needed_size += inode->ads_entries[i].stream_name_utf8_len + 6; + for (i = 0; i < inode->i_num_ads; i++) + needed_size += inode->i_ads_entries[i].stream_name_utf8_len + 6; return needed_size; } else { p = list; - for (i = 0; i < inode->num_ads; i++) { - needed_size = inode->ads_entries[i].stream_name_utf8_len + 6; + for (i = 0; i < inode->i_num_ads; i++) { + needed_size = inode->i_ads_entries[i].stream_name_utf8_len + 6; if (needed_size > size) return -ERANGE; p += sprintf(p, "user.%s", - inode->ads_entries[i].stream_name_utf8) + 1; + inode->i_ads_entries[i].stream_name_utf8) + 1; size -= needed_size; } return p - list; @@ -1667,12 +1687,12 @@ static int wimfs_listxattr(const char *path, char *list, size_t size) * @mode is currently ignored. */ static int wimfs_mkdir(const char *path, mode_t mode) { - struct dentry *dentry; + struct wim_dentry *dentry; int ret; ret = create_dentry(wimfs_get_context(), path, &dentry); if (ret == 0) - dentry->d_inode->attributes = FILE_ATTRIBUTE_DIRECTORY; + dentry->d_inode->i_attributes = FILE_ATTRIBUTE_DIRECTORY; return ret; } @@ -1686,7 +1706,7 @@ static int wimfs_mknod(const char *path, mode_t mode, dev_t rdev) && (stream_name = path_stream_name(path))) { /* Make an alternate data stream */ struct ads_entry *new_entry; - struct inode *inode; + struct wim_inode *inode; char *p = (char*)stream_name - 1; wimlib_assert(*p == ':'); @@ -1694,8 +1714,8 @@ static int wimfs_mknod(const char *path, mode_t mode, dev_t rdev) inode = wim_pathname_to_inode(ctx->wim, path); if (!inode) - return -ENOENT; - if (inode->attributes & + return -errno; + if (inode->i_attributes & (FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_DIRECTORY)) return -ENOENT; if (inode_get_ads_entry(inode, stream_name, NULL)) @@ -1705,13 +1725,13 @@ static int wimfs_mknod(const char *path, mode_t mode, dev_t rdev) return -ENOMEM; return 0; } else { - struct dentry *dentry; + struct wim_dentry *dentry; int ret; /* Make a normal file (not an alternate data stream) */ ret = create_dentry(ctx, path, &dentry); if (ret == 0) - dentry->d_inode->attributes = FILE_ATTRIBUTE_NORMAL; + dentry->d_inode->i_attributes = FILE_ATTRIBUTE_NORMAL; return ret; } } @@ -1720,11 +1740,11 @@ static int wimfs_mknod(const char *path, mode_t mode, dev_t rdev) /* Open a file. */ static int wimfs_open(const char *path, struct fuse_file_info *fi) { - struct dentry *dentry; - struct lookup_table_entry *lte; + struct wim_dentry *dentry; + struct wim_lookup_table_entry *lte; int ret; - struct wimlib_fd *fd; - struct inode *inode; + struct wimfs_fd *fd; + struct wim_inode *inode; u16 stream_idx; u32 stream_id; struct wimfs_context *ctx = wimfs_get_context(); @@ -1739,7 +1759,7 @@ static int wimfs_open(const char *path, struct fuse_file_info *fi) if (stream_idx == 0) stream_id = 0; else - stream_id = inode->ads_entries[stream_idx - 1].stream_id; + stream_id = inode->i_ads_entries[stream_idx - 1].stream_id; /* The file resource may be in the staging directory (read-write mounts * only) or in the WIM. If it's in the staging directory, we need to @@ -1757,7 +1777,7 @@ static int wimfs_open(const char *path, struct fuse_file_info *fi) return ret; } - ret = alloc_wimlib_fd(inode, stream_id, lte, &fd, + ret = alloc_wimfs_fd(inode, stream_id, lte, &fd, wimfs_ctx_readonly(ctx)); if (ret != 0) return ret; @@ -1766,7 +1786,7 @@ static int wimfs_open(const char *path, struct fuse_file_info *fi) fd->staging_fd = open(lte->staging_file_name, fi->flags); if (fd->staging_fd == -1) { int errno_save = errno; - close_wimlib_fd(fd); + close_wimfs_fd(fd); return -errno_save; } } @@ -1777,18 +1797,18 @@ static int wimfs_open(const char *path, struct fuse_file_info *fi) /* Opens a directory. */ static int wimfs_opendir(const char *path, struct fuse_file_info *fi) { - struct inode *inode; + struct wim_inode *inode; int ret; - struct wimlib_fd *fd = NULL; + struct wimfs_fd *fd = NULL; struct wimfs_context *ctx = wimfs_get_context(); WIMStruct *w = ctx->wim; inode = wim_pathname_to_inode(w, path); if (!inode) - return -ENOENT; + return -errno; if (!inode_is_directory(inode)) return -ENOTDIR; - ret = alloc_wimlib_fd(inode, 0, NULL, &fd, wimfs_ctx_readonly(ctx)); + ret = alloc_wimfs_fd(inode, 0, NULL, &fd, wimfs_ctx_readonly(ctx)); fi->fh = (uintptr_t)fd; return ret; } @@ -1800,7 +1820,7 @@ static int wimfs_opendir(const char *path, struct fuse_file_info *fi) static int wimfs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { - struct wimlib_fd *fd = (struct wimlib_fd*)(uintptr_t)fi->fh; + struct wimfs_fd *fd = (struct wimfs_fd*)(uintptr_t)fi->fh; ssize_t ret; if (!fd) @@ -1842,7 +1862,7 @@ struct fill_params { fuse_fill_dir_t filler; }; -static int dentry_fuse_fill(struct dentry *dentry, void *arg) +static int dentry_fuse_fill(struct wim_dentry *dentry, void *arg) { struct fill_params *fill_params = arg; return fill_params->filler(fill_params->buf, dentry->file_name_utf8, @@ -1854,8 +1874,8 @@ static int dentry_fuse_fill(struct dentry *dentry, void *arg) static int wimfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { - struct wimlib_fd *fd = (struct wimlib_fd*)(uintptr_t)fi->fh; - struct inode *inode; + struct wimfs_fd *fd = (struct wimfs_fd*)(uintptr_t)fi->fh; + struct wim_inode *inode; if (!fd) return -EBADF; @@ -1870,7 +1890,7 @@ static int wimfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, filler(buf, ".", NULL, 0); filler(buf, "..", NULL, 0); - return for_dentry_in_rbtree(inode->children.rb_node, + return for_dentry_in_rbtree(inode->i_children.rb_node, dentry_fuse_fill, &fill_params); } @@ -1878,10 +1898,10 @@ static int wimfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, static int wimfs_readlink(const char *path, char *buf, size_t buf_len) { struct wimfs_context *ctx = wimfs_get_context(); - struct inode *inode = wim_pathname_to_inode(ctx->wim, path); + struct wim_inode *inode = wim_pathname_to_inode(ctx->wim, path); int ret; if (!inode) - return -ENOENT; + return -errno; if (!inode_is_symlink(inode)) return -EINVAL; @@ -1895,22 +1915,22 @@ static int wimfs_readlink(const char *path, char *buf, size_t buf_len) /* Close a file. */ static int wimfs_release(const char *path, struct fuse_file_info *fi) { - struct wimlib_fd *fd = (struct wimlib_fd*)(uintptr_t)fi->fh; - return close_wimlib_fd(fd); + struct wimfs_fd *fd = (struct wimfs_fd*)(uintptr_t)fi->fh; + return close_wimfs_fd(fd); } /* Close a directory */ static int wimfs_releasedir(const char *path, struct fuse_file_info *fi) { - struct wimlib_fd *fd = (struct wimlib_fd*)(uintptr_t)fi->fh; - return close_wimlib_fd(fd); + struct wimfs_fd *fd = (struct wimfs_fd*)(uintptr_t)fi->fh; + return close_wimfs_fd(fd); } #ifdef ENABLE_XATTR /* Remove an alternate data stream through the XATTR interface */ static int wimfs_removexattr(const char *path, const char *name) { - struct inode *inode; + struct wim_inode *inode; struct ads_entry *ads_entry; u16 ads_idx; struct wimfs_context *ctx = wimfs_get_context(); @@ -1924,7 +1944,7 @@ static int wimfs_removexattr(const char *path, const char *name) inode = wim_pathname_to_inode(ctx->wim, path); if (!inode) - return -ENOENT; + return -errno; ads_entry = inode_get_ads_entry(inode, name, &ads_idx); if (!ads_entry) @@ -1937,11 +1957,9 @@ static int wimfs_removexattr(const char *path, const char *name) /* Renames a file or directory. See rename (3) */ static int wimfs_rename(const char *from, const char *to) { - struct dentry *src; - struct dentry *dst; - struct dentry *parent_of_dst; - char *file_name_utf16 = NULL, *file_name_utf8 = NULL; - u16 file_name_utf16_len, file_name_utf8_len; + struct wim_dentry *src; + struct wim_dentry *dst; + struct wim_dentry *parent_of_dst; WIMStruct *w = wimfs_get_WIMStruct(); int ret; @@ -1950,16 +1968,10 @@ static int wimfs_rename(const char *from, const char *to) src = get_dentry(w, from); if (!src) - return -ENOENT; + return -errno; dst = get_dentry(w, to); - ret = get_names(&file_name_utf16, &file_name_utf8, - &file_name_utf16_len, &file_name_utf8_len, - path_basename(to)); - if (ret != 0) - return -ENOMEM; - if (dst) { /* Destination file exists */ @@ -1979,24 +1991,21 @@ static int wimfs_rename(const char *from, const char *to) return -ENOTEMPTY; } parent_of_dst = dst->parent; - remove_dentry(dst, w->lookup_table); } else { /* Destination does not exist */ parent_of_dst = get_parent_dentry(w, to); if (!parent_of_dst) - return -ENOENT; + return -errno; if (!dentry_is_directory(parent_of_dst)) return -ENOTDIR; } - FREE(src->file_name); - FREE(src->file_name_utf8); - src->file_name = file_name_utf16; - src->file_name_utf8 = file_name_utf8; - src->file_name_len = file_name_utf16_len; - src->file_name_utf8_len = file_name_utf8_len; - + ret = set_dentry_name(src, to); + if (ret != 0) + return -ENOMEM; + if (dst) + remove_dentry(dst, w->lookup_table); unlink_dentry(src); dentry_add_child(parent_of_dst, src); return 0; @@ -2005,14 +2014,17 @@ static int wimfs_rename(const char *from, const char *to) /* Remove a directory */ static int wimfs_rmdir(const char *path) { - struct dentry *dentry; + struct wim_dentry *parent, *dentry; WIMStruct *w = wimfs_get_WIMStruct(); dentry = get_dentry(w, path); if (!dentry) - return -ENOENT; + return -errno; + + if (!dentry_is_directory(dentry)) + return -ENOTDIR; - if (!dentry_is_empty_directory(dentry)) + if (dentry_has_children(dentry)) return -ENOTEMPTY; remove_dentry(dentry, w->lookup_table); @@ -2026,9 +2038,9 @@ static int wimfs_setxattr(const char *path, const char *name, { struct ads_entry *existing_ads_entry; struct ads_entry *new_ads_entry; - struct lookup_table_entry *existing_lte; - struct lookup_table_entry *lte; - struct inode *inode; + struct wim_lookup_table_entry *existing_lte; + struct wim_lookup_table_entry *lte; + struct wim_inode *inode; u8 value_hash[SHA1_HASH_SIZE]; u16 ads_idx; struct wimfs_context *ctx = wimfs_get_context(); @@ -2042,7 +2054,7 @@ static int wimfs_setxattr(const char *path, const char *name, inode = wim_pathname_to_inode(ctx->wim, path); if (!inode) - return -ENOENT; + return -errno; existing_ads_entry = inode_get_ads_entry(inode, name, &ads_idx); if (existing_ads_entry) { @@ -2091,13 +2103,13 @@ static int wimfs_setxattr(const char *path, const char *name, static int wimfs_symlink(const char *to, const char *from) { struct wimfs_context *ctx = wimfs_get_context(); - struct dentry *dentry; + struct wim_dentry *dentry; int ret; ret = create_dentry(ctx, from, &dentry); if (ret == 0) { - dentry->d_inode->attributes = FILE_ATTRIBUTE_REPARSE_POINT; - dentry->d_inode->reparse_tag = WIM_IO_REPARSE_TAG_SYMLINK; + dentry->d_inode->i_attributes = FILE_ATTRIBUTE_REPARSE_POINT; + dentry->d_inode->i_reparse_tag = WIM_IO_REPARSE_TAG_SYMLINK; if (inode_set_symlink(dentry->d_inode, to, ctx->wim->lookup_table, NULL)) { @@ -2113,12 +2125,12 @@ static int wimfs_symlink(const char *to, const char *from) /* Reduce the size of a file */ static int wimfs_truncate(const char *path, off_t size) { - struct dentry *dentry; - struct lookup_table_entry *lte; + struct wim_dentry *dentry; + struct wim_lookup_table_entry *lte; int ret; u16 stream_idx; u32 stream_id; - struct inode *inode; + struct wim_inode *inode; struct wimfs_context *ctx = wimfs_get_context(); ret = lookup_resource(ctx->wim, path, get_lookup_flags(ctx), @@ -2134,7 +2146,7 @@ static int wimfs_truncate(const char *path, off_t size) if (stream_idx == 0) stream_id = 0; else - stream_id = inode->ads_entries[stream_idx - 1].stream_id; + stream_id = inode->i_ads_entries[stream_idx - 1].stream_id; if (lte->resource_location == RESOURCE_IN_STAGING_FILE) { ret = truncate(lte->staging_file_name, size); @@ -2152,8 +2164,8 @@ static int wimfs_truncate(const char *path, off_t size) /* Unlink a non-directory or alternate data stream */ static int wimfs_unlink(const char *path) { - struct dentry *dentry; - struct lookup_table_entry *lte; + struct wim_dentry *dentry; + struct wim_lookup_table_entry *lte; int ret; u16 stream_idx; struct wimfs_context *ctx = wimfs_get_context(); @@ -2180,43 +2192,43 @@ static int wimfs_unlink(const char *path) */ static int wimfs_utimens(const char *path, const struct timespec tv[2]) { - struct dentry *dentry; - struct inode *inode; + struct wim_dentry *dentry; + struct wim_inode *inode; WIMStruct *w = wimfs_get_WIMStruct(); dentry = get_dentry(w, path); if (!dentry) - return -ENOENT; + return -errno; inode = dentry->d_inode; if (tv[0].tv_nsec != UTIME_OMIT) { if (tv[0].tv_nsec == UTIME_NOW) - inode->last_access_time = get_wim_timestamp(); + inode->i_last_access_time = get_wim_timestamp(); else - inode->last_access_time = timespec_to_wim_timestamp(&tv[0]); + inode->i_last_access_time = timespec_to_wim_timestamp(&tv[0]); } if (tv[1].tv_nsec != UTIME_OMIT) { if (tv[1].tv_nsec == UTIME_NOW) - inode->last_write_time = get_wim_timestamp(); + inode->i_last_write_time = get_wim_timestamp(); else - inode->last_write_time = timespec_to_wim_timestamp(&tv[1]); + inode->i_last_write_time = timespec_to_wim_timestamp(&tv[1]); } return 0; } #else static int wimfs_utime(const char *path, struct utimbuf *times) { - struct dentry *dentry; - struct inode *inode; + struct wim_dentry *dentry; + struct wim_inode *inode; WIMStruct *w = wimfs_get_WIMStruct(); dentry = get_dentry(w, path); if (!dentry) - return -ENOENT; + return -errno; inode = dentry->d_inode; - inode->last_write_time = unix_timestamp_to_wim(times->modtime); - inode->last_access_time = unix_timestamp_to_wim(times->actime); + inode->i_last_write_time = unix_timestamp_to_wim(times->modtime); + inode->i_last_access_time = unix_timestamp_to_wim(times->actime); return 0; } #endif @@ -2227,7 +2239,7 @@ static int wimfs_utime(const char *path, struct utimbuf *times) static int wimfs_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { - struct wimlib_fd *fd = (struct wimlib_fd*)(uintptr_t)fi->fh; + struct wimfs_fd *fd = (struct wimfs_fd*)(uintptr_t)fi->fh; int ret; u64 now; @@ -2249,8 +2261,8 @@ static int wimfs_write(const char *path, const char *buf, size_t size, return -errno; now = get_wim_timestamp(); - fd->f_inode->last_write_time = now; - fd->f_inode->last_access_time = now; + fd->f_inode->i_last_write_time = now; + fd->f_inode->i_last_access_time = now; return ret; } @@ -2298,6 +2310,9 @@ static struct fuse_operations wimfs_operations = { #endif .write = wimfs_write, + /* wimfs keeps file descriptor structures (struct wimfs_fd), so there is + * no need to have the file path provided on operations such as read() + * where only the file descriptor is needed. */ #if FUSE_MAJOR_VERSION > 2 || (FUSE_MAJOR_VERSION == 2 && FUSE_MINOR_VERSION >= 8) .flag_nullpath_ok = 1, #endif @@ -2318,11 +2333,11 @@ WIMLIBAPI int wimlib_mount_image(WIMStruct *wim, int image, const char *dir, char *argv[16]; int ret; char *dir_copy; - struct lookup_table *joined_tab, *wim_tab_save; + struct wim_lookup_table *joined_tab, *wim_tab_save; struct image_metadata *imd; struct wimfs_context ctx; struct hlist_node *cur_node; - struct inode *inode; + struct wim_inode *inode; DEBUG("Mount: wim = %p, image = %d, dir = %s, flags = %d, ", wim, image, dir, mount_flags); @@ -2370,7 +2385,7 @@ WIMLIBAPI int wimlib_mount_image(WIMStruct *wim, int image, const char *dir, goto out; } - if (imd->inode_list.first) + if (imd->inode_list.first) /* May be unneeded? */ imd->inode_list.first->pprev = &imd->inode_list.first; if (imd->modified) { @@ -2386,6 +2401,7 @@ WIMLIBAPI int wimlib_mount_image(WIMStruct *wim, int image, const char *dir, goto out; } + /* Use default stream interface if one was not specified */ if (!(mount_flags & (WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_NONE | WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_XATTR | WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_WINDOWS))) @@ -2424,11 +2440,8 @@ WIMLIBAPI int wimlib_mount_image(WIMStruct *wim, int image, const char *dir, argv[argc++] = "-d"; /* - * We provide the use_ino option because we are going to assign inode - * numbers oursides. The inodes will be given unique numbers in the - * assign_inode_numbers() function, and the static variable @next_ino is - * set to the next available inode number. - */ + * We provide the use_ino option to the FUSE mount because we are going + * to assign inode numbers oursides. */ char optstring[256] = "use_ino" ",subtype=wimfs" @@ -2472,13 +2485,11 @@ WIMLIBAPI int wimlib_mount_image(WIMStruct *wim, int image, const char *dir, /* Resolve the lookup table entries for every inode in the image, and * assign inode numbers */ DEBUG("Resolving lookup table entries and assigning inode numbers"); - ctx.next_ino = 1; - hlist_for_each_entry(inode, cur_node, &imd->inode_list, hlist) { + hlist_for_each_entry(inode, cur_node, &imd->inode_list, i_hlist) { inode_resolve_ltes(inode, wim->lookup_table); - inode->ino = ctx.next_ino++; + inode->i_ino = ctx.next_ino++; } - /*ctx.next_ino = assign_inode_numbers(&imd->inode_list);*/ DEBUG("(next_ino = %"PRIu64")", ctx.next_ino); DEBUG("Calling fuse_main()"); @@ -2486,6 +2497,7 @@ WIMLIBAPI int wimlib_mount_image(WIMStruct *wim, int image, const char *dir, ret = fuse_main(argc, argv, &wimfs_operations, &ctx); DEBUG("Returned from fuse_main() (ret = %d)", ret); + if (ret) ret = WIMLIB_ERR_FUSE; out_free_dir_copy: diff --git a/src/ntfs-apply.c b/src/ntfs-apply.c index 84fed6a3..998702f2 100644 --- a/src/ntfs-apply.c +++ b/src/ntfs-apply.c @@ -58,7 +58,7 @@ static int extract_wim_chunk_to_ntfs_attr(const u8 *buf, size_t len, * Extracts a WIM resource to a NTFS attribute. */ static int -extract_wim_resource_to_ntfs_attr(const struct lookup_table_entry *lte, +extract_wim_resource_to_ntfs_attr(const struct wim_lookup_table_entry *lte, ntfs_attr *na) { return extract_wim_resource(lte, wim_resource_size(lte), @@ -81,22 +81,22 @@ extract_wim_resource_to_ntfs_attr(const struct lookup_table_entry *lte, * * Returns 0 on success, nonzero on failure. */ -static int write_ntfs_data_streams(ntfs_inode *ni, const struct dentry *dentry, +static int write_ntfs_data_streams(ntfs_inode *ni, const struct wim_dentry *dentry, union wimlib_progress_info *progress_info) { int ret = 0; unsigned stream_idx = 0; ntfschar *stream_name = AT_UNNAMED; u32 stream_name_len = 0; - const struct inode *inode = dentry->d_inode; - struct lookup_table_entry *lte; + const struct wim_inode *inode = dentry->d_inode; + struct wim_lookup_table_entry *lte; DEBUG("Writing %u NTFS data stream%s for `%s'", - inode->num_ads + 1, - (inode->num_ads == 0 ? "" : "s"), + inode->i_num_ads + 1, + (inode->i_num_ads == 0 ? "" : "s"), dentry->full_path_utf8); - lte = inode->lte; + lte = inode->i_lte; while (1) { if (stream_name_len) { /* Create an empty named stream. */ @@ -148,13 +148,13 @@ static int write_ntfs_data_streams(ntfs_inode *ni, const struct dentry *dentry, * have been extracted. */ progress_info->extract.completed_bytes += wim_resource_size(lte); } - if (stream_idx == inode->num_ads) /* Has the last stream been extracted? */ + if (stream_idx == inode->i_num_ads) /* Has the last stream been extracted? */ break; /* Get the name and lookup table entry for the next stream. */ - stream_name = (ntfschar*)inode->ads_entries[stream_idx].stream_name; - stream_name_len = inode->ads_entries[stream_idx].stream_name_len / 2; - lte = inode->ads_entries[stream_idx].lte; + stream_name = (ntfschar*)inode->i_ads_entries[stream_idx].stream_name; + stream_name_len = inode->i_ads_entries[stream_idx].stream_name_len / 2; + lte = inode->i_ads_entries[stream_idx].lte; stream_idx++; } return ret; @@ -162,7 +162,7 @@ static int write_ntfs_data_streams(ntfs_inode *ni, const struct dentry *dentry, /* Open the NTFS inode that corresponds to the parent of a WIM dentry. Returns * the opened inode, or NULL on failure. */ -static ntfs_inode *dentry_open_parent_ni(const struct dentry *dentry, +static ntfs_inode *dentry_open_parent_ni(const struct wim_dentry *dentry, ntfs_volume *vol) { char *p; @@ -192,15 +192,15 @@ static ntfs_inode *dentry_open_parent_ni(const struct dentry *dentry, * * The hard link is named @from_dentry->file_name and is located under the * directory specified by @dir_ni, and it is made to point to the previously - * extracted file located at @inode->extracted_file. + * extracted file located at @inode->i_extracted_file. * * Or, in other words, this adds a new name @from_dentry->full_path_utf8 to an - * existing NTFS inode which already has a name @inode->extracted_file. + * existing NTFS inode which already has a name @inode->i_extracted_file. * * Return 0 on success, nonzero on failure. */ -static int apply_ntfs_hardlink(const struct dentry *from_dentry, - const struct inode *inode, +static int apply_ntfs_hardlink(const struct wim_dentry *from_dentry, + const struct wim_inode *inode, ntfs_inode **dir_ni_p) { int ret; @@ -218,12 +218,12 @@ static int apply_ntfs_hardlink(const struct dentry *from_dentry, } DEBUG("Extracting NTFS hard link `%s' => `%s'", - from_dentry->full_path_utf8, inode->extracted_file); + from_dentry->full_path_utf8, inode->i_extracted_file); - to_ni = ntfs_pathname_to_inode(vol, NULL, inode->extracted_file); + to_ni = ntfs_pathname_to_inode(vol, NULL, inode->i_extracted_file); if (!to_ni) { ERROR_WITH_ERRNO("Could not find NTFS inode for `%s'", - inode->extracted_file); + inode->i_extracted_file); return WIMLIB_ERR_NTFS_3G; } @@ -241,7 +241,7 @@ static int apply_ntfs_hardlink(const struct dentry *from_dentry, if (ntfs_inode_close_in_dir(to_ni, dir_ni) || ret != 0) { ERROR_WITH_ERRNO("Could not create hard link `%s' => `%s'", from_dentry->full_path_utf8, - inode->extracted_file); + inode->i_extracted_file); ret = WIMLIB_ERR_NTFS_3G; } return ret; @@ -261,20 +261,20 @@ static int apply_ntfs_hardlink(const struct dentry *from_dentry, static int apply_file_attributes_and_security_data(ntfs_inode *ni, ntfs_inode *dir_ni, - const struct dentry *dentry, + const struct wim_dentry *dentry, const WIMStruct *w) { int ret; struct SECURITY_CONTEXT ctx; u32 attributes_le32; - const struct inode *inode; + const struct wim_inode *inode; inode = dentry->d_inode; DEBUG("Setting NTFS file attributes on `%s' to %#"PRIx32, - dentry->full_path_utf8, inode->attributes); + dentry->full_path_utf8, inode->i_attributes); - attributes_le32 = cpu_to_le32(inode->attributes); + attributes_le32 = cpu_to_le32(inode->i_attributes); memset(&ctx, 0, sizeof(ctx)); ctx.vol = ni->vol; ret = ntfs_xattr_system_setxattr(&ctx, XATTR_NTFS_ATTRIB, @@ -286,19 +286,19 @@ apply_file_attributes_and_security_data(ntfs_inode *ni, dentry->full_path_utf8); return WIMLIB_ERR_NTFS_3G; } - if (inode->security_id != -1) { + if (inode->i_security_id != -1) { const char *desc; const struct wim_security_data *sd; sd = wim_const_security_data(w); - wimlib_assert(inode->security_id < sd->num_entries); - desc = (const char *)sd->descriptors[inode->security_id]; + wimlib_assert(inode->i_security_id < sd->num_entries); + desc = (const char *)sd->descriptors[inode->i_security_id]; DEBUG("Applying security descriptor %d to `%s'", - inode->security_id, dentry->full_path_utf8); + inode->i_security_id, dentry->full_path_utf8); ret = ntfs_xattr_system_setxattr(&ctx, XATTR_NTFS_ACL, ni, dir_ni, desc, - sd->sizes[inode->security_id], 0); + sd->sizes[inode->i_security_id], 0); if (ret != 0) { ERROR_WITH_ERRNO("Failed to set security data on `%s'", @@ -313,10 +313,10 @@ apply_file_attributes_and_security_data(ntfs_inode *ni, * Transfers the reparse data from a WIM inode (which must represent a reparse * point) to a NTFS inode. */ -static int apply_reparse_data(ntfs_inode *ni, const struct dentry *dentry, +static int apply_reparse_data(ntfs_inode *ni, const struct wim_dentry *dentry, union wimlib_progress_info *progress_info) { - struct lookup_table_entry *lte; + struct wim_lookup_table_entry *lte; int ret = 0; lte = inode_unnamed_lte_resolved(dentry->d_inode); @@ -337,7 +337,7 @@ static int apply_reparse_data(ntfs_inode *ni, const struct dentry *dentry, u8 reparse_data_buf[8 + wim_resource_size(lte)]; u8 *p = reparse_data_buf; - p = put_u32(p, dentry->d_inode->reparse_tag); /* ReparseTag */ + p = put_u32(p, dentry->d_inode->i_reparse_tag); /* ReparseTag */ p = put_u16(p, wim_resource_size(lte)); /* ReparseDataLength */ p = put_u16(p, 0); /* Reserved */ @@ -356,7 +356,7 @@ static int apply_reparse_data(ntfs_inode *ni, const struct dentry *dentry, return 0; } -static int do_apply_dentry_ntfs(struct dentry *dentry, ntfs_inode *dir_ni, +static int do_apply_dentry_ntfs(struct wim_dentry *dentry, ntfs_inode *dir_ni, struct apply_args *args); /* @@ -367,12 +367,12 @@ static int do_apply_dentry_ntfs(struct dentry *dentry, ntfs_inode *dir_ni, * in the Win32 namespace, and not any of the additional names in the POSIX * namespace created from hard links. */ -static int preapply_dentry_with_dos_name(struct dentry *dentry, +static int preapply_dentry_with_dos_name(struct wim_dentry *dentry, ntfs_inode **dir_ni_p, struct apply_args *args) { - struct dentry *other; - struct dentry *dentry_with_dos_name; + struct wim_dentry *other; + struct wim_dentry *dentry_with_dos_name; dentry_with_dos_name = NULL; inode_for_each_dentry(other, dentry->d_inode) { @@ -415,17 +415,17 @@ static int preapply_dentry_with_dos_name(struct dentry *dentry, * * @return: 0 on success; nonzero on failure. */ -static int do_apply_dentry_ntfs(struct dentry *dentry, ntfs_inode *dir_ni, +static int do_apply_dentry_ntfs(struct wim_dentry *dentry, ntfs_inode *dir_ni, struct apply_args *args) { int ret = 0; mode_t type; ntfs_inode *ni = NULL; ntfs_volume *vol = dir_ni->vol; - struct inode *inode = dentry->d_inode; + struct wim_inode *inode = dentry->d_inode; dentry->is_extracted = 1; - if (inode->attributes & FILE_ATTRIBUTE_DIRECTORY) { + if (inode->i_attributes & FILE_ATTRIBUTE_DIRECTORY) { type = S_IFDIR; } else { /* If this dentry is hard-linked to any other dentries in the @@ -439,10 +439,10 @@ static int do_apply_dentry_ntfs(struct dentry *dentry, ntfs_inode *dir_ni, return ret; } type = S_IFREG; - if (inode->link_count > 1) { + if (inode->i_nlink > 1) { /* Inode has multiple dentries referencing it. */ - if (inode->extracted_file) { + if (inode->i_extracted_file) { /* Already extracted another dentry in the hard * link group. Make a hard link instead of * extracting the file data. */ @@ -456,9 +456,9 @@ static int do_apply_dentry_ntfs(struct dentry *dentry, ntfs_inode *dir_ni, /* None of the dentries of this inode have been * extracted yet, so go ahead and extract the * first one. */ - FREE(inode->extracted_file); - inode->extracted_file = STRDUP(dentry->full_path_utf8); - if (!inode->extracted_file) { + FREE(inode->i_extracted_file); + inode->i_extracted_file = STRDUP(dentry->full_path_utf8); + if (!inode->i_extracted_file) { ret = WIMLIB_ERR_NOMEM; goto out_close_dir_ni; } @@ -483,7 +483,7 @@ static int do_apply_dentry_ntfs(struct dentry *dentry, ntfs_inode *dir_ni, /* Write the data streams, unless this is a directory or reparse point * */ - if (!(inode->attributes & (FILE_ATTRIBUTE_REPARSE_POINT | + if (!(inode->i_attributes & (FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_DIRECTORY))) { ret = write_ntfs_data_streams(ni, dentry, &args->progress); if (ret != 0) @@ -496,7 +496,7 @@ static int do_apply_dentry_ntfs(struct dentry *dentry, ntfs_inode *dir_ni, if (ret != 0) goto out_close_dir_ni; - if (inode->attributes & FILE_ATTR_REPARSE_POINT) { + if (inode->i_attributes & FILE_ATTR_REPARSE_POINT) { ret = apply_reparse_data(ni, dentry, &args->progress); if (ret != 0) goto out_close_dir_ni; @@ -566,7 +566,7 @@ out_close_dir_ni: return ret; } -static int apply_root_dentry_ntfs(const struct dentry *dentry, +static int apply_root_dentry_ntfs(const struct wim_dentry *dentry, ntfs_volume *vol, const WIMStruct *w) { ntfs_inode *ni; @@ -587,7 +587,7 @@ static int apply_root_dentry_ntfs(const struct dentry *dentry, } /* Applies a WIM dentry to the NTFS volume */ -int apply_dentry_ntfs(struct dentry *dentry, void *arg) +int apply_dentry_ntfs(struct wim_dentry *dentry, void *arg) { struct apply_args *args = arg; ntfs_volume *vol = args->vol; @@ -606,7 +606,7 @@ int apply_dentry_ntfs(struct dentry *dentry, void *arg) /* Transfers the 100-nanosecond precision timestamps from a WIM dentry to a NTFS * inode */ -int apply_dentry_timestamps_ntfs(struct dentry *dentry, void *arg) +int apply_dentry_timestamps_ntfs(struct wim_dentry *dentry, void *arg) { struct apply_args *args = arg; ntfs_volume *vol = args->vol; @@ -625,9 +625,9 @@ int apply_dentry_timestamps_ntfs(struct dentry *dentry, void *arg) } p = buf; - p = put_u64(p, dentry->d_inode->creation_time); - p = put_u64(p, dentry->d_inode->last_write_time); - p = put_u64(p, dentry->d_inode->last_access_time); + p = put_u64(p, dentry->d_inode->i_creation_time); + p = put_u64(p, dentry->d_inode->i_last_write_time); + p = put_u64(p, dentry->d_inode->i_last_access_time); ret = ntfs_inode_set_times(ni, (const char*)buf, 3 * sizeof(u64), 0); if (ret != 0) { ERROR_WITH_ERRNO("Failed to set NTFS timestamps on `%s'", diff --git a/src/ntfs-capture.c b/src/ntfs-capture.c index 8f123f80..69123f06 100644 --- a/src/ntfs-capture.c +++ b/src/ntfs-capture.c @@ -246,9 +246,9 @@ out_error: /* Load the streams from a file or reparse point in the NTFS volume into the WIM * lookup table */ -static int capture_ntfs_streams(struct dentry *dentry, ntfs_inode *ni, +static int capture_ntfs_streams(struct wim_dentry *dentry, ntfs_inode *ni, char path[], size_t path_len, - struct lookup_table *lookup_table, + struct wim_lookup_table *lookup_table, ntfs_volume **ntfs_vol_p, ATTR_TYPES type) { @@ -256,7 +256,7 @@ static int capture_ntfs_streams(struct dentry *dentry, ntfs_inode *ni, u8 attr_hash[SHA1_HASH_SIZE]; struct ntfs_location *ntfs_loc = NULL; int ret = 0; - struct lookup_table_entry *lte; + struct wim_lookup_table_entry *lte; DEBUG2("Capturing NTFS data streams from `%s'", path); @@ -330,7 +330,7 @@ static int capture_ntfs_streams(struct dentry *dentry, ntfs_inode *ni, lte->ntfs_loc = ntfs_loc; lte->resource_location = RESOURCE_IN_NTFS_VOLUME; if (type == AT_REPARSE_POINT) { - dentry->d_inode->reparse_tag = reparse_tag; + dentry->d_inode->i_reparse_tag = reparse_tag; ntfs_loc->is_reparse_point = true; lte->resource_entry.original_size = data_size - 8; lte->resource_entry.size = data_size - 8; @@ -350,13 +350,13 @@ static int capture_ntfs_streams(struct dentry *dentry, ntfs_inode *ni, if (name_length == 0) { /* Unnamed data stream. Put the reference to it in the * dentry's inode. */ - if (dentry->d_inode->lte) { + if (dentry->d_inode->i_lte) { ERROR("Found two un-named data streams for " "`%s'", path); ret = WIMLIB_ERR_NTFS_3G; goto out_free_lte; } - dentry->d_inode->lte = lte; + dentry->d_inode->i_lte = lte; } else { /* Named data stream. Put the reference to it in the * alternate data stream entries */ @@ -399,11 +399,11 @@ out_put_actx: } struct readdir_ctx { - struct dentry *parent; + struct wim_dentry *parent; ntfs_inode *dir_ni; char *path; size_t path_len; - struct lookup_table *lookup_table; + struct wim_lookup_table *lookup_table; struct sd_set *sd_set; const struct capture_config *config; ntfs_volume **ntfs_vol_p; @@ -412,10 +412,10 @@ struct readdir_ctx { }; static int -build_dentry_tree_ntfs_recursive(struct dentry **root_p, ntfs_inode *dir_ni, +build_dentry_tree_ntfs_recursive(struct wim_dentry **root_p, ntfs_inode *dir_ni, ntfs_inode *ni, char path[], size_t path_len, int name_type, - struct lookup_table *lookup_table, + struct wim_lookup_table *lookup_table, struct sd_set *sd_set, const struct capture_config *config, ntfs_volume **ntfs_vol_p, @@ -430,7 +430,7 @@ static int wim_ntfs_capture_filldir(void *dirent, const ntfschar *name, struct readdir_ctx *ctx; size_t utf8_name_len; char *utf8_name; - struct dentry *child = NULL; + struct wim_dentry *child = NULL; int ret; size_t path_len; @@ -477,7 +477,7 @@ out_free_utf8_name: return ret; } -static int change_dentry_short_name(struct dentry *dentry, +static int change_dentry_short_name(struct wim_dentry *dentry, const char short_name_utf8[], int short_name_utf8_len) { @@ -498,13 +498,13 @@ static int change_dentry_short_name(struct dentry *dentry, * At the same time, update the WIM lookup table with lookup table entries for * the NTFS streams, and build an array of security descriptors. */ -static int build_dentry_tree_ntfs_recursive(struct dentry **root_p, +static int build_dentry_tree_ntfs_recursive(struct wim_dentry **root_p, ntfs_inode *dir_ni, ntfs_inode *ni, char path[], size_t path_len, int name_type, - struct lookup_table *lookup_table, + struct wim_lookup_table *lookup_table, struct sd_set *sd_set, const struct capture_config *config, ntfs_volume **ntfs_vol_p, @@ -514,7 +514,7 @@ static int build_dentry_tree_ntfs_recursive(struct dentry **root_p, u32 attributes; int mrec_flags; int ret; - struct dentry *root; + struct wim_dentry *root; if (exclude_path(path, config, false)) { if ((add_image_flags & WIMLIB_ADD_IMAGE_FLAG_VERBOSE) @@ -585,12 +585,12 @@ static int build_dentry_tree_ntfs_recursive(struct dentry **root_p, } } - root->d_inode->creation_time = le64_to_cpu(ni->creation_time); - root->d_inode->last_write_time = le64_to_cpu(ni->last_data_change_time); - root->d_inode->last_access_time = le64_to_cpu(ni->last_access_time); - root->d_inode->attributes = le32_to_cpu(attributes); - root->d_inode->ino = ni->mft_no; - root->d_inode->resolved = true; + root->d_inode->i_creation_time = le64_to_cpu(ni->creation_time); + root->d_inode->i_last_write_time = le64_to_cpu(ni->last_data_change_time); + root->d_inode->i_last_access_time = le64_to_cpu(ni->last_access_time); + root->d_inode->i_attributes = le32_to_cpu(attributes); + root->d_inode->i_ino = ni->mft_no; + root->d_inode->i_resolved = 1; if (attributes & FILE_ATTR_REPARSE_POINT) { /* Junction point, symbolic link, or other reparse point */ @@ -639,28 +639,28 @@ static int build_dentry_tree_ntfs_recursive(struct dentry **root_p, ni, dir_ni, sd, ret); } if (ret > 0) { - root->d_inode->security_id = sd_set_add_sd(sd_set, sd, ret); - if (root->d_inode->security_id == -1) { + root->d_inode->i_security_id = sd_set_add_sd(sd_set, sd, ret); + if (root->d_inode->i_security_id == -1) { ERROR("Out of memory"); return WIMLIB_ERR_NOMEM; } DEBUG("Added security ID = %u for `%s'", - root->d_inode->security_id, path); + root->d_inode->i_security_id, path); ret = 0; } else if (ret < 0) { ERROR_WITH_ERRNO("Failed to get security information from " "`%s'", path); ret = WIMLIB_ERR_NTFS_3G; } else { - root->d_inode->security_id = -1; + root->d_inode->i_security_id = -1; DEBUG("No security ID for `%s'", path); } return ret; } -int build_dentry_tree_ntfs(struct dentry **root_p, +int build_dentry_tree_ntfs(struct wim_dentry **root_p, const char *device, - struct lookup_table *lookup_table, + struct wim_lookup_table *lookup_table, struct wim_security_data *sd, const struct capture_config *config, int add_image_flags, diff --git a/src/resource.c b/src/resource.c index 17aaabfa..3c0804b0 100644 --- a/src/resource.c +++ b/src/resource.c @@ -1,7 +1,7 @@ /* * resource.c * - * Read uncompressed and compressed metadata and file resources. + * Read uncompressed and compressed metadata and file resources from a WIM file. */ /* @@ -476,7 +476,7 @@ out: * * Returns zero on success, nonzero on failure. */ -int read_wim_resource(const struct lookup_table_entry *lte, u8 buf[], +int read_wim_resource(const struct wim_lookup_table_entry *lte, u8 buf[], size_t size, u64 offset, int flags) { int ctype; @@ -596,13 +596,19 @@ int read_wim_resource(const struct lookup_table_entry *lte, u8 buf[], * * Returns 0 on success; nonzero on failure. */ -int read_full_wim_resource(const struct lookup_table_entry *lte, u8 buf[], +int read_full_wim_resource(const struct wim_lookup_table_entry *lte, u8 buf[], int flags) { return read_wim_resource(lte, buf, wim_resource_size(lte), 0, flags); } -int extract_wim_resource(const struct lookup_table_entry *lte, +/* Extracts the first @size bytes of a WIM resource to somewhere. In the + * process, the SHA1 message digest of the resource is checked if the full + * resource is being extracted. + * + * @extract_chunk is a function that is called to extract each chunk of the + * resource. */ +int extract_wim_resource(const struct wim_lookup_table_entry *lte, u64 size, extract_chunk_func_t extract_chunk, void *extract_chunk_arg) @@ -612,16 +618,19 @@ int extract_wim_resource(const struct lookup_table_entry *lte, u64 offset = 0; int ret = 0; u8 hash[SHA1_HASH_SIZE]; - + bool check_hash = (size == wim_resource_size(lte)); SHA_CTX ctx; - sha1_init(&ctx); + + if (check_hash) + sha1_init(&ctx); while (bytes_remaining) { u64 to_read = min(bytes_remaining, sizeof(buf)); ret = read_wim_resource(lte, buf, to_read, offset, 0); if (ret != 0) return ret; - sha1_update(&ctx, buf, to_read); + if (check_hash) + sha1_update(&ctx, buf, to_read); ret = extract_chunk(buf, to_read, offset, extract_chunk_arg); if (ret != 0) { ERROR_WITH_ERRNO("Error extracting WIM resource"); @@ -630,19 +639,21 @@ int extract_wim_resource(const struct lookup_table_entry *lte, bytes_remaining -= to_read; offset += to_read; } - sha1_final(hash, &ctx); - if (!hashes_equal(hash, lte->hash)) { - #ifdef ENABLE_ERROR_MESSAGES - ERROR("Invalid checksum on the following WIM resource:"); - print_lookup_table_entry(lte); - #endif - return WIMLIB_ERR_INVALID_RESOURCE_HASH; + if (check_hash) { + sha1_final(hash, &ctx); + if (!hashes_equal(hash, lte->hash)) { + #ifdef ENABLE_ERROR_MESSAGES + ERROR("Invalid checksum on the following WIM resource:"); + print_lookup_table_entry(lte); + #endif + return WIMLIB_ERR_INVALID_RESOURCE_HASH; + } } return 0; } -/* Write @n bytes from @buf to the file descriptor @fd, retrying on interupt and - * on short writes. +/* Write @n bytes from @buf to the file descriptor @fd, retrying on internupt + * and on short writes. * * Returns short count and set errno on failure. */ static ssize_t full_write(int fd, const void *buf, size_t n) @@ -665,8 +676,7 @@ static ssize_t full_write(int fd, const void *buf, size_t n) return total; } -int extract_wim_chunk_to_fd(const u8 *buf, size_t len, - u64 offset, void *arg) +int extract_wim_chunk_to_fd(const u8 *buf, size_t len, u64 offset, void *arg) { int fd = *(int*)arg; ssize_t ret = full_write(fd, buf, len); @@ -685,8 +695,10 @@ int extract_wim_chunk_to_fd(const u8 *buf, size_t len, * * The output_resource_entry, out_refcnt, and part_number fields of @lte are * updated. + * + * (This function is confusing and should be refactored somehow.) */ -int copy_resource(struct lookup_table_entry *lte, void *wim) +int copy_resource(struct wim_lookup_table_entry *lte, void *wim) { WIMStruct *w = wim; int ret; diff --git a/src/security.c b/src/security.c index c084258e..dd9d1d82 100644 --- a/src/security.c +++ b/src/security.c @@ -1,9 +1,7 @@ /* * security.c * - * Read and write the WIM security data. The security data is a table of - * security descriptors. Each WIM image has its own security data, but it's - * possible that an image's security data have no security descriptors. + * Read and write the per-WIM-image table of security descriptors. */ /* @@ -57,7 +55,7 @@ static void empty_sacl_fixup(u8 *descr, u64 *size_p) * * @metadata_resource: An array that contains the uncompressed metadata * resource for the WIM file. - * @metadata_resource_len: The length of @metadata_resource. It MUST be at + * @metadata_resource_len: The length of @metadata_resource. It must be at * least 8 bytes. * @sd_p: A pointer to a pointer to a wim_security_data structure that * will be filled in with a pointer to a new wim_security_data @@ -74,6 +72,8 @@ int read_security_data(const u8 metadata_resource[], u64 metadata_resource_len, int ret; u64 total_len; + wimlib_assert(metadata_resource_len >= 8); + /* * Sorry this function is excessively complicated--- I'm just being * extremely careful about integer overflows. @@ -121,7 +121,9 @@ int read_security_data(const u8 metadata_resource[], u64 metadata_resource_len, sd->num_entries, sd->total_length); if (sd->num_entries == 0) { - /* No security descriptors. */ + /* No security descriptors. We allow the total_length field to + * be either 8 (which is correct, since there are always 2 + * 32-bit integers) or 0. */ if (sd->total_length != 0 && sd->total_length != 8) { ERROR("Invalid security data length (%u): expected 0 or 8", sd->total_length); @@ -135,14 +137,11 @@ int read_security_data(const u8 metadata_resource[], u64 metadata_resource_len, u64 size_no_descriptors = 8 + sizes_size; if (size_no_descriptors > (u64)sd->total_length) { ERROR("Security data total length of %u is too short because " - "there must be at least %"PRIu64" bytes of security data", + "there seem to be at least %"PRIu64" bytes of security data", sd->total_length, 8 + sizes_size); goto out_invalid_sd; } - if (sizeof(size_t) < 8 && sizes_size > 0xffffffff) { - ERROR("Too many security descriptors!"); - goto out_invalid_sd; - } + sd->sizes = MALLOC(sizes_size); if (!sd->sizes) { ret = WIMLIB_ERR_NOMEM; @@ -174,14 +173,15 @@ int read_security_data(const u8 metadata_resource[], u64 metadata_resource_len, goto out_invalid_sd; } total_len += sd->sizes[i]; - /* This check assures that the descriptor size fits in a 32 bit + /* This check ensures that the descriptor size fits in a 32 bit * integer. Because if it didn't, the total length would come * out bigger than sd->total_length, which is a 32 bit integer. * */ if (total_len > (u64)sd->total_length) { ERROR("Security data total length of %u is too short " - "because there are at least %"PRIu64" bytes of " - "security data", sd->total_length, total_len); + "because there seem to be at least %"PRIu64" " + "bytes of security data", + sd->total_length, total_len); goto out_invalid_sd; } sd->descriptors[i] = MALLOC(sd->sizes[i]); diff --git a/src/sha1.c b/src/sha1.c index 05c4ab89..5af92568 100644 --- a/src/sha1.c +++ b/src/sha1.c @@ -222,9 +222,8 @@ static int sha1_stream(FILE *fp, u8 md[SHA1_HASH_SIZE]) } -/* Calculates the SHA1 message digest given the name of a file. @md must point - * to a buffer of length 20 bytes into which the message digest is written. - */ +/* Calculates the SHA1 message digest of a file. @md must point to a buffer of + * length 20 bytes into which the message digest is written. */ int sha1sum(const char *filename, u8 md[SHA1_HASH_SIZE]) { FILE *fp; diff --git a/src/split.c b/src/split.c index 59aedf79..17a6ced6 100644 --- a/src/split.c +++ b/src/split.c @@ -47,7 +47,7 @@ static int finish_swm(WIMStruct *w, struct list_head *lte_list, { off_t lookup_table_offset = ftello(w->out_fp); int ret; - struct lookup_table_entry *lte; + struct wim_lookup_table_entry *lte; list_for_each_entry(lte, lte_list, staging_list) { ret = write_lookup_table_entry(lte, w->out_fp); @@ -70,7 +70,7 @@ static int finish_swm(WIMStruct *w, struct list_head *lte_list, progress_func); } -static int copy_resource_to_swm(struct lookup_table_entry *lte, void *__args) +static int copy_resource_to_swm(struct wim_lookup_table_entry *lte, void *__args) { struct split_args *args = (struct split_args*)__args; WIMStruct *w = args->w; @@ -121,8 +121,8 @@ static int copy_resource_to_swm(struct lookup_table_entry *lte, void *__args) return copy_resource(lte, w); } -/* Splits the WIM file @wimfile into multiple parts prefixed by @swm_name with - * size at most @part_size. */ +/* Splits the WIM file @w into multiple parts prefixed by @swm_name with size at + * most @part_size bytes. */ WIMLIBAPI int wimlib_split(WIMStruct *w, const char *swm_name, size_t part_size, int write_flags, wimlib_progress_func_t progress_func) @@ -186,7 +186,7 @@ WIMLIBAPI int wimlib_split(WIMStruct *w, const char *swm_name, w->write_metadata = true; for (int i = 0; i < w->hdr.image_count; i++) { - struct lookup_table_entry *metadata_lte; + struct wim_lookup_table_entry *metadata_lte; metadata_lte = w->image_metadata[i].metadata_lte; ret = copy_resource(metadata_lte, w); if (ret != 0) @@ -212,8 +212,8 @@ WIMLIBAPI int wimlib_split(WIMStruct *w, const char *swm_name, } /* The swms are all ready now, except the total_parts and part_number - * fields in their headers are wrong (we don't know the total parts - * until they are all written). Fix them. */ + * fields in their headers are wrong (since we don't know the total + * parts until they are all written). Fix them. */ int total_parts = args.cur_part_number; for (int i = 1; i <= total_parts; i++) { const char *part_name; @@ -236,8 +236,9 @@ WIMLIBAPI int wimlib_split(WIMStruct *w, const char *swm_name, put_u16(&buf[2], total_parts); if (fseek(fp, 40, SEEK_SET) != 0 || - fwrite(buf, 1, sizeof(buf), fp) != sizeof(buf) - || fclose(fp) != 0) { + fwrite(buf, 1, sizeof(buf), fp) != sizeof(buf) || + fclose(fp) != 0) + { ERROR_WITH_ERRNO("Error overwriting header of `%s'", part_name); ret = WIMLIB_ERR_WRITE; diff --git a/src/symlink.c b/src/symlink.c index ccdd6f59..b0f03f06 100644 --- a/src/symlink.c +++ b/src/symlink.c @@ -32,10 +32,13 @@ /* * Find the symlink target of a symbolic link or junction point in the WIM. * - * See http://msdn.microsoft.com/en-us/library/cc232006(v=prot.10).aspx - * Except the first 8 bytes aren't included in the resource (presumably because - * we already know the reparse tag from the dentry, and we already know the - * reparse tag len from the lookup table entry resource length). + * See http://msdn.microsoft.com/en-us/library/cc232006(v=prot.10).aspx for a + * description of the format of the so-called "reparse point data buffers". + * + * But, in the WIM format, the first 8 bytes of the reparse point data buffer + * are omitted, presumably because we already know the reparse tag from the + * dentry, and we already know the reparse tag length from the lookup table + * entry resource length. */ static ssize_t get_symlink_name(const u8 *resource, size_t resource_len, char *buf, size_t buf_len, @@ -65,12 +68,6 @@ static ssize_t get_symlink_name(const u8 *resource, size_t resource_len, wimlib_assert(reparse_tag == WIM_IO_REPARSE_TAG_SYMLINK || reparse_tag == WIM_IO_REPARSE_TAG_MOUNT_POINT); - /* I think that some junction points incorrectly get marked as symbolic - * links. So, parse the link buffer as a symlink if the flags seem - * plausible. */ - if (flags <= 1) - reparse_tag = WIM_IO_REPARSE_TAG_SYMLINK; - if (reparse_tag == WIM_IO_REPARSE_TAG_MOUNT_POINT) { header_size = 8; } else { @@ -168,14 +165,14 @@ static int make_symlink_reparse_data_buf(const char *symlink_target, return ret; } -/* Get the symlink target from a dentry. +/* Get the symlink target from a WIM inode. * - * The dentry may be either "real" symlink or a junction point. + * The inode may be either "real" symlink or a junction point. */ -ssize_t inode_readlink(const struct inode *inode, char *buf, size_t buf_len, +ssize_t inode_readlink(const struct wim_inode *inode, char *buf, size_t buf_len, const WIMStruct *w, int read_resource_flags) { - const struct lookup_table_entry *lte; + const struct wim_lookup_table_entry *lte; int ret; wimlib_assert(inode_is_symlink(inode)); @@ -192,7 +189,7 @@ ssize_t inode_readlink(const struct inode *inode, char *buf, size_t buf_len, if (ret != 0) return -EIO; return get_symlink_name(res_buf, wim_resource_size(lte), buf, - buf_len, inode->reparse_tag); + buf_len, inode->i_reparse_tag); } /* @@ -206,14 +203,14 @@ ssize_t inode_readlink(const struct inode *inode, char *buf, size_t buf_len, * * On failure @dentry and @lookup_table are not modified. */ -int inode_set_symlink(struct inode *inode, const char *target, - struct lookup_table *lookup_table, - struct lookup_table_entry **lte_ret) +int inode_set_symlink(struct wim_inode *inode, const char *target, + struct wim_lookup_table *lookup_table, + struct wim_lookup_table_entry **lte_ret) { int ret; size_t symlink_buf_len; - struct lookup_table_entry *lte = NULL, *existing_lte; + struct wim_lookup_table_entry *lte = NULL, *existing_lte; u8 symlink_buf_hash[SHA1_HASH_SIZE]; void *symlink_buf; @@ -247,8 +244,8 @@ int inode_set_symlink(struct inode *inode, const char *target, copy_hash(lte->hash, symlink_buf_hash); } - inode->lte = lte; - inode->resolved = true; + inode->i_lte = lte; + inode->i_resolved = 1; DEBUG("Loaded symlink buf"); diff --git a/src/verify.c b/src/verify.c index a4527feb..6602832a 100644 --- a/src/verify.c +++ b/src/verify.c @@ -30,30 +30,23 @@ #include "dentry.h" #include "lookup_table.h" -static inline struct dentry *inode_first_dentry(struct inode *inode) +static int verify_inode(struct wim_inode *inode, const WIMStruct *w) { - wimlib_assert(inode->dentry_list.next != &inode->dentry_list); - return container_of(inode->dentry_list.next, struct dentry, - inode_dentry_list); -} - -static int verify_inode(struct inode *inode, const WIMStruct *w) -{ - const struct lookup_table *table = w->lookup_table; + const struct wim_lookup_table *table = w->lookup_table; const struct wim_security_data *sd = wim_const_security_data(w); - const struct dentry *first_dentry = inode_first_dentry(inode); + const struct wim_dentry *first_dentry = inode_first_dentry(inode); int ret = WIMLIB_ERR_INVALID_DENTRY; /* Check the security ID */ - if (inode->security_id < -1) { + if (inode->i_security_id < -1) { ERROR("Dentry `%s' has an invalid security ID (%d)", - first_dentry->full_path_utf8, inode->security_id); + first_dentry->full_path_utf8, inode->i_security_id); goto out; } - if (inode->security_id >= sd->num_entries) { + if (inode->i_security_id >= sd->num_entries) { ERROR("Dentry `%s' has an invalid security ID (%d) " "(there are only %u entries in the security table)", - first_dentry->full_path_utf8, inode->security_id, + first_dentry->full_path_utf8, inode->i_security_id, sd->num_entries); goto out; } @@ -62,8 +55,8 @@ static int verify_inode(struct inode *inode, const WIMStruct *w) * if the SHA1 message digest is all 0's, which indicates there is * intentionally no resource there. */ if (w->hdr.total_parts == 1) { - for (unsigned i = 0; i <= inode->num_ads; i++) { - struct lookup_table_entry *lte; + for (unsigned i = 0; i <= inode->i_num_ads; i++) { + struct wim_lookup_table_entry *lte; const u8 *hash; hash = inode_stream_hash_unresolved(inode, i); lte = __lookup_resource(table, hash); @@ -73,7 +66,7 @@ static int verify_inode(struct inode *inode, const WIMStruct *w) goto out; } if (lte) - lte->real_refcnt += inode->link_count; + lte->real_refcnt += inode->i_nlink; /* The following is now done when required by * wim_run_full_verifications(). */ @@ -117,10 +110,10 @@ static int verify_inode(struct inode *inode, const WIMStruct *w) /* Make sure there is only one un-named stream. */ unsigned num_unnamed_streams = 0; - for (unsigned i = 0; i <= inode->num_ads; i++) { + for (unsigned i = 0; i <= inode->i_num_ads; i++) { const u8 *hash; hash = inode_stream_hash_unresolved(inode, i); - if (!inode_stream_name_len(inode, i) && !is_zero_hash(hash)) + if (inode_stream_name_len(inode, i) == 0 && !is_zero_hash(hash)) num_unnamed_streams++; } if (num_unnamed_streams > 1) { @@ -128,18 +121,18 @@ static int verify_inode(struct inode *inode, const WIMStruct *w) first_dentry->full_path_utf8, num_unnamed_streams); goto out; } - inode->verified = true; + inode->i_verified = 1; ret = 0; out: return ret; } /* Run some miscellaneous verifications on a WIM dentry */ -int verify_dentry(struct dentry *dentry, void *wim) +int verify_dentry(struct wim_dentry *dentry, void *wim) { int ret; - if (!dentry->d_inode->verified) { + if (!dentry->d_inode->i_verified) { ret = verify_inode(dentry->d_inode, wim); if (ret != 0) return ret; @@ -163,8 +156,8 @@ int verify_dentry(struct dentry *dentry, void *wim) #if 0 /* Check timestamps */ - if (inode->last_access_time < inode->creation_time || - inode->last_write_time < inode->creation_time) { + if (inode->i_last_access_time < inode->i_creation_time || + inode->i_last_write_time < inode->i_creation_time) { WARNING("Dentry `%s' was created after it was last accessed or " "written to", dentry->full_path_utf8); } @@ -178,7 +171,7 @@ static int image_run_full_verifications(WIMStruct *w) return for_dentry_in_tree(wim_root_dentry(w), verify_dentry, w); } -static int lte_fix_refcnt(struct lookup_table_entry *lte, void *ctr) +static int lte_fix_refcnt(struct wim_lookup_table_entry *lte, void *ctr) { if (lte->refcnt != lte->real_refcnt) { WARNING("The following lookup table entry has a reference " @@ -228,8 +221,8 @@ int wim_run_full_verifications(WIMStruct *w) } /* - * Sanity checks to make sure a set of WIMs correctly correspond to a spanned - * set. + * verify_swm_set: - Sanity checks to make sure a set of WIMs correctly + * correspond to a spanned set. * * @w: * Part 1 of the set. diff --git a/src/wim.c b/src/wim.c index 72b03c0e..89b0156c 100644 --- a/src/wim.c +++ b/src/wim.c @@ -1,5 +1,5 @@ /* - * wim.c + * wim.c - Stuff that doesn't fit into any other file */ /* @@ -123,7 +123,7 @@ static int sort_image_metadata_by_position(const void *p1, const void *p2) * If @lte points to a metadata resource, append it to the list of metadata * resources in the WIMStruct. Otherwise, do nothing. */ -static int append_metadata_resource_entry(struct lookup_table_entry *lte, +static int append_metadata_resource_entry(struct wim_lookup_table_entry *lte, void *wim_p) { WIMStruct *w = wim_p; @@ -168,7 +168,7 @@ static int wim_hdr_flags_compression_type(int wim_hdr_flags) WIMLIBAPI int wimlib_create_new_wim(int ctype, WIMStruct **w_ret) { WIMStruct *w; - struct lookup_table *table; + struct wim_lookup_table *table; int ret; DEBUG("Creating new WIM with %s compression.", @@ -580,7 +580,7 @@ WIMLIBAPI int wimlib_open_wim(const char *wim_file, int open_flags, } void destroy_image_metadata(struct image_metadata *imd, - struct lookup_table *table) + struct wim_lookup_table *table) { free_dentry_tree(imd->root_dentry, table); free_security_data(imd->security_data); diff --git a/src/wimlib_internal.h b/src/wimlib_internal.h index 99b2a5aa..0f65a12d 100644 --- a/src/wimlib_internal.h +++ b/src/wimlib_internal.h @@ -53,8 +53,8 @@ struct stat; -struct dentry; -struct inode; +struct wim_dentry; +struct wim_inode; #define WIM_MAGIC_LEN 8 #define WIM_GID_LEN 16 @@ -239,19 +239,19 @@ struct wim_security_data { u32 refcnt; }; -struct inode_table; +struct wim_inode_table; /* Metadata resource for an image. */ struct image_metadata { /* Pointer to the root dentry for the image. */ - struct dentry *root_dentry; + struct wim_dentry *root_dentry; /* Pointer to the security data for the image. */ struct wim_security_data *security_data; /* A pointer to the lookup table entry for this image's metadata * resource. */ - struct lookup_table_entry *metadata_lte; + struct wim_lookup_table_entry *metadata_lte; /* Linked list of inodes for this image. */ struct hlist_head inode_list; @@ -285,7 +285,7 @@ struct WIMStruct { char *filename; /* The lookup table for the WIM file. */ - struct lookup_table *lookup_table; + struct wim_lookup_table *lookup_table; /* Pointer to the XML data read from the WIM file. */ u8 *xml_data; @@ -322,7 +322,7 @@ struct WIMStruct { /* Inline utility functions for WIMStructs. */ -static inline struct dentry *wim_root_dentry(WIMStruct *w) +static inline struct wim_dentry *wim_root_dentry(WIMStruct *w) { return w->image_metadata[w->current_image - 1].root_dentry; } @@ -370,7 +370,7 @@ struct capture_config { extern bool exclude_path(const char *path, const struct capture_config *config, bool exclude_prefix); -extern int add_new_dentry_tree(WIMStruct *dest_wim, struct dentry *root, +extern int add_new_dentry_tree(WIMStruct *dest_wim, struct wim_dentry *root, struct wim_security_data *sd); /* extract_image.c */ @@ -384,7 +384,7 @@ extern int add_new_dentry_tree(WIMStruct *dest_wim, struct dentry *root, extern u64 assign_inode_numbers(struct hlist_head *inode_list); -extern int dentry_tree_fix_inodes(struct dentry *root, +extern int dentry_tree_fix_inodes(struct wim_dentry *root, struct hlist_head *inode_list); /* header.c */ @@ -412,7 +412,7 @@ extern int check_wim_integrity(WIMStruct *w, extern int new_joined_lookup_table(WIMStruct *w, WIMStruct **additional_swms, unsigned num_additional_swms, - struct lookup_table **table_ret); + struct wim_lookup_table **table_ret); /* metadata_resource.c */ @@ -434,16 +434,16 @@ struct apply_args { #endif struct list_head empty_files; wimlib_progress_func_t progress_func; - int (*apply_dentry)(struct dentry *, void *); + int (*apply_dentry)(struct wim_dentry *, void *); }; -extern int apply_dentry_ntfs(struct dentry *dentry, void *arg); -extern int apply_dentry_timestamps_ntfs(struct dentry *dentry, void *arg); +extern int apply_dentry_ntfs(struct wim_dentry *dentry, void *arg); +extern int apply_dentry_timestamps_ntfs(struct wim_dentry *dentry, void *arg); /* ntfs-capture.c */ -extern int build_dentry_tree_ntfs(struct dentry **root_p, +extern int build_dentry_tree_ntfs(struct wim_dentry **root_p, const char *device, - struct lookup_table *lookup_table, + struct wim_lookup_table *lookup_table, struct wim_security_data *sd, const struct capture_config *config, int add_image_flags, @@ -461,13 +461,13 @@ extern u8 *put_resource_entry(u8 *p, const struct resource_entry *entry); extern int read_uncompressed_resource(FILE *fp, u64 offset, u64 size, u8 buf[]); -extern int read_wim_resource(const struct lookup_table_entry *lte, u8 buf[], +extern int read_wim_resource(const struct wim_lookup_table_entry *lte, u8 buf[], size_t size, u64 offset, int flags); -extern int read_full_wim_resource(const struct lookup_table_entry *lte, +extern int read_full_wim_resource(const struct wim_lookup_table_entry *lte, u8 buf[], int flags); -extern int write_wim_resource(struct lookup_table_entry *lte, +extern int write_wim_resource(struct wim_lookup_table_entry *lte, FILE *out_fp, int out_ctype, struct resource_entry *out_res_entry, int flags); @@ -478,7 +478,7 @@ typedef int (*extract_chunk_func_t)(const u8 *, size_t, u64, void *); extern int extract_wim_chunk_to_fd(const u8 *buf, size_t len, u64 offset, void *arg); -extern int extract_wim_resource(const struct lookup_table_entry *lte, +extern int extract_wim_resource(const struct wim_lookup_table_entry *lte, u64 size, extract_chunk_func_t extract_chunk, void *extract_chunk_arg); /* @@ -488,7 +488,7 @@ extern int extract_wim_resource(const struct lookup_table_entry *lte, * Returns 0 on success; nonzero on failure. */ static inline int -extract_wim_resource_to_fd(const struct lookup_table_entry *lte, +extract_wim_resource_to_fd(const struct wim_lookup_table_entry *lte, int fd, u64 size) { return extract_wim_resource(lte, size, @@ -496,8 +496,8 @@ extract_wim_resource_to_fd(const struct lookup_table_entry *lte, } -extern int write_dentry_resources(struct dentry *dentry, void *wim_p); -extern int copy_resource(struct lookup_table_entry *lte, void *w); +extern int write_dentry_resources(struct wim_dentry *dentry, void *wim_p); +extern int copy_resource(struct wim_lookup_table_entry *lte, void *w); /* security.c */ @@ -509,15 +509,15 @@ extern u8 *write_security_data(const struct wim_security_data *sd, u8 *p); extern void free_security_data(struct wim_security_data *sd); /* symlink.c */ -ssize_t inode_readlink(const struct inode *inode, char *buf, size_t buf_len, +ssize_t inode_readlink(const struct wim_inode *inode, char *buf, size_t buf_len, const WIMStruct *w, int read_resource_flags); -extern int inode_set_symlink(struct inode *inode, +extern int inode_set_symlink(struct wim_inode *inode, const char *target, - struct lookup_table *lookup_table, - struct lookup_table_entry **lte_ret); + struct wim_lookup_table *lookup_table, + struct wim_lookup_table_entry **lte_ret); /* verify.c */ -extern int verify_dentry(struct dentry *dentry, void *wim); +extern int verify_dentry(struct wim_dentry *dentry, void *wim); extern int wim_run_full_verifications(WIMStruct *w); extern int verify_swm_set(WIMStruct *w, WIMStruct **additional_swms, @@ -527,7 +527,7 @@ extern int verify_swm_set(WIMStruct *w, extern int select_wim_image(WIMStruct *w, int image); extern int for_image(WIMStruct *w, int image, int (*visitor)(WIMStruct *)); extern void destroy_image_metadata(struct image_metadata *imd, - struct lookup_table *lt); + struct wim_lookup_table *lt); /* write.c */ diff --git a/src/write.c b/src/write.c index a431871b..777fa2c0 100644 --- a/src/write.c +++ b/src/write.c @@ -98,7 +98,7 @@ struct chunk_table { * output file. */ static int -begin_wim_resource_chunk_tab(const struct lookup_table_entry *lte, +begin_wim_resource_chunk_tab(const struct wim_lookup_table_entry *lte, FILE *out_fp, off_t file_offset, struct chunk_table **chunk_tab_ret) @@ -250,7 +250,7 @@ finish_wim_resource_chunk_tab(struct chunk_table *chunk_tab, /* Prepare for multiple reads to a resource by caching a FILE * or NTFS * attribute pointer in the lookup table entry. */ -static int prepare_resource_for_read(struct lookup_table_entry *lte +static int prepare_resource_for_read(struct wim_lookup_table_entry *lte #ifdef WITH_NTFS_3G , ntfs_inode **ni_ret @@ -299,7 +299,7 @@ static int prepare_resource_for_read(struct lookup_table_entry *lte /* Undo prepare_resource_for_read() by closing the cached FILE * or NTFS * attribute. */ -static void end_wim_resource_read(struct lookup_table_entry *lte +static void end_wim_resource_read(struct wim_lookup_table_entry *lte #ifdef WITH_NTFS_3G , ntfs_inode *ni #endif @@ -323,7 +323,7 @@ static void end_wim_resource_read(struct lookup_table_entry *lte } static int -write_uncompressed_resource_and_truncate(struct lookup_table_entry *lte, +write_uncompressed_resource_and_truncate(struct wim_lookup_table_entry *lte, FILE *out_fp, off_t file_offset, struct resource_entry *out_res_entry) @@ -364,7 +364,7 @@ write_uncompressed_resource_and_truncate(struct lookup_table_entry *lte, * * Returns 0 on success; nonzero on failure. */ -int write_wim_resource(struct lookup_table_entry *lte, +int write_wim_resource(struct wim_lookup_table_entry *lte, FILE *out_fp, int out_ctype, struct resource_entry *out_res_entry, int flags) @@ -626,7 +626,7 @@ struct compressor_thread_params { #define MAX_CHUNKS_PER_MSG 2 struct message { - struct lookup_table_entry *lte; + struct wim_lookup_table_entry *lte; u8 *uncompressed_chunks[MAX_CHUNKS_PER_MSG]; u8 *out_compressed_chunks[MAX_CHUNKS_PER_MSG]; u8 *compressed_chunks[MAX_CHUNKS_PER_MSG]; @@ -686,7 +686,7 @@ static int do_write_stream_list(struct list_head *my_resources, int write_resource_flags) { int ret; - struct lookup_table_entry *lte, *tmp; + struct wim_lookup_table_entry *lte, *tmp; list_for_each_entry_safe(lte, tmp, my_resources, staging_list) { ret = write_wim_resource(lte, @@ -777,7 +777,7 @@ static int main_writer_thread_proc(struct list_head *stream_list, int ret; struct chunk_table *cur_chunk_tab = NULL; struct message *msgs = CALLOC(num_messages, sizeof(struct message)); - struct lookup_table_entry *next_lte = NULL; + struct wim_lookup_table_entry *next_lte = NULL; // Initially, all the messages are available to use. LIST_HEAD(available_msgs); @@ -818,7 +818,7 @@ static int main_writer_thread_proc(struct list_head *stream_list, // list and written directly by the main thread. LIST_HEAD(my_resources); - struct lookup_table_entry *cur_lte = NULL; + struct wim_lookup_table_entry *cur_lte = NULL; struct message *msg; #ifdef WITH_NTFS_3G @@ -908,7 +908,7 @@ static int main_writer_thread_proc(struct list_head *stream_list, break; } next_lte = container_of(next_resource, - struct lookup_table_entry, + struct wim_lookup_table_entry, staging_list); next_resource = next_resource->next; if ((!(write_flags & WIMLIB_WRITE_FLAG_RECOMPRESS) @@ -1113,7 +1113,7 @@ static int main_writer_thread_proc(struct list_head *stream_list, cur_lte = NULL; else cur_lte = container_of(cur_lte->staging_list.next, - struct lookup_table_entry, + struct wim_lookup_table_entry, staging_list); // Since we just finished writing a stream, @@ -1297,7 +1297,7 @@ static int write_stream_list(struct list_head *stream_list, FILE *out_fp, unsigned num_threads, wimlib_progress_func_t progress_func) { - struct lookup_table_entry *lte; + struct wim_lookup_table_entry *lte; size_t num_streams = 0; u64 total_bytes = 0; u64 total_compression_bytes = 0; @@ -1345,7 +1345,7 @@ struct lte_overwrite_prepare_args { struct list_head *stream_list; }; -static int lte_overwrite_prepare(struct lookup_table_entry *lte, void *arg) +static int lte_overwrite_prepare(struct wim_lookup_table_entry *lte, void *arg) { struct lte_overwrite_prepare_args *args = arg; @@ -1382,17 +1382,17 @@ static int wim_find_new_streams(WIMStruct *wim, off_t end_offset, lte_overwrite_prepare, &args); } -static int inode_find_streams_to_write(struct inode *inode, - struct lookup_table *table, +static int inode_find_streams_to_write(struct wim_inode *inode, + struct wim_lookup_table *table, struct list_head *stream_list) { - struct lookup_table_entry *lte; - for (unsigned i = 0; i <= inode->num_ads; i++) { + struct wim_lookup_table_entry *lte; + for (unsigned i = 0; i <= inode->i_num_ads; i++) { lte = inode_stream_lte(inode, i, table); if (lte) { if (lte->out_refcnt == 0) list_add_tail(<e->staging_list, stream_list); - lte->out_refcnt += inode->link_count; + lte->out_refcnt += inode->i_nlink; } } return 0; @@ -1400,12 +1400,12 @@ static int inode_find_streams_to_write(struct inode *inode, static int image_find_streams_to_write(WIMStruct *w) { - struct inode *inode; + struct wim_inode *inode; struct hlist_node *cur; struct hlist_head *inode_list; inode_list = &wim_get_current_image_metadata(w)->inode_list; - hlist_for_each_entry(inode, cur, inode_list, hlist) { + hlist_for_each_entry(inode, cur, inode_list, i_hlist) { inode_find_streams_to_write(inode, w->lookup_table, (struct list_head*)w->private); } diff --git a/src/xml.c b/src/xml.c index 9fbe259f..ca2ec3e7 100644 --- a/src/xml.c +++ b/src/xml.c @@ -79,7 +79,7 @@ struct image_info { char *display_description; union { char *flags; - struct lookup_table *lookup_table; + struct wim_lookup_table *lookup_table; }; }; @@ -988,12 +988,12 @@ void xml_set_memory_allocator(void *(*malloc_func)(size_t), } #endif -static int calculate_dentry_statistics(struct dentry *dentry, void *arg) +static int calculate_dentry_statistics(struct wim_dentry *dentry, void *arg) { struct image_info *info = arg; - struct lookup_table *lookup_table = info->lookup_table; - const struct inode *inode = dentry->d_inode; - struct lookup_table_entry *lte; + struct wim_lookup_table *lookup_table = info->lookup_table; + const struct wim_inode *inode = dentry->d_inode; + struct wim_lookup_table_entry *lte; /* Update directory count and file count. * @@ -1045,12 +1045,12 @@ static int calculate_dentry_statistics(struct dentry *dentry, void *arg) info->hard_link_bytes += wim_resource_size(lte); } - if (inode->link_count >= 2 && dentry_is_first_in_inode(dentry)) { - for (unsigned i = 0; i < inode->num_ads; i++) { - if (inode->ads_entries[i].stream_name_len) { + if (inode->i_nlink >= 2 && dentry_is_first_in_inode(dentry)) { + for (unsigned i = 0; i < inode->i_num_ads; i++) { + if (inode->i_ads_entries[i].stream_name_len) { lte = inode_stream_lte(inode, i + 1, lookup_table); if (lte) { - info->hard_link_bytes += inode->link_count * + info->hard_link_bytes += inode->i_nlink * wim_resource_size(lte); } } -- 2.43.0