[sheepdog] [PATCH v5 8/8] object cache: add a object_list for cache entry for cache deleting

levin li levin108 at gmail.com
Fri Jul 27 14:01:22 CEST 2012


From: levin li <xingke.lwp at taobao.com>

When deleting an entire VDI cache, a object list is easy for traversing
comparing to a rb-tree

Signed-off-by: levin li <xingke.lwp at taobao.com>
---
 sheep/object_cache.c |   55 +++++++++++++++++++++++++++++--------------------
 1 files changed, 32 insertions(+), 23 deletions(-)

diff --git a/sheep/object_cache.c b/sheep/object_cache.c
index 51837ee..1f3e631 100644
--- a/sheep/object_cache.c
+++ b/sheep/object_cache.c
@@ -60,6 +60,7 @@ struct object_cache {
 	struct hlist_node hash;
 
 	struct list_head dirty_list;
+	struct list_head object_list;
 	struct rb_root dirty_tree;
 	struct rb_root object_tree;
 
@@ -74,7 +75,8 @@ struct object_cache_entry {
 	struct rb_node node;
 	struct rb_node dirty_node;
 	struct object_cache *oc;
-	struct list_head list;
+	struct list_head dirty_list;
+	struct list_head object_list;
 	struct cds_list_head lru_list;
 };
 
@@ -195,7 +197,7 @@ del_from_dirty_tree_and_list(struct object_cache_entry *entry,
 			     struct rb_root *dirty_tree)
 {
 	rb_erase(&entry->dirty_node, dirty_tree);
-	list_del_init(&entry->list);
+	list_del_init(&entry->dirty_list);
 }
 
 static inline void
@@ -538,7 +540,7 @@ dirty_tree_insert(struct object_cache *oc, uint32_t idx,
 		entry->idx |= CACHE_CREATE_BIT;
 	rb_link_node(&entry->dirty_node, parent, p);
 	rb_insert_color(&entry->dirty_node, &oc->dirty_tree);
-	list_add(&entry->list, &oc->dirty_list);
+	list_add(&entry->dirty_list, &oc->dirty_list);
 
 	return entry;
 }
@@ -638,6 +640,8 @@ static void add_to_object_cache(struct object_cache *oc, uint32_t idx)
 	entry = xzalloc(sizeof(*entry));
 	entry->oc = oc;
 	entry->idx = idx;
+	INIT_LIST_HEAD(&entry->dirty_list);
+	INIT_LIST_HEAD(&entry->object_list);
 	CDS_INIT_LIST_HEAD(&entry->lru_list);
 
 	dprintf("cache object for vdi %" PRIx32 ", idx %08" PRIx32 "added\n",
@@ -831,7 +835,7 @@ static int object_cache_push(struct object_cache *oc)
 	list_splice_init(&oc->dirty_list, &inactive_dirty_list);
 	pthread_rwlock_unlock(&oc->lock);
 
-	list_for_each_entry_safe(entry, t, &inactive_dirty_list, list) {
+	list_for_each_entry_safe(entry, t, &inactive_dirty_list, dirty_list) {
 		pthread_rwlock_wrlock(&oc->lock);
 		bmap = entry->bmap;
 		create = entry->idx & CACHE_CREATE_BIT;
@@ -876,29 +880,34 @@ int object_is_cached(uint64_t oid)
 void object_cache_delete(uint32_t vid)
 {
 	struct object_cache *cache;
+	int h = hash(vid);
+	struct object_cache_entry *entry, *t;
+	struct strbuf buf = STRBUF_INIT;
 
 	cache = find_object_cache(vid, 0);
-	if (cache) {
-		int h = hash(vid);
-		struct object_cache_entry *entry, *t;
-		struct strbuf buf = STRBUF_INIT;
-
-		/* Firstly we free memeory */
-		pthread_mutex_lock(&hashtable_lock[h]);
-		hlist_del(&cache->hash);
-		pthread_mutex_unlock(&hashtable_lock[h]);
-
-		list_for_each_entry_safe(entry, t, &cache->dirty_list, list) {
-			free(entry);
-		}
-		free(cache);
+	if (!cache)
+		return;
 
-		/* Then we free disk */
-		strbuf_addf(&buf, "%s/%06"PRIx32, cache_dir, vid);
-		rmdir_r(buf.buf);
+	/* Firstly we free memeory */
+	pthread_mutex_lock(&hashtable_lock[h]);
+	hlist_del(&cache->hash);
+	pthread_mutex_unlock(&hashtable_lock[h]);
 
-		strbuf_release(&buf);
+	pthread_rwlock_wrlock(&cache->lock);
+	list_for_each_entry_safe(entry, t, &cache->object_list, dirty_list) {
+		del_from_object_tree_and_list(entry, &cache->object_tree);
+		if (!list_empty(&entry->dirty_list))
+			del_from_dirty_tree_and_list(entry, &cache->dirty_tree);
+		free(entry);
 	}
+	pthread_rwlock_unlock(&cache->lock);
+	free(cache);
+
+	/* Then we free disk */
+	strbuf_addf(&buf, "%s/%06"PRIx32, cache_dir, vid);
+	rmdir_r(buf.buf);
+
+	strbuf_release(&buf);
 
 }
 
@@ -1157,7 +1166,7 @@ void object_cache_remove(uint64_t oid)
 	entry = object_tree_search(&oc->object_tree, idx);
 	if (!entry)
 		goto out;
-	if (!list_empty(&entry->list))
+	if (!list_empty(&entry->dirty_list))
 		del_from_dirty_tree_and_list(entry, &oc->dirty_tree);
 	del_from_object_tree_and_list(entry, &oc->object_tree);
 	free(entry);
-- 
1.7.1




More information about the sheepdog mailing list