[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