From: Liu Yuan <[email protected]>

Signed-off-by: Liu Yuan <[email protected]>
---
 sheep/object_cache.c |  181 +++++++++++++++++++++++++++-----------------------
 1 file changed, 97 insertions(+), 84 deletions(-)

diff --git a/sheep/object_cache.c b/sheep/object_cache.c
index d6b5604..2ee609b 100644
--- a/sheep/object_cache.c
+++ b/sheep/object_cache.c
@@ -244,12 +244,76 @@ out:
        return ret;
 }
 
-static int write_cache_object(uint32_t vid, uint32_t idx, void *buf,
+static struct object_cache_entry *
+dirty_tree_and_list_insert(struct object_cache *oc, uint32_t idx,
+                 uint64_t bmap, int create)
+{
+       struct rb_node **p = &oc->dirty_tree.rb_node;
+       struct rb_node *parent = NULL;
+       struct object_cache_entry *entry;
+       idx = idx_mask(idx);
+
+       while (*p) {
+               parent = *p;
+               entry = rb_entry(parent, struct object_cache_entry, dirty_node);
+
+               if (idx < idx_mask(entry->idx))
+                       p = &(*p)->rb_left;
+               else if (idx > idx_mask(entry->idx))
+                       p = &(*p)->rb_right;
+               else {
+                       /* already has this entry, merge bmap */
+                       entry->bmap |= bmap;
+                       if (create)
+                               entry->idx |= CACHE_CREATE_BIT;
+                       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 wrt)
+{
+       struct object_cache *oc = entry->oc;
+
+       if (wrt) {
+               uint64_t bmap = calc_object_bmap(datalen, offset);
+
+               pthread_rwlock_wrlock(&oc->lock);
+               dirty_tree_and_list_insert(oc, idx, bmap, 0);
+               pthread_rwlock_unlock(&oc->lock);
+       }
+
+       lru_move_entry(entry);
+}
+
+static int write_cache_object(struct object_cache_entry *entry, void *buf,
                              size_t count, off_t offset)
 {
        size_t size;
        int fd, flags = def_open_flags, ret = SD_RES_SUCCESS;
        struct strbuf p;
+       uint32_t vid = entry->oc->vid, idx = idx_mask(entry->idx);
 
        strbuf_init(&p, PATH_MAX);
        strbuf_addstr(&p, cache_dir);
@@ -281,7 +345,10 @@ static int write_cache_object(uint32_t vid, uint32_t idx, 
void *buf,
                eprintf("size %zu, count:%zu, offset %jd %m\n",
                        size, count, (intmax_t)offset);
                ret = SD_RES_EIO;
+               goto out_close;
        }
+
+       update_cache_entry(entry, idx, count, offset, 1);
 out_close:
        close(fd);
 out:
@@ -289,8 +356,8 @@ out:
        return ret;
 }
 
-static int read_cache_object(uint32_t vid, uint32_t idx, void *buf,
-                            size_t count, off_t offset)
+static int read_cache_object_noupdate(uint32_t vid, uint32_t idx, void *buf,
+                                     size_t count, off_t offset)
 {
        size_t size;
        int fd, flags = def_open_flags, ret = SD_RES_SUCCESS;
@@ -326,6 +393,7 @@ static int read_cache_object(uint32_t vid, uint32_t idx, 
void *buf,
                eprintf("size %zu, count:%zu, offset %jd %m\n",
                        size, count, (intmax_t)offset);
                ret = SD_RES_EIO;
+               goto out_close;
        }
 
 out_close:
@@ -334,6 +402,18 @@ out:
        strbuf_release(&p);
        return ret;
 }
+static int read_cache_object(struct object_cache_entry *entry, void *buf,
+                            size_t count, off_t offset)
+{
+       uint32_t vid = entry->oc->vid, idx = idx_mask(entry->idx);
+       int ret;
+
+       ret = read_cache_object_noupdate(vid, idx, buf, count, offset);
+
+       if (ret == SD_RES_SUCCESS)
+               update_cache_entry(entry, idx, count, offset, 0);
+       return ret;
+}
 
 static int push_cache_object(uint32_t vid, uint32_t idx, uint64_t bmap,
                             int create)
@@ -376,7 +456,7 @@ static int push_cache_object(uint32_t vid, uint32_t idx, 
uint64_t bmap,
                goto out;
        }
 
-       ret = read_cache_object(vid, idx, buf, data_length, offset);
+       ret = read_cache_object_noupdate(vid, idx, buf, data_length, offset);
        if (ret != SD_RES_SUCCESS)
                goto out;
 
@@ -478,46 +558,6 @@ static void reclaim_done(struct work *work)
        free(work);
 }
 
-static struct object_cache_entry *
-dirty_tree_and_list_insert(struct object_cache *oc, uint32_t idx,
-                 uint64_t bmap, int create)
-{
-       struct rb_node **p = &oc->dirty_tree.rb_node;
-       struct rb_node *parent = NULL;
-       struct object_cache_entry *entry;
-       idx = idx_mask(idx);
-
-       while (*p) {
-               parent = *p;
-               entry = rb_entry(parent, struct object_cache_entry, dirty_node);
-
-               if (idx < idx_mask(entry->idx))
-                       p = &(*p)->rb_left;
-               else if (idx > idx_mask(entry->idx))
-                       p = &(*p)->rb_right;
-               else {
-                       /* already has this entry, merge bmap */
-                       entry->bmap |= bmap;
-                       if (create)
-                               entry->idx |= CACHE_CREATE_BIT;
-                       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 int create_dir_for(uint32_t vid)
 {
        int ret = 0;
@@ -570,28 +610,6 @@ out:
        return cache;
 }
 
-/* Caller should hold the oc->lock */
-static inline void
-add_to_dirty_tree_and_list(struct object_cache *oc, uint32_t idx,
-                          uint64_t bmap, int create)
-{
-       struct object_cache_entry *entry;
-       entry = dirty_tree_and_list_insert(oc, idx, bmap, create);
-
-       cds_list_del_rcu(&entry->lru_list);
-       cds_list_add_rcu(&entry->lru_list, &sys_cache.cache_lru_list);
-}
-
-static void update_cache_entry(struct object_cache *oc, uint32_t idx,
-               size_t datalen, off_t offset)
-{
-       uint64_t bmap = calc_object_bmap(datalen, offset);
-
-       pthread_rwlock_wrlock(&oc->lock);
-       add_to_dirty_tree_and_list(oc, idx, bmap, 0);
-       pthread_rwlock_unlock(&oc->lock);
-}
-
 void object_cache_try_to_reclaim(void)
 {
        struct work *work;
@@ -641,9 +659,10 @@ static void add_to_object_cache(struct object_cache *oc, 
uint32_t idx,
        }
        if (create) {
                uint64_t all = UINT64_MAX;
-               add_to_dirty_tree_and_list(oc, idx, all, create);
+               dirty_tree_and_list_insert(oc, idx, all, create);
        }
        pthread_rwlock_unlock(&oc->lock);
+       lru_move_entry(entry);
 
        object_cache_try_to_reclaim();
 }
@@ -976,30 +995,26 @@ retry:
        if (!entry) {
                dprintf("retry oid %"PRIx64"\n", oid);
                /*
-                * For the case that object exists but can't be added to list,
-                * we call pthread_yield() to expect other thread can add object
-                * to list ASAP.
+                * For the case that object exists but isn't added to object
+                * list yet, we call pthread_yield() to expect other thread can
+                * add object to list ASAP.
                 */
                pthread_yield();
                goto retry;
        }
 
        if (hdr->flags & SD_FLAG_CMD_WRITE) {
-               ret = write_cache_object(cache->vid, idx, req->data,
-                                        hdr->data_length, hdr->obj.offset);
+               ret = write_cache_object(entry, req->data, hdr->data_length,
+                                        hdr->obj.offset);
                if (ret != SD_RES_SUCCESS)
                        goto err;
-               update_cache_entry(cache, idx, hdr->data_length,
-                                  hdr->obj.offset);
        } else {
-               ret = read_cache_object(cache->vid, idx, req->data,
-                                       hdr->data_length, hdr->obj.offset);
+               ret = read_cache_object(entry, req->data, hdr->data_length,
+                                       hdr->obj.offset);
                if (ret != SD_RES_SUCCESS)
                        goto err;
                req->rp.data_length = hdr->data_length;
 
-               cds_list_del_rcu(&entry->lru_list);
-               cds_list_add_rcu(&entry->lru_list, &sys_cache.cache_lru_list);
        }
 err:
        put_cache_entry(entry);
@@ -1021,13 +1036,11 @@ int object_cache_write(uint64_t oid, char *data, 
unsigned int datalen,
 
        entry = get_cache_entry(cache, idx);
        if (!entry) {
-               dprintf("cache object %" PRIx32 " doesn't exist\n", idx);
+               dprintf("%" PRIx64 " doesn't exist\n", oid);
                return SD_RES_NO_CACHE;
        }
 
-       ret = write_cache_object(vid, idx, data, datalen, offset);
-       if (ret == SD_RES_SUCCESS)
-               update_cache_entry(cache, idx, datalen, offset);
+       ret = write_cache_object(entry, data, datalen, offset);
 
        put_cache_entry(entry);
 
@@ -1049,11 +1062,11 @@ int object_cache_read(uint64_t oid, char *data, 
unsigned int datalen,
 
        entry = get_cache_entry(cache, idx);
        if (!entry) {
-               dprintf("cache object %" PRIx32 " doesn't exist\n", idx);
+               dprintf("%" PRIx64 " doesn't exist\n", oid);
                return SD_RES_NO_CACHE;
        }
 
-       ret = read_cache_object(vid, idx, data, datalen, offset);
+       ret = read_cache_object(entry, data, datalen, offset);
 
        put_cache_entry(entry);
 
-- 
1.7.10.2

-- 
sheepdog mailing list
[email protected]
http://lists.wpkg.org/mailman/listinfo/sheepdog

Reply via email to