From 2fc33f535a398ea85964c0e483c5692821d775f3 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Fri, 1 May 2015 21:51:40 -0500 Subject: [PATCH] wim_inode: Remove i_list, leaving only i_hlist --- include/wimlib/inode.h | 19 +++++-------------- include/wimlib/inode_table.h | 25 +++++++------------------ include/wimlib/metadata.h | 8 ++++++-- src/inode.c | 3 --- src/inode_fixup.c | 35 +++++++++++++++++++---------------- src/inode_table.c | 19 +++++++++---------- src/mount_image.c | 9 +++++---- src/wim.c | 4 ++-- 8 files changed, 53 insertions(+), 69 deletions(-) diff --git a/include/wimlib/inode.h b/include/wimlib/inode.h index 08ce3e91..f516a1f8 100644 --- a/include/wimlib/inode.h +++ b/include/wimlib/inode.h @@ -121,19 +121,10 @@ struct wim_inode { * i_nlink dentries in this list. */ struct list_head i_dentry; - /* Field to place this inode into a list. */ - union { - /* Hash list node- used in inode_fixup.c when the inodes are - * placed into a hash table keyed by inode number and optionally - * device number, in order to detect dentries that are aliases - * for the same inode. */ - struct hlist_node i_hlist; - - /* Normal list node- used to connect all the inodes of a WIM - * image into a single linked list referenced from the `struct - * wim_image_metadata' for that image. */ - struct list_head i_list; - }; + /* Field to place this inode into a list. While reading a WIM image or + * adding files to a WIM image this is owned by the inode table; + * otherwise this links the inodes for the WIM image. */ + struct hlist_node i_hlist; /* Number of dentries that are aliases for this inode. */ u32 i_nlink; @@ -437,6 +428,6 @@ inode_unref_blobs(struct wim_inode *inode, struct blob_table *blob_table); /* inode_fixup.c */ extern int -dentry_tree_fix_inodes(struct wim_dentry *root, struct list_head *inode_list); +dentry_tree_fix_inodes(struct wim_dentry *root, struct hlist_head *inode_list); #endif /* _WIMLIB_INODE_H */ diff --git a/include/wimlib/inode_table.h b/include/wimlib/inode_table.h index abfc28bb..01f371e0 100644 --- a/include/wimlib/inode_table.h +++ b/include/wimlib/inode_table.h @@ -6,27 +6,16 @@ struct wim_dentry; -/* Hash table to find inodes, given an inode number (in the case of reading - * a WIM images), or both an inode number and a device number (in the case of - * capturing a WIM image). */ +/* Hash table to find inodes for hard link detection, given an inode number (in + * the case of reading a WIM image), or both an inode number and a device number + * (in the case of adding files to a WIM image). Also contains an extra list to + * hold inodes for which no additional hard link detection is desired. In both + * cases the inodes are linked by i_hlist. */ struct wim_inode_table { - /* Fields for the hash table */ struct hlist_head *array; size_t num_entries; size_t capacity; - - /* - * Linked list of "extra" inodes. These may be: - * - * - inodes with link count 1, which are all allowed to have 0 for their - * inode number, meaning we cannot insert them into the hash table. - * - * - Groups we create ourselves by splitting a nominal inode due to - * inconsistencies in the dentries. These inodes will share an inode - * number with some other inode until assign_inode_numbers() is - * called. - */ - struct list_head extra_inodes; + struct hlist_head extra_inodes; }; @@ -40,7 +29,7 @@ inode_table_new_dentry(struct wim_inode_table *table, const tchar *name, extern void inode_table_prepare_inode_list(struct wim_inode_table *table, - struct list_head *head); + struct hlist_head *head); extern void destroy_inode_table(struct wim_inode_table *table); diff --git a/include/wimlib/metadata.h b/include/wimlib/metadata.h index af35b539..cb456bc4 100644 --- a/include/wimlib/metadata.h +++ b/include/wimlib/metadata.h @@ -26,7 +26,7 @@ struct wim_image_metadata { struct blob_descriptor *metadata_blob; /* Linked list of 'struct wim_inode's for this image. */ - struct list_head inode_list; + struct hlist_head inode_list; /* Linked list of 'struct blob_descriptor's for blobs that are * referenced by this image's dentry tree, but have not had their SHA-1 @@ -71,7 +71,11 @@ wim_get_current_security_data(WIMStruct *wim) /* Iterate over each inode in a WIM image */ #define image_for_each_inode(inode, imd) \ - list_for_each_entry(inode, &(imd)->inode_list, i_list) + hlist_for_each_entry(inode, &(imd)->inode_list, i_hlist) + +/* Iterate over each inode in a WIM image (safe against inode removal) */ +#define image_for_each_inode_safe(inode, tmp, imd) \ + hlist_for_each_entry_safe(inode, tmp, &(imd)->inode_list, i_hlist) /* Iterate over each blob in a WIM image that has not yet been hashed */ #define image_for_each_unhashed_blob(blob, imd) \ diff --git a/src/inode.c b/src/inode.c index 4c380bfc..6277f0c4 100644 --- a/src/inode.c +++ b/src/inode.c @@ -57,7 +57,6 @@ new_inode(struct wim_dentry *dentry, bool set_timestamps) inode->i_security_id = -1; /*inode->i_nlink = 0;*/ inode->i_not_rpfixed = 1; - INIT_LIST_HEAD(&inode->i_list); INIT_LIST_HEAD(&inode->i_dentry); inode->i_streams = inode->i_embedded_streams; if (set_timestamps) { @@ -86,8 +85,6 @@ free_inode(struct wim_inode *inode) FREE(inode->i_streams); if (inode->i_extra) FREE(inode->i_extra); - /* HACK: This may instead delete the inode from i_list, but hlist_del() - * behaves the same as list_del(). */ if (!hlist_unhashed(&inode->i_hlist)) hlist_del(&inode->i_hlist); FREE(inode); diff --git a/src/inode_fixup.c b/src/inode_fixup.c index 5e8a58af..2ece5308 100644 --- a/src/inode_fixup.c +++ b/src/inode_fixup.c @@ -67,7 +67,7 @@ inode_table_insert(struct wim_dentry *dentry, void *_params) struct wim_inode *inode; if (d_inode->i_ino == 0) { - list_add_tail(&d_inode->i_list, &table->extra_inodes); + hlist_add_head(&d_inode->i_hlist, &table->extra_inodes); return 0; } @@ -111,32 +111,35 @@ inode_table_insert(struct wim_dentry *dentry, void *_params) return 0; } +static void +hlist_move_all(struct hlist_head *src, struct hlist_head *dest) +{ + struct hlist_node *node; + + while ((node = src->first) != NULL) { + hlist_del(node); + hlist_add_head(node, dest); + } +} + /* Move the inodes from the 'struct wim_inode_table' to the 'inode_list'. */ static void build_inode_list(struct wim_inode_table *inode_table, - struct list_head *inode_list) + struct hlist_head *inode_list) { - list_splice(&inode_table->extra_inodes, inode_list); - for (size_t i = 0; i < inode_table->capacity; i++) { - while (!hlist_empty(&inode_table->array[i])) { - struct wim_inode *inode; - - inode = hlist_entry(inode_table->array[i].first, - struct wim_inode, i_hlist); - hlist_del(&inode->i_hlist); - list_add(&inode->i_list, inode_list); - } - } + hlist_move_all(&inode_table->extra_inodes, inode_list); + for (size_t i = 0; i < inode_table->capacity; i++) + hlist_move_all(&inode_table->array[i], inode_list); } /* Re-assign inode numbers to the inodes in the list. */ static void -reassign_inode_numbers(struct list_head *inode_list) +reassign_inode_numbers(struct hlist_head *inode_list) { struct wim_inode *inode; u64 cur_ino = 1; - list_for_each_entry(inode, inode_list, i_list) + hlist_for_each_entry(inode, inode_list, i_hlist) inode->i_ino = cur_ino++; } @@ -165,7 +168,7 @@ reassign_inode_numbers(struct list_head *inode_list) * i_ino fields. */ int -dentry_tree_fix_inodes(struct wim_dentry *root, struct list_head *inode_list) +dentry_tree_fix_inodes(struct wim_dentry *root, struct hlist_head *inode_list) { struct inode_fixup_params params; int ret; diff --git a/src/inode_table.c b/src/inode_table.c index 7c8626f2..86e3155f 100644 --- a/src/inode_table.c +++ b/src/inode_table.c @@ -39,7 +39,7 @@ init_inode_table(struct wim_inode_table *table, size_t capacity) return WIMLIB_ERR_NOMEM; table->num_entries = 0; table->capacity = capacity; - INIT_LIST_HEAD(&table->extra_inodes); + INIT_HLIST_HEAD(&table->extra_inodes); return 0; } @@ -99,7 +99,7 @@ inode_table_new_dentry(struct wim_inode_table *table, const tchar *name, ret = new_dentry_with_new_inode(name, false, &dentry); if (ret) return ret; - list_add_tail(&dentry->d_inode->i_list, &table->extra_inodes); + hlist_add_head(&dentry->d_inode->i_hlist, &table->extra_inodes); } else { size_t pos; @@ -136,14 +136,14 @@ inode_table_new_dentry(struct wim_inode_table *table, const tchar *name, */ void inode_table_prepare_inode_list(struct wim_inode_table *table, - struct list_head *head) + struct hlist_head *head) { - struct wim_inode *inode, *tmp_inode; + struct wim_inode *inode; struct hlist_node *tmp; u64 cur_ino = 1; /* Re-assign inode numbers in the existing list to avoid duplicates. */ - list_for_each_entry(inode, head, i_list) + hlist_for_each_entry(inode, head, i_hlist) inode->i_ino = cur_ino++; /* Assign inode numbers to the new inodes and move them to the image's @@ -152,16 +152,15 @@ inode_table_prepare_inode_list(struct wim_inode_table *table, hlist_for_each_entry_safe(inode, tmp, &table->array[i], i_hlist) { inode->i_ino = cur_ino++; inode->i_devno = 0; - list_add_tail(&inode->i_list, head); + hlist_add_head(&inode->i_hlist, head); } INIT_HLIST_HEAD(&table->array[i]); } - list_for_each_entry_safe(inode, tmp_inode, &table->extra_inodes, i_list) - { + hlist_for_each_entry_safe(inode, tmp, &table->extra_inodes, i_hlist) { inode->i_ino = cur_ino++; inode->i_devno = 0; - list_add_tail(&inode->i_list, head); + hlist_add_head(&inode->i_hlist, head); } - INIT_LIST_HEAD(&table->extra_inodes); + INIT_HLIST_HEAD(&table->extra_inodes); table->num_entries = 0; } diff --git a/src/mount_image.c b/src/mount_image.c index 3e9566b5..cc1bb5f9 100644 --- a/src/mount_image.c +++ b/src/mount_image.c @@ -502,8 +502,8 @@ create_file(struct fuse_context *fuse_ctx, const char *path, } } - list_add_tail(&new_inode->i_list, - &wim_get_current_image_metadata(wimfs_ctx->wim)->inode_list); + hlist_add_head(&new_inode->i_hlist, + &wim_get_current_image_metadata(wimfs_ctx->wim)->inode_list); dentry_add_child(parent, new_dentry); @@ -1001,12 +1001,13 @@ inode_close_fds(struct wim_inode *inode) static void close_all_fds(struct wimfs_context *ctx) { - struct wim_inode *inode, *tmp; + struct wim_inode *inode; + struct hlist_node *tmp; struct wim_image_metadata *imd; imd = wim_get_current_image_metadata(ctx->wim); - list_for_each_entry_safe(inode, tmp, &imd->inode_list, i_list) + image_for_each_inode_safe(inode, tmp, imd) inode_close_fds(inode); } diff --git a/src/wim.c b/src/wim.c index 522380f1..a82bd479 100644 --- a/src/wim.c +++ b/src/wim.c @@ -217,7 +217,7 @@ destroy_image_metadata(struct wim_image_metadata *imd, free_blob_descriptor(blob); } INIT_LIST_HEAD(&imd->unhashed_blobs); - INIT_LIST_HEAD(&imd->inode_list); + INIT_HLIST_HEAD(&imd->inode_list); #ifdef WITH_NTFS_3G if (imd->ntfs_vol) { do_ntfs_umount(imd->ntfs_vol); @@ -260,7 +260,7 @@ new_image_metadata(void) imd = CALLOC(1, sizeof(*imd)); if (imd) { imd->refcnt = 1; - INIT_LIST_HEAD(&imd->inode_list); + INIT_HLIST_HEAD(&imd->inode_list); INIT_LIST_HEAD(&imd->unhashed_blobs); } return imd; -- 2.43.0