[Sheepdog] [PATCH] sheep: keep the vnodes cache until epoch changs
yaohaiting.wujue at gmail.com
yaohaiting.wujue at gmail.com
Fri Apr 27 09:05:46 CEST 2012
From: HaiTing Yao <wujue.yht at taobao.com>
After one request had been done, we check the cache reference counter
and try to free it.
This freeing has two problems, so I think we should keep the cache until
epoch changes.
Problems:
1, race condition
get_ordered_sd_vnode_list gets the cache and try to use it, but
free_ordered_sd_vnode_list frees it.
2, no cache when I/O is not tense
create and free the cache frequently when I/O is not tense
Signed-off-by: HaiTing Yao <wujue.yht at taobao.com>
---
sheep/group.c | 14 +++++++++-----
1 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/sheep/group.c b/sheep/group.c
index b4cf2da..317691c 100644
--- a/sheep/group.c
+++ b/sheep/group.c
@@ -139,8 +139,9 @@ int get_ordered_sd_vnode_list(struct sd_vnode **entries,
{
static LIST_HEAD(vnodes_list);
struct vnodes_cache *cache;
+ struct vnodes_cache *next_cache;
- list_for_each_entry(cache, &vnodes_list, list) {
+ list_for_each_entry_safe(cache, next_cache, &vnodes_list, list) {
if (cache->epoch == sys->epoch) {
*entries = cache->vnodes;
*nr_vnodes = cache->nr_vnodes;
@@ -148,6 +149,11 @@ int get_ordered_sd_vnode_list(struct sd_vnode **entries,
cache->refcnt++;
return SD_RES_SUCCESS;
+ } else if (cache->epoch < sys->epoch) {
+ if (!cache->refcnt) {
+ list_del(&cache->list);
+ free(cache);
+ }
}
}
@@ -181,10 +187,8 @@ void free_ordered_sd_vnode_list(struct sd_vnode *entries)
return;
cache = container_of(entries, struct vnodes_cache, vnodes[0]);
- if (--cache->refcnt == 0) {
- list_del(&cache->list);
- free(cache);
- }
+
+ cache->refcnt--;
}
void setup_ordered_sd_vnode_list(struct request *req)
--
1.7.1
More information about the sheepdog
mailing list