[Sheepdog] [PATCH] sheepdog: add helper functions read_object() and write_object()

MORITA Kazutaka morita.kazutaka at lab.ntt.co.jp
Mon May 10 00:38:23 CEST 2010


Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
 block/sheepdog.c |  184 +++++++++++++++++++++++++++++++-----------------------
 1 files changed, 107 insertions(+), 77 deletions(-)

diff --git a/block/sheepdog.c b/block/sheepdog.c
index b57256a..bdb6270 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -22,7 +22,7 @@
 #define SD_OP_GET_NODE_LIST  0x19
 #define SD_OP_GET_VM_LIST    0x20
 #define SD_OP_MAKE_FS        0x21
-#define SD_OP_READ_VDIS      0x26
+#define SD_OP_READ_VDIS      0x25
 
 #define SD_OP_DEBUG_INC_NVER 0xA0
 #define SD_OP_DEBUG_SET_NODE 0xA1
@@ -878,40 +878,43 @@ static int add_aio_request(struct bdrv_sd_state *s, struct aio_req *aio_req,
 	return 0;
 }
 
-static int read_vdi_obj(char *addr, char *buf, uint32_t vid, int *copies)
+static int read_write_object(int fd, char *buf, uint64_t oid, int copies,
+			     unsigned int datalen, uint64_t offset,
+			     int write, int create)
 {
 	struct sd_obj_req hdr;
 	struct sd_obj_rsp *rsp = (struct sd_obj_rsp *)&hdr;
 	unsigned int wlen, rlen;
-	int ret, fd, i = 0;
-
-	wlen = 0;
-	rlen = SD_INODE_SIZE;
+	int ret;
 
 	memset(&hdr, 0, sizeof(hdr));
 
-	hdr.opcode = SD_OP_READ_OBJ;
-	hdr.oid = vid_to_vdi_oid(vid);
-	hdr.data_length = rlen;
-
-	fd = connect_to_sdog(addr);
-	if (fd < 0) {
-		eprintf("failed to connect to a sheep, %d\n", i);
-		return -1;
+	if (write) {
+		wlen = datalen;
+		rlen = 0;
+		hdr.flags = SD_FLAG_CMD_WRITE;
+		if (create)
+			hdr.opcode = SD_OP_CREATE_AND_WRITE_OBJ;
+		else
+			hdr.opcode = SD_OP_WRITE_OBJ;
+	} else {
+		wlen = 0;
+		rlen = datalen;
+		hdr.opcode = SD_OP_READ_OBJ;
 	}
+	hdr.oid = oid;
+	hdr.data_length = datalen;
+	hdr.offset = offset;
+	hdr.copies = copies;
 
 	ret = do_req(fd, (struct sd_req *)&hdr, buf, &wlen, &rlen);
-
-	close(fd);
-
 	if (ret) {
-		eprintf("failed to send a request to the sheep, %d\n", i);
+		eprintf("failed to send a request to the sheep\n");
 		return -1;
 	}
 
 	switch (rsp->result) {
 	case SD_RES_SUCCESS:
-		*copies = rsp->copies;
 		return 0;
 	default:
 		eprintf("%s\n", sd_strerror(rsp->result));
@@ -919,15 +922,27 @@ static int read_vdi_obj(char *addr, char *buf, uint32_t vid, int *copies)
 	}
 }
 
+static int read_object(int fd, char *buf, uint64_t oid, int copies,
+		       unsigned int datalen, uint64_t offset)
+{
+	return read_write_object(fd, buf, oid, copies, datalen, offset, 0, 0);
+}
+
+static int write_object(int fd, char *buf, uint64_t oid, int copies,
+			unsigned int datalen, uint64_t offset, int create)
+{
+	return read_write_object(fd, buf, oid, copies, datalen, offset, 1, create);
+}
+
 /* TODO: error cleanups */
 static int sd_open(BlockDriverState *bs, const char *filename, int flags)
 {
-	int ret, i;
+	int ret, i, fd;
 	uint32_t vid = 0;
 	struct bdrv_sd_state *s = bs->opaque;
 	char vdi[256];
 	uint32_t snapid;
-	int for_snapshot = 0, dummy;
+	int for_snapshot = 0;
 	char *buf;
 
 	buf = qemu_malloc(SD_INODE_SIZE);
@@ -961,7 +976,16 @@ static int sd_open(BlockDriverState *bs, const char *filename, int flags)
 	else
 		s->is_current = 1;
 
-	ret = read_vdi_obj(s->addr, buf, vid, &dummy);
+	fd = connect_to_sdog(s->addr);
+	if (fd < 0) {
+		eprintf("failed to connect\n");
+		goto out;
+	}
+
+	ret = read_object(fd, buf, vid_to_vdi_oid(vid), 0, SD_INODE_SIZE, 0);
+
+	close(fd);
+
 	if (ret)
 		goto out;
 
@@ -1198,7 +1222,7 @@ out:
 
 static int sd_create_branch(struct bdrv_sd_state *s)
 {
-	int ret, copies;
+	int ret, fd;
 	uint32_t vid;
 	char *buf;
 
@@ -1215,9 +1239,17 @@ static int sd_create_branch(struct bdrv_sd_state *s)
 
 	eprintf("%" PRIx32 " is created.\n", vid);
 
-	copies = s->inode.nr_copies;
+	fd = connect_to_sdog(s->addr);
+	if (fd < 0) {
+		eprintf("failed to connect\n");
+		goto out;
+	}
+
+	ret = read_object(fd, buf, vid_to_vdi_oid(vid), s->inode.nr_copies,
+			  SD_INODE_SIZE, 0);
+
+	close(fd);
 
-	ret = read_vdi_obj(s->addr, buf, vid, &copies);
 	if (ret < 0)
 		goto out;
 
@@ -1369,11 +1401,11 @@ static BlockDriverAIOCB *sd_aio_readv(BlockDriverState *bs,
 static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
 {
 	struct bdrv_sd_state *s = bs->opaque;
-	int ret, fd, dummy;
-	struct sd_obj_req hdr;
-	unsigned int rlen, wlen;
+	int ret, fd;
 	uint32_t new_vid;
 	struct sd_inode *inode;
+	unsigned int datalen;
+	uint64_t offset;
 
 	sd_release(bs);
 
@@ -1393,6 +1425,9 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
 
 	s->inode.vm_state_size = sn_info->vm_state_size;
 	s->inode.vm_clock_nsec = sn_info->vm_clock_nsec;
+	offset = 0;
+	/* we don't need to read entire object */
+	datalen = SD_INODE_SIZE - sizeof(s->inode.data_vdi_id);
 
 	/* refresh inode. */
 	fd = connect_to_sdog(s->addr);
@@ -1401,30 +1436,14 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
 		goto cleanup;
 	}
 
-	memset(&hdr, 0, sizeof(hdr));
-	hdr.opcode = SD_OP_WRITE_OBJ;
-
-	hdr.oid = vid_to_vdi_oid(s->inode.vdi_id);
-	hdr.copies = s->inode.nr_copies;
-
-	hdr.flags |= SD_FLAG_CMD_WRITE;
-	hdr.data_length = SD_INODE_SIZE;
-	hdr.offset = 0;
-	wlen = SD_INODE_SIZE;
-	rlen = 0;
-
-	ret = do_req(fd, (struct sd_req *)&hdr, &s->inode, &wlen, &rlen);
+	ret = write_object(fd, (char *)&s->inode, vid_to_vdi_oid(s->inode.vdi_id),
+			   s->inode.nr_copies, datalen, offset, 0);
 	if (ret < 0) {
 		eprintf("failed to write snapshot's inode.\n");
 		ret = -EIO;
 		goto cleanup;
 	}
 
-	if (fd < 0) {
-		ret = -EIO;
-		goto cleanup;
-	}
-
 	ret = do_sd_create(s->addr, s->name, NULL, s->inode.vdi_size >> 9,
 			   s->inode.vdi_id, &new_vid, 1);
 	if (ret < 0) {
@@ -1433,19 +1452,24 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
 		goto cleanup;
 	}
 
-	inode = (struct sd_inode *)qemu_malloc(sizeof(struct sd_inode));
+	inode = (struct sd_inode *)qemu_malloc(datalen);
 	if (!inode) {
 		eprintf("failed to allocate memory for inode. %m\n");
 		goto cleanup;
 	}
 
-	if (read_vdi_obj(s->addr, (char *)inode, new_vid, &dummy) < 0) {
+	ret = read_object(fd, (char *)inode, vid_to_vdi_oid(new_vid),
+			  s->inode.nr_copies, datalen, offset);
+
+	close(fd);
+
+	if (ret < 0) {
 		eprintf("failed to read new inode info. %m\n");
 		ret = -EIO;
 		goto cleanup;
 	}
 
-	memcpy(&s->inode, inode, sizeof(struct sd_inode));
+	memcpy(&s->inode, inode, datalen);
 	eprintf("s->inode: name %s snap_id %x oid %x\n",
 		s->inode.name, s->inode.snap_id, s->inode.vdi_id);
 
@@ -1462,7 +1486,7 @@ static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
 	char *buf = NULL;
 	uint32_t vid;
 	uint32_t snapid = 0;
-	int ret = -ENOENT, dummy;
+	int ret = -ENOENT, fd;
 
 	sd_release(bs);
 
@@ -1493,7 +1517,17 @@ static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
 		goto out;
 	}
 
-	ret = read_vdi_obj(s->addr, buf, vid, &dummy);
+	fd = connect_to_sdog(s->addr);
+	if (fd < 0) {
+		eprintf("failed to connect\n");
+		goto out;
+	}
+
+	ret = read_object(fd, buf, vid_to_vdi_oid(vid), s->inode.nr_copies,
+			  SD_INODE_SIZE, 0);
+
+	close(fd);
+
 	if (ret) {
 		ret = -ENOENT;
 		goto out;
@@ -1584,14 +1618,21 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
 
 	start_nr = fnv_64a_buf(s->name, strlen(s->name), FNV1A_64_INIT) & (SD_NR_VDIS - 1);
 
+	fd = connect_to_sdog(s->addr);
+	if (fd < 0) {
+		eprintf("failed to connect\n");
+		goto out;
+	}
+
 	/* TODO: round up */
 	for (i = start_nr; i < SD_NR_VDIS && found < nr; i++) {
-		int copies;
-
 		if (!test_bit(i, vdi_inuse))
 			break;
 
-		ret = read_vdi_obj(s->addr, (char *)&inode, i, &copies);
+		/* we don't need to read entire object */
+		ret = read_object(fd, (char *)&inode, vid_to_vdi_oid(i),
+				  0, SD_INODE_SIZE - sizeof(inode.data_vdi_id), 0);
+
 		if (ret)
 			continue;
 
@@ -1606,6 +1647,8 @@ static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
 			found++;
 		}
 	}
+
+	close(fd);
 out:
 	*psn_tab = sn_tab;
 
@@ -1617,10 +1660,9 @@ out:
 static int do_load_save_vmstate(struct bdrv_sd_state *s, uint8_t *data,
 				int64_t pos, int size, int load)
 {
-	struct sd_obj_req hdr;
-	int fd;
+	int fd, create;
 	int ret = 0;
-	unsigned int rlen = 0, wlen = 0, data_len;
+	unsigned int data_len;
 	uint64_t vmstate_oid;
 	uint32_t vdi_index;
 	uint64_t offset;
@@ -1639,27 +1681,15 @@ static int do_load_save_vmstate(struct bdrv_sd_state *s, uint8_t *data,
 
 		vmstate_oid = vid_to_vmstate_oid(s->inode.vdi_id, vdi_index);
 
-		memset(&hdr, 0, sizeof(hdr));
-		if (load) {
-			hdr.opcode = SD_OP_READ_OBJ;
-			wlen = 0;
-			rlen = data_len;
-			hdr.flags = 0;
-		} else {
-			if (offset)
-				hdr.opcode = SD_OP_WRITE_OBJ;
-			else
-				hdr.opcode = SD_OP_CREATE_AND_WRITE_OBJ;
-			hdr.flags = SD_FLAG_CMD_WRITE;
-			wlen = data_len;
-			rlen = 0;
-		}
-		hdr.oid = vmstate_oid;
-		hdr.copies = s->inode.nr_copies;
-		hdr.data_length = data_len;
-		hdr.offset = offset;
+		create = (offset == 0);
+		if (load)
+			ret = read_object(fd, (char *)data, vmstate_oid,
+					  s->inode.nr_copies, data_len, offset);
+		else
+			ret = write_object(fd, (char *)data, vmstate_oid,
+					   s->inode.nr_copies, data_len, offset, create);
 
-		if (do_req(fd, (struct sd_req *)&hdr, data, &wlen, &rlen) < 0) {
+		if (ret < 0) {
 			eprintf("failed to save vmstate %m\n");
 			ret = -EIO;
 			goto cleanup;
-- 
1.5.6.5




More information about the sheepdog mailing list