[Sheepdog] [PATCH v2 5/7] sheep: add flush_vdi operation

Liu Yuan namei.unix at gmail.com
Mon Mar 12 13:10:17 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 a678de5..80b9530 100644
--- a/sheep/object_cache.c
+++ b/sheep/object_cache.c
@@ -367,8 +367,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 */
@@ -376,7 +419,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 af2f80b..01ddb93 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 1386ed5..1e9c3d2 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