From: Liu Yuan <tailai...@taobao.com> We don't need it because we can rely object tree to find cache entry. And we don't search dirty tree.
Signed-off-by: Liu Yuan <tailai...@taobao.com> --- sheep/object_cache.c | 121 ++++++++++---------------------------------------- 1 file changed, 24 insertions(+), 97 deletions(-) diff --git a/sheep/object_cache.c b/sheep/object_cache.c index 8e637da..d468c59 100644 --- a/sheep/object_cache.c +++ b/sheep/object_cache.c @@ -59,7 +59,6 @@ struct object_cache_entry { uint64_t bmap; /* each bit represents one dirty block in object */ struct object_cache *oc; struct rb_node node; - struct rb_node dirty_node; struct list_head dirty_list; struct list_head object_list; struct cds_list_head lru_list; @@ -71,7 +70,6 @@ struct object_cache { struct list_head dirty_list; struct list_head object_list; - struct rb_root dirty_tree; struct rb_root object_tree; pthread_rwlock_t lock; @@ -182,20 +180,15 @@ static struct object_cache_entry *object_tree_search(struct rb_root *root, } static inline void -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->dirty_list); -} - -static inline void del_from_object_tree_and_list(struct object_cache_entry *entry, struct rb_root *object_tree) { rb_erase(&entry->node, object_tree); list_del_init(&entry->object_list); cds_list_del_rcu(&entry->lru_list); + if (!list_empty(&entry->dirty_list)) + list_del_init(&entry->dirty_list); + free(entry); } static uint64_t idx_to_oid(uint32_t vid, uint32_t idx) @@ -214,74 +207,22 @@ static int remove_cache_object(struct object_cache *oc, uint32_t idx) sprintf(path, "%s/%06"PRIx32"/%08"PRIx32, cache_dir, oc->vid, idx); dprintf("removing cache object %"PRIx64"\n", idx_to_oid(oc->vid, idx)); if (unlink(path) < 0) { - ret = SD_RES_EIO; eprintf("failed to remove cached object %m\n"); + if (errno == ENOENT) + return SD_RES_SUCCESS; + ret = SD_RES_EIO; goto out; } out: return ret; } -static struct object_cache_entry * -dirty_tree_and_list_insert(struct object_cache *oc, uint32_t idx, - uint64_t bmap, bool create) -{ - struct rb_node **p = &oc->dirty_tree.rb_node; - struct rb_node *parent = NULL; - struct object_cache_entry *entry; - - while (*p) { - parent = *p; - entry = rb_entry(parent, struct object_cache_entry, dirty_node); - - if (idx < entry_idx(entry)) - p = &(*p)->rb_left; - else if (idx > entry_idx(entry)) - p = &(*p)->rb_right; - else { - /* already has this entry, merge bmap */ - entry->bmap |= bmap; - return entry; - } - } - - entry = object_tree_search(&oc->object_tree, idx); - if (!entry) - panic("Can not find object entry %" PRIx32 "\n", idx); - - entry->bmap |= bmap; - if (create) - 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->dirty_list, &oc->dirty_list); - - return entry; -} - static inline void lru_move_entry(struct object_cache_entry *entry) { cds_list_del_rcu(&entry->lru_list); cds_list_add_rcu(&entry->lru_list, &sys_cache.cache_lru_list); } -static inline void update_cache_entry(struct object_cache_entry *entry, - uint32_t idx, size_t datalen, - off_t offset, int dirty) -{ - struct object_cache *oc = entry->oc; - - if (dirty) { - uint64_t bmap = calc_object_bmap(datalen, offset); - - pthread_rwlock_wrlock(&oc->lock); - dirty_tree_and_list_insert(oc, idx, bmap, false); - pthread_rwlock_unlock(&oc->lock); - } - - lru_move_entry(entry); -} - static int read_cache_object_noupdate(uint32_t vid, uint32_t idx, void *buf, size_t count, off_t offset) { @@ -358,7 +299,7 @@ static int read_cache_object(struct object_cache_entry *entry, void *buf, ret = read_cache_object_noupdate(vid, idx, buf, count, offset); if (ret == SD_RES_SUCCESS) - update_cache_entry(entry, idx, count, offset, 0); + lru_move_entry(entry); return ret; } @@ -372,10 +313,17 @@ static int write_cache_object(struct object_cache_entry *entry, void *buf, int ret; ret = write_cache_object_noupdate(vid, idx, buf, count, offset); - + if (ret == SD_RES_SUCCESS && writeback) { + pthread_rwlock_wrlock(&entry->oc->lock); + entry->bmap |= calc_object_bmap(count, offset); + if (list_empty(&entry->dirty_list)) + list_add(&entry->dirty_list, &entry->oc->dirty_list); + pthread_rwlock_unlock(&entry->oc->lock); + } if (ret != SD_RES_SUCCESS) return ret; + lru_move_entry(entry); if (writeback) goto out; @@ -395,7 +343,6 @@ static int write_cache_object(struct object_cache_entry *entry, void *buf, return ret; } out: - update_cache_entry(entry, idx, count, offset, writeback); return ret; } @@ -454,7 +401,6 @@ static int push_cache_object(uint32_t vid, uint32_t idx, uint64_t bmap, ret = exec_local_req(&hdr, buf); if (ret != SD_RES_SUCCESS) eprintf("failed to push object %x\n", ret); - out: free(buf); return ret; @@ -474,9 +420,8 @@ static int do_reclaim_object(struct object_cache_entry *entry) uint64_t oid; int ret = 0; - pthread_rwlock_wrlock(&oc->lock); - oid = idx_to_oid(oc->vid, entry_idx(entry)); + pthread_rwlock_wrlock(&oc->lock); if (uatomic_read(&entry->refcnt) > 0) { dprintf("%"PRIx64" is in operation, skip...\n", oid); ret = -1; @@ -529,7 +474,6 @@ static void do_reclaim(struct work *work) data_length = data_length / 1024 / 1024; uatomic_sub(&sys_cache.cache_size, data_length); - free(entry); } dprintf("cache reclaim complete\n"); @@ -581,7 +525,6 @@ not_found: cache->object_tree = RB_ROOT; create_dir_for(vid); - cache->dirty_tree = RB_ROOT; INIT_LIST_HEAD(&cache->dirty_list); INIT_LIST_HEAD(&cache->object_list); @@ -616,7 +559,7 @@ void object_cache_try_to_reclaim(void) } static void add_to_object_cache(struct object_cache *oc, uint32_t idx, - bool create) + bool writeback) { struct object_cache_entry *entry, *old; uint32_t data_length; @@ -645,9 +588,10 @@ static void add_to_object_cache(struct object_cache *oc, uint32_t idx, free(entry); entry = old; } - if (create) { - uint64_t all = UINT64_MAX; - dirty_tree_and_list_insert(oc, idx, all, create); + if (writeback) { + entry->bmap = UINT64_MAX; + entry->idx |= CACHE_CREATE_BIT; + list_add(&entry->dirty_list, &oc->dirty_list); } pthread_rwlock_unlock(&oc->lock); lru_move_entry(entry); @@ -817,7 +761,7 @@ static int object_cache_push(struct object_cache *oc) goto push_failed; entry->idx &= ~CACHE_CREATE_BIT; entry->bmap = 0; - del_from_dirty_tree_and_list(entry, &oc->dirty_tree); + list_del_init(&entry->dirty_list); } push_failed: pthread_rwlock_unlock(&oc->lock); @@ -856,9 +800,6 @@ void object_cache_delete(uint32_t vid) pthread_rwlock_wrlock(&cache->lock); list_for_each_entry_safe(entry, t, &cache->object_list, object_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); @@ -880,10 +821,8 @@ get_cache_entry(struct object_cache *cache, uint32_t idx) pthread_rwlock_unlock(&cache->lock); return NULL; } - uatomic_inc(&entry->refcnt); pthread_rwlock_unlock(&cache->lock); - return entry; } @@ -993,7 +932,6 @@ int object_cache_handle_request(struct request *req) if (req->rq.opcode == SD_OP_CREATE_AND_WRITE_OBJ) create = true; - retry: ret = object_cache_lookup(cache, idx, create, hdr->flags & SD_FLAG_CMD_CACHE); @@ -1043,10 +981,8 @@ int object_cache_write(uint64_t oid, char *data, unsigned int datalen, struct object_cache_entry *entry; int ret; - cache = find_object_cache(vid, false); - dprintf("%" PRIx64 "\n", oid); - + cache = find_object_cache(vid, false); entry = get_cache_entry(cache, idx); if (!entry) { dprintf("%" PRIx64 " doesn't exist\n", oid); @@ -1054,9 +990,7 @@ int object_cache_write(uint64_t oid, char *data, unsigned int datalen, } ret = write_cache_object(entry, data, datalen, offset, create, false); - put_cache_entry(entry); - return ret; } @@ -1069,10 +1003,8 @@ int object_cache_read(uint64_t oid, char *data, unsigned int datalen, struct object_cache_entry *entry; int ret; - cache = find_object_cache(vid, false); - dprintf("%" PRIx64 "\n", oid); - + cache = find_object_cache(vid, false); entry = get_cache_entry(cache, idx); if (!entry) { dprintf("%" PRIx64 " doesn't exist\n", oid); @@ -1080,9 +1012,7 @@ int object_cache_read(uint64_t oid, char *data, unsigned int datalen, } ret = read_cache_object(entry, data, datalen, offset); - put_cache_entry(entry); - return ret; } @@ -1128,10 +1058,7 @@ void object_cache_remove(uint64_t oid) entry = object_tree_search(&oc->object_tree, idx); if (!entry) goto out; - 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); out: pthread_rwlock_unlock(&oc->lock); return; -- 1.7.9.5 -- sheepdog mailing list sheepdog@lists.wpkg.org http://lists.wpkg.org/mailman/listinfo/sheepdog