[sheepdog] [PATCH v2 9/9] object cache: add a object_list for cache entry for cache deleting

levin li levin108 at gmail.com
Wed Jul 25 14:15:25 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 |   51 ++++++++++++++++++++++++++++----------------------
 1 file changed, 29 insertions(+), 22 deletions(-)

diff --git a/sheep/object_cache.c b/sheep/object_cache.c
index 0e2779a..b974037 100644
--- a/sheep/object_cache.c
+++ b/sheep/object_cache.c
@@ -68,6 +68,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;
 
@@ -83,7 +84,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;
 };
 
@@ -217,7 +219,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
@@ -401,7 +403,7 @@ dirty_tree_insert(struct object_cache *oc, uint32_t idx,
 		entry->flags |= ENTRY_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;
 }
@@ -501,6 +503,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",
@@ -863,7 +867,7 @@ static int object_cache_push(struct object_cache *oc)
 	 * 2. for sync flush, Guest assure us of that only one sync
 	 * request is issued in one of gateway worker threads
 	 * So we need not to protect inactive dirty tree and list */
-	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_rdlock(&oc->lock);
 		bmap = entry->bmap;
 		create = entry->flags & ENTRY_CREATE_BIT;
@@ -909,29 +913,32 @@ 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;
+	if (!cache)
+		return;
 
-		/* Firstly we free memeory */
-		pthread_mutex_lock(&hashtable_lock[h]);
-		hlist_del(&cache->hash);
-		pthread_mutex_unlock(&hashtable_lock[h]);
+	/* 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);
+	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);
+	}
+	free(cache);
 
-		/* Then we free disk */
-		strbuf_addf(&buf, "%s/%06"PRIx32, cache_dir, vid);
-		rmdir_r(buf.buf);
+	/* Then we free disk */
+	strbuf_addf(&buf, "%s/%06"PRIx32, cache_dir, vid);
+	rmdir_r(buf.buf);
 
-		strbuf_release(&buf);
-	}
+	strbuf_release(&buf);
 
 }
 
@@ -1214,7 +1221,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.10




More information about the sheepdog mailing list