put_inode() fix
authorEric Biggers <ebiggers3@gmail.com>
Mon, 3 Sep 2012 14:32:51 +0000 (09:32 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Mon, 3 Sep 2012 14:32:51 +0000 (09:32 -0500)
src/dentry.c
src/dentry.h
src/extract.c
src/hardlink.c
src/lookup_table.c
src/lookup_table.h

index c7c5fb9b9df6f5f9fa5d93263ab652a5d187654d..043ceade5803e5690c1943940b7003015b420a14 100644 (file)
@@ -677,7 +677,7 @@ void put_inode(struct inode *inode)
 {
        if (inode) {
                wimlib_assert(inode->link_count);
-               if (--inode->link_count)
+               if (--inode->link_count == 0)
                        free_inode(inode);
        }
 }
@@ -729,6 +729,7 @@ static int do_free_dentry(struct dentry *dentry, void *__lookup_table)
        unsigned i;
 
        if (lookup_table) {
+               wimlib_assert(inode->link_count);
                for (i = 0; i <= inode->num_ads; i++) {
                        lte = inode_stream_lte(inode, i, lookup_table);
                        lte_decrement_refcnt(lte, lookup_table);
index 1e3a04bc13aba41abc8f452ba87e6607f7fe9baa..355c492a901383d0c28891ae51010ec65f665a01 100644 (file)
@@ -176,6 +176,9 @@ struct inode {
        char *extracted_file;
 };
 
+#define inode_for_each_dentry(dentry, inode) \
+               list_for_each_entry(dentry, &inode->dentry_list, inode_dentry_list)
+
 /* 
  * In-memory structure for a WIM directory entry (dentry).  There is a directory
  * tree for each image in the WIM. 
index 6f4e74c95a1007114d449e61ae50ef9be49e8df6..6e01191be028fe4bef4287ef2003a6a558a09527 100644 (file)
@@ -208,6 +208,7 @@ static int extract_regular_file(WIMStruct *w,
                        return extract_regular_file_linked(dentry, output_dir,
                                                           output_path,
                                                           extract_flags, lte);
+               FREE(lte->extracted_file);
                lte->extracted_file = STRDUP(output_path);
                if (!lte->extracted_file)
                        return WIMLIB_ERR_NOMEM;
index 87f75a872a5a6d56d87835b51111b946bd231a81..26c9e05d5e50b343c10944c74175ad048316e387 100644 (file)
@@ -151,7 +151,6 @@ u64 assign_inode_numbers(struct hlist_head *inode_list)
        struct inode *inode;
        struct hlist_node *cur;
        u64 cur_ino = 1;
-       struct dentry *dentry;
        hlist_for_each_entry(inode, cur, inode_list, hlist) {
                inode->ino = cur_ino;
                cur_ino++;
@@ -250,7 +249,7 @@ static int fix_true_inode(struct inode *inode)
        u64 last_atime = 0;
        bool found_short_name = false;
 
-       list_for_each_entry(dentry, &inode->dentry_list, inode_dentry_list) {
+       inode_for_each_dentry(dentry, inode) {
                if (!ref_dentry || ref_dentry->inode->num_ads == 0)
                        ref_dentry = dentry;
                if (dentry->short_name_len) {
@@ -274,7 +273,7 @@ static int fix_true_inode(struct inode *inode)
        ref_inode = ref_dentry->inode;
        ref_inode->link_count = 1;
 
-       list_for_each_entry(dentry, &inode->dentry_list, inode_dentry_list) {
+       inode_for_each_dentry(dentry, inode) {
                if (dentry != ref_dentry) {
                        if (!inodes_consistent(ref_inode, dentry->inode)) {
                                inconsistent_inode(dentry->inode);
@@ -325,7 +324,7 @@ fix_nominal_inode(struct inode *inode, struct hlist_head *inode_list)
         /* Create a list of dentries in the nominal inode that have at
          * 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. */
-       list_for_each_entry(dentry, &inode->dentry_list, inode_dentry_list) {
+       inode_for_each_dentry(dentry, inode) {
                for (unsigned i = 0; i <= dentry->inode->num_ads; i++) {
                        const u8 *hash;
                        hash = inode_stream_hash(dentry->inode, i);
@@ -365,8 +364,7 @@ fix_nominal_inode(struct inode *inode, struct hlist_head *inode_list)
          * these dentries for consistency with the others to form a set of true
          * inodes. */
        num_true_inodes = 0;
-       list_for_each_entry(dentry, &dentries_with_data_streams, tmp_list)
-       {
+       list_for_each_entry(dentry, &dentries_with_data_streams, tmp_list) {
                /* Look for a true inode that is consistent with
                 * this dentry and add this dentry to it.  Or, if none
                 * of the true inodes are consistent with this
@@ -404,7 +402,7 @@ next_dentry_2:
                inode = container_of(true_inodes.first,
                                     struct inode,
                                     hlist);
-               /* Assign the streamless dentries to the one and only true link
+               /* Assign the streamless dentries to the one and only true
                 * inode. */
                list_for_each_entry(dentry, &dentries_with_no_data_streams, tmp_list)
                        list_add(&dentry->inode_dentry_list, &inode->dentry_list);
@@ -412,6 +410,10 @@ next_dentry_2:
         if (num_true_inodes != 1) {
                #ifdef ENABLE_DEBUG
                {
+                       inode = container_of(true_inodes.first,
+                                            struct inode,
+                                            hlist);
+
                        printf("Split nominal inode 0x%"PRIx64" into %zu "
                               "inodes:\n",
                               inode->ino, num_true_inodes);
index 54b5d7567dc5d8b3342a270465f52c7b3f0ef22a..d4a1ba4229ddb30b4aa10b7e540cfb003fb19ac6 100644 (file)
@@ -99,6 +99,7 @@ void free_lookup_table_entry(struct lookup_table_entry *lte)
                default:
                        break;
                }
+               FREE(lte->extracted_file);
                FREE(lte);
        }
 }
index ede2bfe6fa5d7ba9be1444764f3877ad6fc95091..f0d454a18e22d6f9bb75b3952e0a58f61355110d 100644 (file)
@@ -173,23 +173,21 @@ struct lookup_table_entry {
         * dentries. */
        u32 out_refcnt;
 
-       union {
-               /* When a WIM file is written, @output_resource_entry is filled
-                * in with the resource entry for the output WIM.  This will not
-                * necessarily be the same as the @resource_entry since:
-                *      - The stream may have a different offset in the new WIM
-                *      - The stream may have a different compressed size in the
-                *      new WIM if the compression type changed
-                */
-               struct resource_entry output_resource_entry;
-
-               /* This field is used for the special hardlink or symlink image
-                * application mode.   In these mode, all identical files are
-                * linked together, and @extracted_file will be set to the
-                * filename of the first extracted file containing this stream.
-                * */
-               char *extracted_file;
-       };
+       /* When a WIM file is written, @output_resource_entry is filled
+        * in with the resource entry for the output WIM.  This will not
+        * necessarily be the same as the @resource_entry since:
+        *      - The stream may have a different offset in the new WIM
+        *      - The stream may have a different compressed size in the
+        *      new WIM if the compression type changed
+        */
+       struct resource_entry output_resource_entry;
+
+       /* This field is used for the special hardlink or symlink image
+        * application mode.   In these mode, all identical files are
+        * linked together, and @extracted_file will be set to the
+        * filename of the first extracted file containing this stream.
+        * */
+       char *extracted_file;
 
        /* Circular linked list of streams that share the same lookup table
         * entry.