[Sheepdog] [PATCH] object cache: add flush_and_delete operation
MORITA Kazutaka
morita.kazutaka at lab.ntt.co.jp
Tue Apr 3 19:19:56 CEST 2012
At Tue, 3 Apr 2012 16:03:57 +0800,
Liu Yuan wrote:
>
> From: Liu Yuan <tailai.ly at taobao.com>
>
> 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..84bffc2 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);
Hmm, does this work well when multiple write requests arrive at the
same time? I cannot come up with a better approach, though.
BTW, do we really need to split a object cache into 4 MB files? It
looks simpler and faster to use a single large and sparse file for the
object caches (the file has the same size and content with the virtual
disk) since we can avoid extra open/close calls.
Thanks,
Kazutaka
More information about the sheepdog
mailing list