From: Eric Biggers Date: Mon, 3 Sep 2012 14:32:51 +0000 (-0500) Subject: put_inode() fix X-Git-Tag: v1.0.2~12 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=eb066ffe5f37eae975c285cbbfc377247b0d60ff put_inode() fix --- diff --git a/src/dentry.c b/src/dentry.c index c7c5fb9b..043ceade 100644 --- a/src/dentry.c +++ b/src/dentry.c @@ -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); diff --git a/src/dentry.h b/src/dentry.h index 1e3a04bc..355c492a 100644 --- a/src/dentry.h +++ b/src/dentry.h @@ -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. diff --git a/src/extract.c b/src/extract.c index 6f4e74c9..6e01191b 100644 --- a/src/extract.c +++ b/src/extract.c @@ -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; diff --git a/src/hardlink.c b/src/hardlink.c index 87f75a87..26c9e05d 100644 --- a/src/hardlink.c +++ b/src/hardlink.c @@ -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); diff --git a/src/lookup_table.c b/src/lookup_table.c index 54b5d756..d4a1ba42 100644 --- a/src/lookup_table.c +++ b/src/lookup_table.c @@ -99,6 +99,7 @@ void free_lookup_table_entry(struct lookup_table_entry *lte) default: break; } + FREE(lte->extracted_file); FREE(lte); } } diff --git a/src/lookup_table.h b/src/lookup_table.h index ede2bfe6..f0d454a1 100644 --- a/src/lookup_table.h +++ b/src/lookup_table.h @@ -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.