Ugly hack
authorEric Biggers <ebiggers3@gmail.com>
Wed, 19 Dec 2012 05:08:20 +0000 (23:08 -0600)
committerEric Biggers <ebiggers3@gmail.com>
Wed, 19 Dec 2012 05:17:01 +0000 (23:17 -0600)
After exporting an image, an inode list may be shared between multiple images.
This is a fix to make deleting the inodes from the list still work when the list
head may have been freed already.

src/dentry.c
src/export_image.c
src/list.h
src/mount_image.c

index 978a825..3847fbb 100644 (file)
@@ -896,7 +896,7 @@ void free_inode(struct inode *inode)
                FREE(inode->fds);
                pthread_mutex_destroy(&inode->i_mutex);
                if (inode->hlist.pprev)
-                       hlist_del(&inode->hlist);
+                       hlist_safe_del(&inode->hlist);
        #endif
                FREE(inode->extracted_file);
                FREE(inode);
index a24950a..58d6057 100644 (file)
@@ -234,6 +234,8 @@ WIMLIBAPI int wimlib_export_image(WIMStruct *src_wim,
 
        dest_wim->image_metadata[
                dest_wim->hdr.image_count - 1].inode_list = src_imd->inode_list;
+       if (src_imd->inode_list.first)
+               src_imd->inode_list.first->pprev = NULL;
 
        /* All memory allocations have been taken care of, so it's no longer
         * possible for this function to fail.  Go ahead and increment the
index 82f08e5..ce2dad2 100644 (file)
@@ -195,6 +195,16 @@ 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;
index 69fad24..090a828 100644 (file)
@@ -2370,6 +2370,9 @@ WIMLIBAPI int wimlib_mount_image(WIMStruct *wim, int image, const char *dir,
                goto out;
        }
 
+       if (imd->inode_list.first)
+               imd->inode_list.first->pprev = &imd->inode_list.first;
+
        if (imd->modified) {
                ERROR("Cannot mount image that was added "
                      "with wimlib_add_image()");