From: Eric Biggers Date: Wed, 19 Dec 2012 05:08:20 +0000 (-0600) Subject: Ugly hack X-Git-Tag: v1.2.1~12 X-Git-Url: https://wimlib.net/git/?p=wimlib;a=commitdiff_plain;h=5604fa76ebf1b5589425aa3864585975624b822d Ugly hack 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. --- diff --git a/src/dentry.c b/src/dentry.c index 978a825f..3847fbb2 100644 --- a/src/dentry.c +++ b/src/dentry.c @@ -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); diff --git a/src/export_image.c b/src/export_image.c index a24950ad..58d6057a 100644 --- a/src/export_image.c +++ b/src/export_image.c @@ -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 diff --git a/src/list.h b/src/list.h index 82f08e5f..ce2dad2c 100644 --- a/src/list.h +++ b/src/list.h @@ -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; diff --git a/src/mount_image.c b/src/mount_image.c index 69fad244..090a8280 100644 --- a/src/mount_image.c +++ b/src/mount_image.c @@ -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()");