wim_inode: Remove i_list, leaving only i_hlist
authorEric Biggers <ebiggers3@gmail.com>
Sat, 2 May 2015 02:51:40 +0000 (21:51 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Sat, 2 May 2015 03:13:32 +0000 (22:13 -0500)
include/wimlib/inode.h
include/wimlib/inode_table.h
include/wimlib/metadata.h
src/inode.c
src/inode_fixup.c
src/inode_table.c
src/mount_image.c
src/wim.c

index 08ce3e9..f516a1f 100644 (file)
@@ -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  */
index abfc28b..01f371e 100644 (file)
@@ -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);
index af35b53..cb456bc 100644 (file)
@@ -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) \
index 4c380bf..6277f0c 100644 (file)
@@ -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);
index 5e8a58a..2ece530 100644 (file)
@@ -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;
index 7c8626f..86e3155 100644 (file)
@@ -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;
 }
index 3e9566b..cc1bb5f 100644 (file)
@@ -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);
 }
 
index 522380f..a82bd47 100644 (file)
--- 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;