[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