[Sheepdog] [PATCH] object cache: add flush_and_delete operation
Liu Yuan
namei.unix at gmail.com
Wed Apr 4 11:49:29 CEST 2012
On 04/04/2012 01:19 AM, MORITA Kazutaka wrote:
> Hmm, does this work well when multiple write requests arrive at the
> same time? I cannot come up with a better approach, though.
Hi Kazum,
I give a second try, finding that Guest(RHEL 6) will wait after issue
a write request till its completion at very eary bootup before 'login'.
I didn't see concurrent IO from the log at that stage, so I recommend
not do over-design without a practical real case that cause inconsistency.
Here is the V2 path
-V2
correct object_cache_lookup() usage
>From a167146c55f0354a6f44fa7b28cd9a3a4e4ee089 Mon Sep 17 00:00:00 2001
From: Liu Yuan <tailai.ly at taobao.com>
Date: Wed, 4 Apr 2012 17:11:45 +0800
Subject: [PATCH v2] object cache: add flush_and_delete operation
If 1) VDI is opened without cache enabled and 2) we unfortunately have
a cache for it previously, we should flush the cache then delete it.
Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
---
sheep/object_cache.c | 42 ++++++++++++++++++++++++++++++++++++++++++
sheep/sheep_priv.h | 1 +
sheep/store.c | 30 +++++++++++++++++++++---------
3 files changed, 64 insertions(+), 9 deletions(-)
diff --git a/sheep/object_cache.c b/sheep/object_cache.c
index b59f8f7..e856be4 100644
--- a/sheep/object_cache.c
+++ b/sheep/object_cache.c
@@ -20,6 +20,7 @@
#include <pthread.h>
#include <errno.h>
#include <sys/file.h>
+#include <dirent.h>
#include "sheep_priv.h"
#include "util.h"
@@ -526,6 +527,47 @@ void object_cache_delete(uint32_t vid)
}
+int object_cache_flush_and_delete(struct object_cache *oc)
+{
+ DIR *dir;
+ struct dirent *d;
+ uint32_t vid = oc->vid;
+ uint32_t idx;
+ struct strbuf p;
+ int ret = 0;
+
+ strbuf_init(&p, PATH_MAX);
+ strbuf_addstr(&p, cache_dir);
+ strbuf_addf(&p, "/%06"PRIx32, vid);
+
+ dprintf("%"PRIx32"\n", vid);
+ dir = opendir(p.buf);
+ if (!dir) {
+ dprintf("%m\n");
+ ret = -1;
+ goto out;
+ }
+
+ while ((d = readdir(dir))) {
+ if (!strncmp(d->d_name, ".", 1))
+ continue;
+ idx = strtoul(d->d_name, NULL, 16);
+ if (idx == ULLONG_MAX)
+ continue;
+ if (push_cache_object(vid, idx, 1) != SD_RES_SUCCESS) {
+ dprintf("failed to push %"PRIx64"\n",
+ idx_to_oid(vid, idx));
+ ret = -1;
+ goto out;
+ }
+ }
+
+ object_cache_delete(vid);
+out:
+ strbuf_release(&p);
+ return ret;
+}
+
int object_cache_init(const char *p)
{
int ret = 0;
diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index d687cc0..c01ee46 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -429,5 +429,6 @@ int object_cache_push(struct object_cache *oc);
int object_cache_init(const char *p);
int object_is_cached(uint64_t oid);
void object_cache_delete(uint32_t vid);
+int object_cache_flush_and_delete(struct object_cache *oc);
#endif
diff --git a/sheep/store.c b/sheep/store.c
index 6661f13..d98d2b4 100644
--- a/sheep/store.c
+++ b/sheep/store.c
@@ -835,16 +835,28 @@ static int bypass_object_cache(struct sd_obj_req *hdr)
{
uint64_t oid = hdr->oid;
- /*
- * We assume the cached object is freshest, donot break it ever.
- * This assumption is useful for non-cache requests from collie,
- * which tries hard to get the newest data.
- */
- if (object_is_cached(oid))
- return 0;
+ if (!(hdr->flags & SD_FLAG_CMD_CACHE)) {
+ uint32_t vid = oid_to_vid(oid);
+ struct object_cache *cache;
- if (!(hdr->flags & SD_FLAG_CMD_CACHE))
- return 1;
+ cache = find_object_cache(vid, 0);
+ if (!cache)
+ return 1;
+ if (hdr->flags & SD_FLAG_CMD_WRITE) {
+ object_cache_flush_and_delete(cache);
+ return 1;
+ } else {
+ /* For read requet, we can read cache if any */
+ uint32_t idx = data_oid_to_idx(oid);
+ if (is_vdi_obj(oid))
+ idx |= 1 << CACHE_VDI_SHIFT;
+
+ if (object_cache_lookup(cache, idx, 0) < 0)
+ return 1;
+ else
+ return 0;
+ }
+ }
/*
* For vmstate && vdi_attr object, we don't do caching
--
1.7.8.2
More information about the sheepdog
mailing list