Am 15.10.2015 um 00:07 schrieb David Turner:
From: Keith McGuigan <kmcguigan@xxxxxxxxxxx> During merges, we would previously free entries that we no longer need in the destination index. But those entries might also be stored in the dir_entry cache, and when a later call to add_to_index found them, they would be used after being freed. To prevent this, add a ref count for struct cache_entry. Whenever a cache entry is added to a data structure, the ref count is incremented; when it is removed from the data structure, it is decremented. When it hits zero, the cache_entry is freed. Signed-off-by: Keith McGuigan <kmcguigan@xxxxxxxxxxx> Signed-off-by: David Turner <dturner@xxxxxxxxxxxxxxxx> --- Fix type of ref_count (from unsigned int to int). cache.h | 27 +++++++++++++++++++++++++++ name-hash.c | 7 ++++++- read-cache.c | 6 +++++- split-index.c | 13 ++++++++----- unpack-trees.c | 6 ++++-- 5 files changed, 50 insertions(+), 9 deletions(-) diff --git a/cache.h b/cache.h index 752031e..7906026 100644 --- a/cache.h +++ b/cache.h @@ -149,6 +149,7 @@ struct stat_data { struct cache_entry { struct hashmap_entry ent; + int ref_count; /* count the number of refs to this in dir_hash */ struct stat_data ce_stat_data; unsigned int ce_mode; unsigned int ce_flags; @@ -213,6 +214,32 @@ struct cache_entry { struct pathspec; /* + * Increment the cache_entry reference count. Should be called + * whenever a pointer to a cache_entry is retained in a data structure, + * thus marking it as alive. + */ +static inline void add_ce_ref(struct cache_entry *ce) +{ + assert(ce != NULL && ce->ref_count >= 0); + ce->ref_count++; +} + +/* + * Decrement the cache_entry reference count. Should be called whenever + * a pointer to a cache_entry is dropped. Once the counter drops to 0 + * the cache_entry memory will be safely freed. + */ +static inline void drop_ce_ref(struct cache_entry *ce) +{ + if (ce != NULL) { + assert(ce->ref_count >= 0);
Shouldn't this be "> 0" to prevent double frees?
+ if (--ce->ref_count < 1) { + free(ce); + } + } +}
-- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html