[Sheepdog] [PATCH 5/7] sheep: add flush_vdi operation
Liu Yuan
namei.unix at gmail.com
Sun Mar 11 13:32:29 CET 2012
From: Liu Yuan <tailai.ly at taobao.com>
This is supposed to be initiated by Guest OS, but our collie
friend might also like it.
Flush operation is operated on vdi basis, that is, when one guest
flush its own dirty data, other guests are not affected.
- use forward_write_obj_req() to flush dirty objects
Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
---
include/sheepdog_proto.h | 1 +
sheep/object_cache.c | 47 ++++++++++++++++++++++++++++++++++++++++++++-
sheep/ops.c | 5 ++++
sheep/sheep_priv.h | 2 +
sheep/store.c | 14 +++++++++++-
5 files changed, 65 insertions(+), 4 deletions(-)
diff --git a/include/sheepdog_proto.h b/include/sheepdog_proto.h
index 2d0d5ec..8cd1cac 100644
--- a/include/sheepdog_proto.h
+++ b/include/sheepdog_proto.h
@@ -29,6 +29,7 @@
#define SD_OP_RELEASE_VDI 0x13
#define SD_OP_GET_VDI_INFO 0x14
#define SD_OP_READ_VDIS 0x15
+#define SD_OP_FLUSH_VDI 0x16
#define SD_FLAG_CMD_WRITE 0x01
#define SD_FLAG_CMD_COW 0x02
diff --git a/sheep/object_cache.c b/sheep/object_cache.c
index 12b26ef..ecd640c 100644
--- a/sheep/object_cache.c
+++ b/sheep/object_cache.c
@@ -365,8 +365,51 @@ static uint64_t idx_to_oid(uint32_t vid, uint32_t idx)
static int push_cache_object(int fd, uint64_t oid)
{
+ struct request fake_req;
+ struct sd_obj_req *hdr = (struct sd_obj_req *)&fake_req.rq;
+ void *buf;
+ unsigned data_length;
+ int ret = SD_RES_NO_MEM;
+
dprintf("%"PRIx64"\n", oid);
- return 0;
+
+ memset(&fake_req, 0, sizeof(fake_req));
+ if (is_vdi_obj(oid))
+ data_length = sizeof(struct sheepdog_inode);
+ else
+ data_length = SD_DATA_OBJ_SIZE;
+
+ buf = zalloc(data_length);
+ if (buf == NULL) {
+ eprintf("failed to allocate memory\n");
+ goto out;
+ }
+
+ ret = read_cache_object(fd, buf, data_length, 0);
+ if (ret != SD_RES_SUCCESS)
+ goto out;
+
+ hdr->offset = 0;
+ hdr->data_length = data_length;
+ hdr->opcode = SD_OP_WRITE_OBJ;
+ hdr->flags = SD_FLAG_CMD_WRITE;
+ hdr->oid = oid;
+ hdr->copies = sys->nr_sobjs;
+ hdr->epoch = sys->epoch;
+ fake_req.data = buf;
+ fake_req.op = get_sd_op(SD_OP_WRITE_OBJ);
+ fake_req.entry = sys->vnodes;
+ fake_req.nr_vnodes = sys->nr_vnodes;
+ fake_req.nr_zones = get_zones_nr_from(sys->nodes, sys->nr_vnodes);
+
+ ret = forward_write_obj_req(&fake_req);
+ if (ret != SD_RES_SUCCESS) {
+ eprintf("failed to push object %x\n", ret);
+ goto out;
+ }
+out:
+ free(buf);
+ return ret;
}
/* Push back all the dirty objects to sheep cluster storage */
@@ -374,7 +417,7 @@ int object_cache_push(struct object_cache *oc)
{
struct object_cache_entry *entry, *t;
struct strbuf buf;
- int fd, ret;
+ int fd, ret = SD_RES_SUCCESS;
strbuf_init(&buf, PATH_MAX);
strbuf_addstr(&buf, cache_dir);
diff --git a/sheep/ops.c b/sheep/ops.c
index 4a672be..6b889fd 100644
--- a/sheep/ops.c
+++ b/sheep/ops.c
@@ -588,6 +588,11 @@ static struct sd_op_template sd_ops[] = {
.type = SD_OP_TYPE_IO,
.process_work = store_remove_obj,
},
+
+ [SD_OP_FLUSH_VDI] = {
+ .type = SD_OP_TYPE_IO,
+ .process_work = store_flush_vdi,
+ },
};
struct sd_op_template *get_sd_op(uint8_t opcode)
diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index d0c6be8..a4161b4 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -246,6 +246,7 @@ int write_object_local(uint64_t oid, char *data, unsigned int datalen,
uint32_t epoch, int create);
int read_object_local(uint64_t oid, char *data, unsigned int datalen,
uint64_t offset, int copies, uint32_t epoch);
+int forward_write_obj_req(struct request *req);
int read_epoch(uint32_t *epoch, uint64_t *ctime,
struct sd_node *entries, int *nr_entries);
@@ -265,6 +266,7 @@ int store_create_and_write_obj(const struct sd_req *, struct sd_rsp *, void *);
int store_write_obj(const struct sd_req *, struct sd_rsp *, void *);
int store_read_obj(const struct sd_req *, struct sd_rsp *, void *);
int store_remove_obj(const struct sd_req *, struct sd_rsp *, void *);
+int store_flush_vdi(const struct sd_req *req, struct sd_rsp *rsp, void *data);
int store_file_write(void *buffer, size_t len);
void *store_file_read(void);
diff --git a/sheep/store.c b/sheep/store.c
index 411079f..1a0d42f 100644
--- a/sheep/store.c
+++ b/sheep/store.c
@@ -288,7 +288,7 @@ out:
return ret;
}
-static int forward_write_obj_req(struct request *req)
+int forward_write_obj_req(struct request *req)
{
int i, n, nr, fd, ret, pollret;
unsigned wlen;
@@ -585,6 +585,16 @@ out:
return ret;
}
+int store_flush_vdi(const struct sd_req *req, struct sd_rsp *rsp, void *data)
+{
+ struct sd_obj_req *hdr = (struct sd_obj_req *)req;
+ uint64_t oid = hdr->oid;
+ uint32_t vid = oid_to_vid(oid);
+ struct object_cache *cache = find_object_cache(vid);
+
+ return object_cache_push(cache);
+}
+
static int do_write_obj(struct siocb *iocb, struct sd_obj_req *req, uint32_t epoch, void *data)
{
struct sd_obj_req *hdr = (struct sd_obj_req *)req;
@@ -778,7 +788,7 @@ void do_io_request(struct work *work)
if (hdr->flags & SD_FLAG_CMD_RECOVERY)
epoch = hdr->tgt_epoch;
- if (hdr->flags & SD_FLAG_CMD_IO_LOCAL) {
+ if (hdr->flags & SD_FLAG_CMD_IO_LOCAL || opcode == SD_OP_FLUSH_VDI) {
ret = do_local_io(req, epoch);
} else {
/* fix object consistency when we read the object for the first time */
--
1.7.8.2
More information about the sheepdog
mailing list