Doing so greatly decreases the amount of casting and improves type safety.

Also switch from struct assignments to mempcys in a few places where we copy
them around.

Signed-off-by: Christoph Hellwig <h...@lst.de>

---
 collie/cluster.c         |   14 +-
 collie/common.c          |   26 ++---
 collie/vdi.c             |   79 +++++++--------
 include/sheepdog_proto.h |   85 +++++-----------
 sheep/group.c            |   15 +-
 sheep/object_cache.c     |   35 +++---
 sheep/ops.c              |  162 +++++++++++++++----------------
 sheep/recovery.c         |   11 +-
 sheep/sdnet.c            |   42 +++-----
 sheep/store.c            |  243 ++++++++++++++++++++++++-----------------------
 10 files changed, 350 insertions(+), 362 deletions(-)

Index: sheepdog/collie/cluster.c
===================================================================
--- sheepdog.orig/collie/cluster.c      2012-05-08 15:31:11.768697902 +0200
+++ sheepdog/collie/cluster.c   2012-05-17 11:29:45.467990741 +0200
@@ -124,8 +124,8 @@ static int cluster_format(int argc, char
 static int cluster_info(int argc, char **argv)
 {
        int i, fd, ret;
-       struct sd_vdi_req hdr;
-       struct sd_vdi_rsp *rsp = (struct sd_vdi_rsp *)&hdr;
+       struct sd_req hdr;
+       struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
        unsigned rlen, wlen;
        struct epoch_log *logs;
        int nr_logs, log_length;
@@ -157,7 +157,7 @@ again:
 
        rlen = hdr.data_length;
        wlen = 0;
-       ret = exec_req(fd, (struct sd_req *)&hdr, logs, &wlen, &rlen);
+       ret = exec_req(fd, &hdr, logs, &wlen, &rlen);
        close(fd);
 
        if (ret != 0)
@@ -247,8 +247,8 @@ static int cluster_shutdown(int argc, ch
 static int restore_snap(uint32_t epoch)
 {
        int fd, ret;
-       struct sd_obj_req hdr;
-       struct sd_obj_rsp *rsp = (struct sd_obj_rsp *)&hdr;
+       struct sd_req hdr;
+       struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
        unsigned rlen, wlen;
 
        fd = connect_to(sdhost, sdport);
@@ -258,11 +258,11 @@ static int restore_snap(uint32_t epoch)
        memset(&hdr, 0, sizeof(hdr));
 
        hdr.opcode = SD_OP_RESTORE;
-       hdr.tgt_epoch = epoch;
+       hdr.obj.tgt_epoch = epoch;
 
        rlen = 0;
        wlen = 0;
-       ret = exec_req(fd, (struct sd_req *)&hdr, NULL, &wlen, &rlen);
+       ret = exec_req(fd, &hdr, NULL, &wlen, &rlen);
        close(fd);
 
        if (ret) {
Index: sheepdog/collie/common.c
===================================================================
--- sheepdog.orig/collie/common.c       2012-05-11 11:20:10.000000000 +0200
+++ sheepdog/collie/common.c    2012-05-17 11:29:45.467990741 +0200
@@ -45,8 +45,8 @@ char *size_to_str(uint64_t _size, char *
 int sd_read_object(uint64_t oid, void *data, unsigned int datalen,
                   uint64_t offset)
 {
-       struct sd_obj_req hdr;
-       struct sd_obj_rsp *rsp = (struct sd_obj_rsp *)&hdr;
+       struct sd_req hdr;
+       struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
        int fd, ret;
        unsigned wlen = 0, rlen = datalen;
 
@@ -59,12 +59,13 @@ int sd_read_object(uint64_t oid, void *d
        memset(&hdr, 0, sizeof(hdr));
        hdr.epoch = node_list_version;
        hdr.opcode = SD_OP_READ_OBJ;
-       hdr.oid = oid;
        hdr.flags = SD_FLAG_CMD_WEAK_CONSISTENCY;
        hdr.data_length = rlen;
-       hdr.offset = offset;
 
-       ret = exec_req(fd, (struct sd_req *)&hdr, data, &wlen, &rlen);
+       hdr.obj.oid = oid;
+       hdr.obj.offset = offset;
+
+       ret = exec_req(fd, &hdr, data, &wlen, &rlen);
        close(fd);
 
        if (ret) {
@@ -84,8 +85,8 @@ int sd_read_object(uint64_t oid, void *d
 int sd_write_object(uint64_t oid, uint64_t cow_oid, void *data, unsigned int 
datalen,
                    uint64_t offset, uint32_t flags, int copies, int create)
 {
-       struct sd_obj_req hdr;
-       struct sd_obj_rsp *rsp = (struct sd_obj_rsp *)&hdr;
+       struct sd_req hdr;
+       struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
        int fd, ret;
        unsigned wlen = datalen, rlen;
 
@@ -101,14 +102,15 @@ int sd_write_object(uint64_t oid, uint64
                hdr.opcode = SD_OP_CREATE_AND_WRITE_OBJ;
        else
                hdr.opcode = SD_OP_WRITE_OBJ;
-       hdr.oid = oid;
-       hdr.cow_oid = cow_oid;
-       hdr.copies = copies;
        hdr.data_length = wlen;
        hdr.flags = (flags & ~SD_FLAG_CMD_IO_LOCAL) | SD_FLAG_CMD_WRITE;
-       hdr.offset = offset;
 
-       ret = exec_req(fd, (struct sd_req *)&hdr, data, &wlen, &rlen);
+       hdr.obj.copies = copies;
+       hdr.obj.oid = oid;
+       hdr.obj.cow_oid = cow_oid;
+       hdr.obj.offset = offset;
+
+       ret = exec_req(fd, &hdr, data, &wlen, &rlen);
        close(fd);
 
        if (ret) {
Index: sheepdog/collie/vdi.c
===================================================================
--- sheepdog.orig/collie/vdi.c  2012-05-16 18:16:10.000000000 +0200
+++ sheepdog/collie/vdi.c       2012-05-17 11:29:45.467990741 +0200
@@ -197,15 +197,15 @@ static void get_oid(uint32_t vid, char *
 }
 
 typedef int (*obj_parser_func_t)(char *sheep, uint64_t oid,
-                                 struct sd_obj_rsp *rsp, char *buf, void 
*data);
+                                 struct sd_rsp *rsp, char *buf, void *data);
 
-static int do_print_obj(char *sheep, uint64_t oid, struct sd_obj_rsp *rsp,
+static int do_print_obj(char *sheep, uint64_t oid, struct sd_rsp *rsp,
                         char *buf, void *data)
 {
        switch (rsp->result) {
        case SD_RES_SUCCESS:
                printf("%s has the object (should be %d copies)\n",
-                      sheep, rsp->copies);
+                      sheep, rsp->obj.copies);
                break;
        case SD_RES_NO_OBJ:
                printf("%s doesn't have the object\n", sheep);
@@ -229,7 +229,7 @@ struct get_data_oid_info {
        unsigned idx;
 };
 
-static int get_data_oid(char *sheep, uint64_t oid, struct sd_obj_rsp *rsp,
+static int get_data_oid(char *sheep, uint64_t oid, struct sd_rsp *rsp,
                         char *buf, void *data)
 {
        struct get_data_oid_info *info = data;
@@ -274,8 +274,8 @@ static void parse_objs(uint64_t oid, obj
 
        for (i = 0; i < nr_nodes; i++) {
                unsigned wlen = 0, rlen = size;
-               struct sd_obj_req hdr;
-               struct sd_obj_rsp *rsp = (struct sd_obj_rsp *)&hdr;
+               struct sd_req hdr;
+               struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
 
                addr_to_str(name, sizeof(name), node_list_entries[i].addr, 0);
 
@@ -288,10 +288,11 @@ static void parse_objs(uint64_t oid, obj
                hdr.opcode = SD_OP_READ_OBJ;
                hdr.data_length = rlen;
                hdr.flags = SD_FLAG_CMD_IO_LOCAL;
-               hdr.oid = oid;
                hdr.epoch = node_list_version;
 
-               ret = exec_req(fd, (struct sd_req *)&hdr, buf, &wlen, &rlen);
+               hdr.obj.oid = oid;
+
+               ret = exec_req(fd, &hdr, buf, &wlen, &rlen);
                close(fd);
 
                sprintf(name + strlen(name), ":%d", node_list_entries[i].port);
@@ -360,8 +361,8 @@ static int find_vdi_name(char *vdiname,
                         uint32_t *vid, int for_snapshot)
 {
        int ret, fd;
-       struct sd_vdi_req hdr;
-       struct sd_vdi_rsp *rsp = (struct sd_vdi_rsp *)&hdr;
+       struct sd_req hdr;
+       struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
        unsigned int wlen, rlen = 0;
        char buf[SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN];
 
@@ -381,10 +382,10 @@ static int find_vdi_name(char *vdiname,
        wlen = SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN;
        hdr.proto_ver = SD_PROTO_VER;
        hdr.data_length = wlen;
-       hdr.snapid = snapid;
        hdr.flags = SD_FLAG_CMD_WRITE;
+       hdr.vdi.snapid = snapid;
 
-       ret = exec_req(fd, (struct sd_req *)&hdr, buf, &wlen, &rlen);
+       ret = exec_req(fd, &hdr, buf, &wlen, &rlen);
        if (ret) {
                ret = -1;
                goto out;
@@ -396,7 +397,7 @@ static int find_vdi_name(char *vdiname,
                ret = -1;
                goto out;
        }
-       *vid = rsp->vdi_id;
+       *vid = rsp->vdi.vdi_id;
 
        ret = 0;
 out:
@@ -407,8 +408,8 @@ out:
 static int do_vdi_create(char *vdiname, int64_t vdi_size, uint32_t base_vid,
                         uint32_t *vdi_id, int snapshot)
 {
-       struct sd_vdi_req hdr;
-       struct sd_vdi_rsp *rsp = (struct sd_vdi_rsp *)&hdr;
+       struct sd_req hdr;
+       struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
        int fd, ret;
        unsigned int wlen, rlen = 0;
        char buf[SD_MAX_VDI_LEN];
@@ -422,19 +423,18 @@ static int do_vdi_create(char *vdiname,
        memset(buf, 0, sizeof(buf));
        strncpy(buf, vdiname, SD_MAX_VDI_LEN);
 
-       memset(&hdr, 0, sizeof(hdr));
-       hdr.opcode = SD_OP_NEW_VDI;
-       hdr.base_vdi_id = base_vid;
-
        wlen = SD_MAX_VDI_LEN;
 
+       memset(&hdr, 0, sizeof(hdr));
+       hdr.opcode = SD_OP_NEW_VDI;
        hdr.flags = SD_FLAG_CMD_WRITE;
-       hdr.snapid = snapshot;
-
        hdr.data_length = wlen;
-       hdr.vdi_size = vdi_size;
 
-       ret = exec_req(fd, (struct sd_req *)&hdr, buf, &wlen, &rlen);
+       hdr.vdi.base_vdi_id = base_vid;
+       hdr.vdi.snapid = snapshot;
+       hdr.vdi.vdi_size = vdi_size;
+
+       ret = exec_req(fd, &hdr, buf, &wlen, &rlen);
 
        close(fd);
 
@@ -450,7 +450,7 @@ static int do_vdi_create(char *vdiname,
        }
 
        if (vdi_id)
-               *vdi_id = rsp->vdi_id;
+               *vdi_id = rsp->vdi.vdi_id;
 
        return EXIT_SUCCESS;
 }
@@ -703,8 +703,8 @@ static int vdi_delete(int argc, char **a
 {
        char *data = argv[optind];
        int fd, ret;
-       struct sd_vdi_req hdr;
-       struct sd_vdi_rsp *rsp = (struct sd_vdi_rsp *)&hdr;
+       struct sd_req hdr;
+       struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
        unsigned rlen, wlen;
        char vdiname[SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN];
 
@@ -718,16 +718,16 @@ static int vdi_delete(int argc, char **a
        wlen = sizeof(vdiname);
 
        hdr.opcode = SD_OP_DEL_VDI;
-       hdr.snapid = vdi_cmd_data.snapshot_id;
        hdr.epoch = node_list_version;
        hdr.flags = SD_FLAG_CMD_WRITE;
        hdr.data_length = wlen;
+       hdr.vdi.snapid = vdi_cmd_data.snapshot_id;
        memset(vdiname, 0, sizeof(vdiname));
        strncpy(vdiname, data, SD_MAX_VDI_LEN);
        strncpy(vdiname + SD_MAX_VDI_LEN, vdi_cmd_data.snapshot_tag,
                SD_MAX_VDI_TAG_LEN);
 
-       ret = exec_req(fd, (struct sd_req *)&hdr, vdiname, &wlen, &rlen);
+       ret = exec_req(fd, &hdr, vdiname, &wlen, &rlen);
        close(fd);
 
        if (ret) {
@@ -806,8 +806,8 @@ static int vdi_object(int argc, char **a
 static int print_obj_epoch(uint64_t oid)
 {
        int i, j, fd, ret, idx;
-       struct sd_vdi_req hdr;
-       struct sd_vdi_rsp *rsp = (struct sd_vdi_rsp *)&hdr;
+       struct sd_req hdr;
+       struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
        unsigned rlen, wlen;
        struct sd_vnode vnodes[SD_MAX_VNODES];
        int idx_buf[SD_MAX_COPIES];
@@ -839,7 +839,7 @@ again:
 
        rlen = hdr.data_length;
        wlen = 0;
-       ret = exec_req(fd, (struct sd_req *)&hdr, logs, &wlen, &rlen);
+       ret = exec_req(fd, &hdr, logs, &wlen, &rlen);
        close(fd);
 
        if (ret != 0)
@@ -934,8 +934,8 @@ static int find_vdi_attr_oid(char *vdina
                             uint32_t *vid, uint64_t *oid, unsigned int 
*nr_copies,
                             int creat, int excl, int delete)
 {
-       struct sd_vdi_req hdr;
-       struct sd_vdi_rsp *rsp = (struct sd_vdi_rsp *)&hdr;
+       struct sd_req hdr;
+       struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
        int fd, ret;
        unsigned int wlen, rlen;
        struct sheepdog_vdi_attr vattr;
@@ -960,9 +960,10 @@ static int find_vdi_attr_oid(char *vdina
        wlen = SD_ATTR_OBJ_SIZE;
        rlen = 0;
        hdr.proto_ver = SD_PROTO_VER;
-       hdr.data_length = wlen;
-       hdr.snapid = vdi_cmd_data.snapshot_id;
        hdr.flags = SD_FLAG_CMD_WRITE;
+       hdr.data_length = wlen;
+       hdr.vdi.snapid = vdi_cmd_data.snapshot_id;
+
        if (creat)
                hdr.flags |= SD_FLAG_CMD_CREAT;
        if (excl)
@@ -970,7 +971,7 @@ static int find_vdi_attr_oid(char *vdina
        if (delete)
                hdr.flags |= SD_FLAG_CMD_DEL;
 
-       ret = exec_req(fd, (struct sd_req *)&hdr, &vattr, &wlen, &rlen);
+       ret = exec_req(fd, &hdr, &vattr, &wlen, &rlen);
        if (ret) {
                ret = SD_RES_EIO;
                goto out;
@@ -981,9 +982,9 @@ static int find_vdi_attr_oid(char *vdina
                goto out;
        }
 
-       *vid = rsp->vdi_id;
-       *oid = vid_to_attr_oid(rsp->vdi_id, rsp->attr_id);
-       *nr_copies = rsp->copies;
+       *vid = rsp->vdi.vdi_id;
+       *oid = vid_to_attr_oid(rsp->vdi.vdi_id, rsp->vdi.attr_id);
+       *nr_copies = rsp->vdi.copies;
 
        ret = SD_RES_SUCCESS;
 out:
Index: sheepdog/include/sheepdog_proto.h
===================================================================
--- sheepdog.orig/include/sheepdog_proto.h      2012-05-16 14:08:53.000000000 
+0200
+++ sheepdog/include/sheepdog_proto.h   2012-05-17 11:29:45.467990741 +0200
@@ -106,7 +106,22 @@ struct sd_req {
        uint32_t        epoch;
        uint32_t        id;
        uint32_t        data_length;
-       uint32_t        opcode_specific[8];
+       union {
+               struct {
+                       uint64_t        oid;
+                       uint64_t        cow_oid;
+                       uint32_t        copies;
+                       uint32_t        tgt_epoch;
+                       uint64_t        offset;
+               } obj;
+               struct {
+                       uint64_t        vdi_size;
+                       uint32_t        base_vdi_id;
+                       uint32_t        copies;
+                       uint32_t        snapid;
+               } vdi;
+               uint32_t                __pad[8];
+       };
 };
 
 struct sd_rsp {
@@ -117,62 +132,18 @@ struct sd_rsp {
        uint32_t        id;
        uint32_t        data_length;
        uint32_t        result;
-       uint32_t        opcode_specific[7];
-};
-
-struct sd_obj_req {
-       uint8_t         proto_ver;
-       uint8_t         opcode;
-       uint16_t        flags;
-       uint32_t        epoch;
-       uint32_t        id;
-       uint32_t        data_length;
-       uint64_t        oid;
-       uint64_t        cow_oid;
-       uint32_t        copies;
-       uint32_t        tgt_epoch;
-       uint64_t        offset;
-};
-
-struct sd_obj_rsp {
-       uint8_t         proto_ver;
-       uint8_t         opcode;
-       uint16_t        flags;
-       uint32_t        epoch;
-       uint32_t        id;
-       uint32_t        data_length;
-       uint32_t        result;
-       uint32_t        copies;
-       uint32_t        pad[6];
-};
-
-struct sd_vdi_req {
-       uint8_t         proto_ver;
-       uint8_t         opcode;
-       uint16_t        flags;
-       uint32_t        epoch;
-       uint32_t        id;
-       uint32_t        data_length;
-       uint64_t        vdi_size;
-       uint32_t        base_vdi_id;
-       uint32_t        copies;
-       uint32_t        snapid;
-       uint32_t        pad[3];
-};
-
-struct sd_vdi_rsp {
-       uint8_t         proto_ver;
-       uint8_t         opcode;
-       uint16_t        flags;
-       uint32_t        epoch;
-       uint32_t        id;
-       uint32_t        data_length;
-       uint32_t        result;
-       uint32_t        rsvd;
-       uint32_t        vdi_id;
-       uint32_t        attr_id;
-       uint32_t        copies;
-       uint32_t        pad[3];
+       union {
+               struct {
+                       uint32_t        copies;
+               } obj;
+               struct {
+                       uint32_t        rsvd;
+                       uint32_t        vdi_id;
+                       uint32_t        attr_id;
+                       uint32_t        copies;
+               } vdi;
+               uint32_t                __pad[7];
+       };
 };
 
 struct sheepdog_inode {
Index: sheepdog/sheep/group.c
===================================================================
--- sheepdog.orig/sheep/group.c 2012-05-17 11:28:37.000000000 +0200
+++ sheepdog/sheep/group.c      2012-05-17 11:37:43.467986184 +0200
@@ -59,8 +59,8 @@ struct join_message {
 };
 
 struct vdi_op_message {
-       struct sd_vdi_req req;
-       struct sd_vdi_rsp rsp;
+       struct sd_req req;
+       struct sd_rsp rsp;
        uint8_t data[0];
 };
 
@@ -1070,7 +1070,7 @@ int is_access_to_busy_objects(uint64_t o
 
 static int need_consistency_check(struct request *req)
 {
-       struct sd_obj_req *hdr = (struct sd_obj_req *)&req->rq;
+       struct sd_req *hdr = &req->rq;
 
        if (hdr->flags & SD_FLAG_CMD_IO_LOCAL)
                /* only gateway fixes data consistency */
@@ -1084,11 +1084,11 @@ static int need_consistency_check(struct
        if (hdr->flags & SD_FLAG_CMD_WEAK_CONSISTENCY)
                return 0;
 
-       if (is_vdi_obj(hdr->oid))
+       if (is_vdi_obj(hdr->obj.oid))
                /* only check consistency for data objects */
                return 0;
 
-       if (sys->enable_write_cache && object_is_cached(hdr->oid))
+       if (sys->enable_write_cache && object_is_cached(hdr->obj.oid))
                /* we don't check consistency for cached objects */
                return 0;
 
@@ -1097,9 +1097,8 @@ static int need_consistency_check(struct
 
 static inline void set_consistency_check(struct request *req)
 {
-       struct sd_obj_req *hdr = (struct sd_obj_req *)&req->rq;
-       uint32_t vdi_id = oid_to_vid(hdr->oid);
-       uint32_t idx = data_oid_to_idx(hdr->oid);
+       uint32_t vdi_id = oid_to_vid(req->rq.obj.oid);
+       uint32_t idx = data_oid_to_idx(req->rq.obj.oid);
        struct data_object_bmap *bmap;
 
        req->check_consistency = 1;
Index: sheepdog/sheep/object_cache.c
===================================================================
--- sheepdog.orig/sheep/object_cache.c  2012-05-17 11:16:55.000000000 +0200
+++ sheepdog/sheep/object_cache.c       2012-05-17 12:15:58.411964297 +0200
@@ -328,25 +328,28 @@ out:
 
 int object_cache_rw(struct object_cache *oc, uint32_t idx, struct request *req)
 {
-       struct sd_obj_req *hdr = (struct sd_obj_req *)&req->rq;
-       struct sd_obj_rsp *rsp = (struct sd_obj_rsp *)&req->rp;
+       struct sd_req *hdr = &req->rq;
        uint64_t bmap = 0;
        int ret;
 
-       dprintf("%08"PRIx32", len %"PRIu32", off %"PRIu64"\n", idx, 
hdr->data_length, hdr->offset);
+       dprintf("%08"PRIx32", len %"PRIu32", off %"PRIu64"\n", idx,
+               hdr->data_length, hdr->obj.offset);
+
        if (hdr->flags & SD_FLAG_CMD_WRITE) {
-               ret = write_cache_object(oc->vid, idx, req->data, 
hdr->data_length, hdr->offset);
+               ret = write_cache_object(oc->vid, idx, req->data,
+                                        hdr->data_length, hdr->obj.offset);
                if (ret != SD_RES_SUCCESS)
                        goto out;
-               bmap = calc_object_bmap(hdr->data_length, hdr->offset);
+               bmap = calc_object_bmap(hdr->data_length, hdr->obj.offset);
                pthread_mutex_lock(&oc->lock);
                add_to_dirty_tree_and_list(oc, idx, bmap, NULL, 0);
                pthread_mutex_unlock(&oc->lock);
        } else {
-               ret = read_cache_object(oc->vid, idx, req->data, 
hdr->data_length, hdr->offset);
+               ret = read_cache_object(oc->vid, idx, req->data,
+                                       hdr->data_length, hdr->obj.offset);
                if (ret != SD_RES_SUCCESS)
                        goto out;
-               rsp->data_length = hdr->data_length;
+               req->rp.data_length = hdr->data_length;
        }
 out:
        return ret;
@@ -403,8 +406,8 @@ int object_cache_pull(struct vnode_info
        int i, fd, ret = SD_RES_NO_MEM;
        unsigned wlen = 0, rlen, data_length, read_len;
        uint64_t oid;
-       struct sd_obj_req hdr = { 0 };
-       struct sd_obj_rsp *rsp = (struct sd_obj_rsp *)&hdr;
+       struct sd_req hdr = { 0 };
+       struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
        struct sd_vnode *v;
        struct sd_vnode *vnodes[SD_MAX_COPIES];
        void *buf;
@@ -460,10 +463,10 @@ pull_remote:
                        continue;
 
                hdr.opcode = SD_OP_READ_OBJ;
-               hdr.oid = oid;
                hdr.epoch = sys->epoch;
                hdr.data_length = rlen = data_length;
                hdr.flags = SD_FLAG_CMD_IO_LOCAL;
+               hdr.obj.oid = oid;
 
                fd = get_sheep_fd(v->addr, v->port, v->node_idx,
                                  hdr.epoch);
@@ -503,7 +506,7 @@ static int push_cache_object(struct vnod
                uint32_t idx, uint64_t bmap, int create)
 {
        struct request fake_req;
-       struct sd_obj_req *hdr = (struct sd_obj_req *)&fake_req.rq;
+       struct sd_req *hdr = &fake_req.rq;
        void *buf;
        off_t offset;
        unsigned data_length;
@@ -545,13 +548,15 @@ static int push_cache_object(struct vnod
        if (ret != SD_RES_SUCCESS)
                goto out;
 
-       hdr->offset = 0;
-       hdr->data_length = data_length;
        hdr->opcode = create ? SD_OP_CREATE_AND_WRITE_OBJ : SD_OP_WRITE_OBJ;
        hdr->flags = SD_FLAG_CMD_WRITE;
-       hdr->oid = oid;
-       hdr->copies = sys->nr_copies;
+       hdr->data_length = data_length;
        hdr->epoch = sys->epoch;
+
+       hdr->obj.oid = oid;
+       hdr->obj.offset = 0;
+       hdr->obj.copies = sys->nr_copies;
+
        fake_req.data = buf;
        fake_req.op = get_sd_op(hdr->opcode);
        fake_req.vnodes = vnode_info;
Index: sheepdog/sheep/ops.c
===================================================================
--- sheepdog.orig/sheep/ops.c   2012-05-17 11:16:55.000000000 +0200
+++ sheepdog/sheep/ops.c        2012-05-17 12:13:38.775965628 +0200
@@ -121,17 +121,17 @@ out:
 
 static int cluster_new_vdi(struct request *req)
 {
-       const struct sd_vdi_req *hdr = (const struct sd_vdi_req *)&req->rq;
-       struct sd_vdi_rsp *vdi_rsp = (struct sd_vdi_rsp *)&req->rp;
+       const struct sd_req *hdr = &req->rq;
+       struct sd_rsp *rsp = &req->rp;
        uint32_t vid = 0, nr_copies = sys->nr_copies;
        int ret;
 
        ret = add_vdi(req->vnodes, hdr->epoch, req->data, hdr->data_length,
-                     hdr->vdi_size, &vid, hdr->base_vdi_id, hdr->copies,
-                     hdr->snapid, &nr_copies);
+                     hdr->vdi.vdi_size, &vid, hdr->vdi.base_vdi_id,
+                     hdr->vdi.copies, hdr->vdi.snapid, &nr_copies);
 
-       vdi_rsp->vdi_id = vid;
-       vdi_rsp->copies = nr_copies;
+       rsp->vdi.vdi_id = vid;
+       rsp->vdi.copies = nr_copies;
 
        return ret;
 }
@@ -139,9 +139,8 @@ static int cluster_new_vdi(struct reques
 static int post_cluster_new_vdi(const struct sd_req *req, struct sd_rsp *rsp,
                                void *data)
 {
-       struct sd_vdi_rsp *vdi_rsp = (struct sd_vdi_rsp *)rsp;
-       unsigned long nr = vdi_rsp->vdi_id;
-       int ret = vdi_rsp->result;
+       unsigned long nr = rsp->vdi.vdi_id;
+       int ret = rsp->result;
 
        vprintf(SDOG_INFO, "done %d %ld\n", ret, nr);
        set_bit(nr, sys->vdi_inuse);
@@ -151,26 +150,27 @@ static int post_cluster_new_vdi(const st
 
 static int cluster_del_vdi(struct request *req)
 {
-       const struct sd_vdi_req *hdr = (const struct sd_vdi_req *)&req->rq;
-       struct sd_vdi_rsp *vdi_rsp = (struct sd_vdi_rsp *)&req->rp;
+       const struct sd_req *hdr = &req->rq;
+       struct sd_rsp *rsp = &req->rp;
        uint32_t vid = 0, nr_copies = sys->nr_copies;
        int ret;
 
        ret = del_vdi(req->vnodes, hdr->epoch, req->data, hdr->data_length,
-                     &vid, hdr->snapid, &nr_copies);
+                     &vid, hdr->vdi.snapid, &nr_copies);
 
        if (sys->enable_write_cache && ret == SD_RES_SUCCESS)
                object_cache_delete(vid);
-       vdi_rsp->vdi_id = vid;
-       vdi_rsp->copies = nr_copies;
+
+       rsp->vdi.vdi_id = vid;
+       rsp->vdi.copies = nr_copies;
 
        return ret;
 }
 
 static int cluster_get_vdi_info(struct request *req)
 {
-       const struct sd_vdi_req *hdr = (const struct sd_vdi_req *)&req->rq;
-       struct sd_vdi_rsp *vdi_rsp = (struct sd_vdi_rsp *)&req->rp;
+       const struct sd_req *hdr = &req->rq;
+       struct sd_rsp *rsp = &req->rp;
        uint32_t vid = 0, nr_copies = sys->nr_copies;
        void *tag;
        int ret;
@@ -186,12 +186,12 @@ static int cluster_get_vdi_info(struct r
                return SD_RES_INVALID_PARMS;
 
        ret = lookup_vdi(req->vnodes, hdr->epoch, req->data, tag, &vid,
-                        hdr->snapid, &nr_copies, NULL);
+                        hdr->vdi.snapid, &nr_copies, NULL);
        if (ret != SD_RES_SUCCESS)
                return ret;
 
-       vdi_rsp->vdi_id = vid;
-       vdi_rsp->copies = nr_copies;
+       rsp->vdi.vdi_id = vid;
+       rsp->vdi.copies = nr_copies;
 
        return ret;
 }
@@ -284,8 +284,8 @@ static int cluster_shutdown(const struct
 
 static int cluster_get_vdi_attr(struct request *req)
 {
-       const struct sd_vdi_req *hdr = (const struct sd_vdi_req *)&req->rq;
-       struct sd_vdi_rsp *vdi_rsp = (struct sd_vdi_rsp *)&req->rp;
+       const struct sd_req *hdr = &req->rq;
+       struct sd_rsp *rsp = &req->rp;
        uint32_t vid = 0, attrid = 0, nr_copies = sys->nr_copies;
        uint64_t created_time = 0;
        int ret;
@@ -293,7 +293,7 @@ static int cluster_get_vdi_attr(struct r
 
        vattr = req->data;
        ret = lookup_vdi(req->vnodes, hdr->epoch, vattr->name, vattr->tag,
-                        &vid, hdr->snapid, &nr_copies, &created_time);
+                        &vid, hdr->vdi.snapid, &nr_copies, &created_time);
        if (ret != SD_RES_SUCCESS)
                return ret;
 
@@ -307,9 +307,9 @@ static int cluster_get_vdi_attr(struct r
                           hdr->flags & SD_FLAG_CMD_EXCL,
                           hdr->flags & SD_FLAG_CMD_DEL);
 
-       vdi_rsp->vdi_id = vid;
-       vdi_rsp->attr_id = attrid;
-       vdi_rsp->copies = nr_copies;
+       rsp->vdi.vdi_id = vid;
+       rsp->vdi.attr_id = attrid;
+       rsp->vdi.copies = nr_copies;
 
        return ret;
 }
@@ -442,20 +442,18 @@ static int local_get_obj_list(struct req
 
 static int local_get_epoch(struct request *req)
 {
-       const struct sd_obj_req *obj_req = (const struct sd_obj_req *)&req->rq;
-       struct sd_obj_rsp *obj_rsp = (struct sd_obj_rsp *)&req->rp;
-       uint32_t epoch = obj_req->tgt_epoch;
+       uint32_t epoch = req->rq.obj.tgt_epoch;
        int len, ret;
 
        dprintf("%d\n", epoch);
 
-       len = epoch_log_read(epoch, req->data, obj_req->data_length);
+       len = epoch_log_read(epoch, req->data, req->rq.data_length);
        if (len == -1) {
                ret = SD_RES_NO_TAG;
-               obj_rsp->data_length = 0;
+               req->rp.data_length = 0;
        } else {
                ret = SD_RES_SUCCESS;
-               obj_rsp->data_length = len;
+               req->rp.data_length = len;
        }
        return ret;
 }
@@ -545,9 +543,8 @@ static int cluster_cleanup(const struct
 static int cluster_restore(const struct sd_req *req, struct sd_rsp *rsp,
                           void *data)
 {
-       const struct sd_obj_req *hdr = (const struct sd_obj_req *)req;
        int ret;
-       struct siocb iocb = { .epoch = hdr->tgt_epoch };
+       struct siocb iocb = { .epoch = req->obj.tgt_epoch };
 
        if (sd_store->restore)
                ret = sd_store->restore(&iocb);
@@ -591,8 +588,7 @@ static void flush_vdi_done(struct work *
 
 static int local_flush_vdi(struct request *req)
 {
-       struct sd_obj_req *hdr = (struct sd_obj_req *)&req->rq;
-       uint64_t oid = hdr->oid;
+       uint64_t oid = req->rq.obj.oid;
        uint32_t vid = oid_to_vid(oid);
        struct object_cache *cache;
 
@@ -642,19 +638,20 @@ static int read_copy_from_replica(struct
                                  uint64_t oid, char *buf)
 {
        int i, nr_copies, ret;
-       unsigned wlen, rlen;
-       char name[128];
-       struct sd_vnode *v;
+       struct sd_req hdr;
+       struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
        struct sd_vnode *obj_vnodes[SD_MAX_COPIES];
-       struct sd_obj_req hdr;
-       struct sd_obj_rsp *rsp = (struct sd_obj_rsp *)&hdr;
-       struct siocb iocb;
-       int fd;
 
        nr_copies = get_nr_copies(req->vnodes);
        oid_to_vnodes(req->vnodes, oid, nr_copies, obj_vnodes);
 
        for (i = 0; i < nr_copies; i++) {
+               struct sd_vnode *v;
+               struct siocb iocb;
+               char name[128];
+               unsigned wlen, rlen;
+               int fd;
+
                v = obj_vnodes[i];
                addr_to_str(name, sizeof(name), v->addr, 0);
 
@@ -679,16 +676,17 @@ static int read_copy_from_replica(struct
                if (fd < 0)
                        continue;
 
-               memset(&hdr, 0, sizeof(hdr));
-               hdr.opcode = SD_OP_READ_OBJ;
-               hdr.oid = oid;
-               hdr.epoch = epoch;
-
                rlen = SD_DATA_OBJ_SIZE;
                wlen = 0;
+
+               memset(&hdr, 0, sizeof(hdr));
+               hdr.opcode = SD_OP_READ_OBJ;
                hdr.flags = SD_FLAG_CMD_IO_LOCAL;
+               hdr.epoch = epoch;
                hdr.data_length = rlen;
-               hdr.offset = 0;
+
+               hdr.obj.oid = oid;
+               hdr.obj.offset = 0;
 
                ret = exec_req(fd, (struct sd_req *)&hdr, buf, &wlen, &rlen);
 
@@ -714,13 +712,13 @@ out:
 
 static int store_remove_obj(struct request *req)
 {
-       struct sd_obj_req *hdr = (struct sd_obj_req *)&req->rq;
-       uint32_t epoch = hdr->epoch;
+       uint32_t epoch = req->rq.epoch;
+       uint64_t oid = req->rq.obj.oid;
        struct strbuf buf = STRBUF_INIT;
        int ret = SD_RES_SUCCESS;
 
        get_store_dir(&buf, epoch);
-       strbuf_addf(&buf, "%016" PRIx64, hdr->oid);
+       strbuf_addf(&buf, "%016" PRIx64, oid);
        if (unlink(buf.buf) < 0) {
                if (errno == ENOENT) {
                        ret = SD_RES_NO_OBJ;
@@ -730,7 +728,7 @@ static int store_remove_obj(struct reque
                ret =  SD_RES_EIO;
        }
        pthread_rwlock_wrlock(&obj_list_cache.lock);
-       if (!objlist_cache_rb_remove(&obj_list_cache.root, hdr->oid))
+       if (!objlist_cache_rb_remove(&obj_list_cache.root, oid))
                obj_list_cache.cache_size--;
        pthread_rwlock_unlock(&obj_list_cache.lock);
  out:
@@ -740,8 +738,8 @@ static int store_remove_obj(struct reque
 
 static int store_read_obj(struct request *req)
 {
-       struct sd_obj_req *hdr = (struct sd_obj_req *)&req->rq;
-       struct sd_obj_rsp *rsps = (struct sd_obj_rsp *)&req->rp;
+       struct sd_req *hdr = &req->rq;
+       struct sd_rsp *rsp = &req->rp;
        int ret;
        uint32_t epoch = hdr->epoch;
        struct siocb iocb;
@@ -749,41 +747,41 @@ static int store_read_obj(struct request
        memset(&iocb, 0, sizeof(iocb));
        iocb.epoch = epoch;
        iocb.flags = hdr->flags;
-       ret = sd_store->open(hdr->oid, &iocb, 0);
+       ret = sd_store->open(hdr->obj.oid, &iocb, 0);
        if (ret != SD_RES_SUCCESS)
                return ret;
 
        iocb.buf = req->data;
        iocb.length = hdr->data_length;
-       iocb.offset = hdr->offset;
-       ret = sd_store->read(hdr->oid, &iocb);
+       iocb.offset = hdr->obj.offset;
+       ret = sd_store->read(hdr->obj.oid, &iocb);
        if (ret != SD_RES_SUCCESS)
                goto out;
 
-       rsps->data_length = hdr->data_length;
-       rsps->copies = sys->nr_copies;
+       rsp->data_length = hdr->data_length;
+       rsp->obj.copies = sys->nr_copies;
 out:
-       sd_store->close(hdr->oid, &iocb);
+       sd_store->close(hdr->obj.oid, &iocb);
        return ret;
 }
 
-static int do_write_obj(struct siocb *iocb, struct sd_obj_req *req, uint32_t 
epoch, void *data)
+static int do_write_obj(struct siocb *iocb, struct sd_req *hdr, uint32_t epoch,
+               void *data)
 {
-       struct sd_obj_req *hdr = (struct sd_obj_req *)req;
-       uint64_t oid = hdr->oid;
+       uint64_t oid = hdr->obj.oid;
        int ret = SD_RES_SUCCESS;
        void *jd = NULL;
 
        iocb->buf = data;
        iocb->length = hdr->data_length;
-       iocb->offset = hdr->offset;
+       iocb->offset = hdr->obj.offset;
        if (is_vdi_obj(oid)) {
                struct strbuf buf = STRBUF_INIT;
 
                get_store_dir(&buf, epoch);
                strbuf_addf(&buf, "%016" PRIx64, oid);
-               jd = jrnl_begin(data, hdr->data_length,
-                                  hdr->offset, buf.buf, jrnl_path);
+               jd = jrnl_begin(data, hdr->data_length, hdr->obj.offset,
+                               buf.buf, jrnl_path);
                if (!jd) {
                        strbuf_release(&buf);
                        return SD_RES_EIO;
@@ -799,7 +797,7 @@ static int do_write_obj(struct siocb *io
 
 static int store_write_obj(struct request *req)
 {
-       struct sd_obj_req *hdr = (struct sd_obj_req *)&req->rq;
+       struct sd_req *hdr = &req->rq;
        int ret;
        uint32_t epoch = hdr->epoch;
        struct siocb iocb;
@@ -807,29 +805,30 @@ static int store_write_obj(struct reques
        memset(&iocb, 0, sizeof(iocb));
        iocb.epoch = epoch;
        iocb.flags = hdr->flags;
-       ret = sd_store->open(hdr->oid, &iocb, 0);
+       ret = sd_store->open(hdr->obj.oid, &iocb, 0);
        if (ret != SD_RES_SUCCESS)
                return ret;
 
        ret = do_write_obj(&iocb, hdr, epoch, req->data);
 
-       sd_store->close(hdr->oid, &iocb);
+       sd_store->close(hdr->obj.oid, &iocb);
        return ret;
 }
 
 static int store_create_and_write_obj(struct request *req)
 {
-       struct sd_obj_req *hdr = (struct sd_obj_req *)&req->rq;
-       struct sd_obj_req cow_hdr;
-       int ret;
+       struct sd_req *hdr = &req->rq;
+       struct sd_req cow_hdr;
        uint32_t epoch = hdr->epoch;
+       uint64_t oid = hdr->obj.oid;
+       int ret;
        char *buf = NULL;
        struct siocb iocb;
        unsigned data_length;
 
-       if (is_vdi_obj(hdr->oid))
+       if (is_vdi_obj(oid))
                data_length = SD_INODE_SIZE;
-       else if (is_vdi_attr_obj(hdr->oid))
+       else if (is_vdi_attr_obj(oid))
                data_length = SD_ATTR_OBJ_SIZE;
        else
                data_length = SD_DATA_OBJ_SIZE;
@@ -838,11 +837,12 @@ static int store_create_and_write_obj(st
        iocb.epoch = epoch;
        iocb.flags = hdr->flags;
        iocb.length = data_length;
-       ret = sd_store->open(hdr->oid, &iocb, 1);
+       ret = sd_store->open(oid, &iocb, 1);
        if (ret != SD_RES_SUCCESS)
                return ret;
+
        if (hdr->flags & SD_FLAG_CMD_COW) {
-               dprintf("%" PRIx64 ", %" PRIx64 "\n", hdr->oid, hdr->cow_oid);
+               dprintf("%" PRIx64 ", %" PRIx64 "\n", oid, hdr->obj.cow_oid);
 
                buf = valloc(SD_DATA_OBJ_SIZE);
                if (!buf) {
@@ -851,28 +851,28 @@ static int store_create_and_write_obj(st
                }
                if (hdr->data_length != SD_DATA_OBJ_SIZE) {
                        ret = read_copy_from_replica(req, hdr->epoch,
-                                                    hdr->cow_oid, buf);
+                                                    hdr->obj.cow_oid, buf);
                        if (ret != SD_RES_SUCCESS) {
                                eprintf("failed to read cow object\n");
                                goto out;
                        }
                }
 
-               memcpy(buf + hdr->offset, req->data, hdr->data_length);
+               memcpy(buf + hdr->obj.offset, req->data, hdr->data_length);
                memcpy(&cow_hdr, hdr, sizeof(cow_hdr));
-               cow_hdr.offset = 0;
                cow_hdr.data_length = SD_DATA_OBJ_SIZE;
+               cow_hdr.obj.offset = 0;
 
                ret = do_write_obj(&iocb, &cow_hdr, epoch, buf);
        } else
                ret = do_write_obj(&iocb, hdr, epoch, req->data);
 
        if (SD_RES_SUCCESS == ret)
-               check_and_insert_objlist_cache(hdr->oid);
+               check_and_insert_objlist_cache(oid);
 out:
        if (buf)
                free(buf);
-       sd_store->close(hdr->oid, &iocb);
+       sd_store->close(oid, &iocb);
        return ret;
 }
 
Index: sheepdog/sheep/sdnet.c
===================================================================
--- sheepdog.orig/sheep/sdnet.c 2012-05-17 11:16:55.000000000 +0200
+++ sheepdog/sheep/sdnet.c      2012-05-17 11:42:08.531983656 +0200
@@ -40,31 +40,31 @@ static int is_access_local(struct reques
 
 static void setup_access_to_local_objects(struct request *req)
 {
-       struct sd_obj_req *hdr = (struct sd_obj_req *)&req->rq;
+       struct sd_req *hdr = &req->rq;
 
        if (hdr->flags & SD_FLAG_CMD_IO_LOCAL) {
-               req->local_oid = hdr->oid;
+               req->local_oid = hdr->obj.oid;
                return;
        }
 
-       if (is_access_local(req, hdr->oid))
-               req->local_oid = hdr->oid;
+       if (is_access_local(req, hdr->obj.oid))
+               req->local_oid = hdr->obj.oid;
 
-       if (hdr->cow_oid)
-               if (is_access_local(req, hdr->cow_oid))
-                       req->local_cow_oid = hdr->cow_oid;
+       if (hdr->obj.cow_oid)
+               if (is_access_local(req, hdr->obj.cow_oid))
+                       req->local_cow_oid = hdr->obj.cow_oid;
 }
 
-static void check_object_consistency(struct sd_obj_req *hdr)
+static void check_object_consistency(struct sd_req *hdr)
 {
-       uint32_t vdi_id = oid_to_vid(hdr->oid);
+       uint32_t vdi_id = oid_to_vid(hdr->obj.oid);
        struct data_object_bmap *bmap, *n;
        int nr_bmaps = 0;
 
        list_for_each_entry_safe(bmap, n, &sys->consistent_obj_list, list) {
                nr_bmaps++;
                if (bmap->vdi_id == vdi_id) {
-                       set_bit(data_oid_to_idx(hdr->oid), bmap->dobjs);
+                       set_bit(data_oid_to_idx(hdr->obj.oid), bmap->dobjs);
                        list_del(&bmap->list);
                        list_add_tail(&bmap->list, &sys->consistent_obj_list);
                        return;
@@ -81,7 +81,7 @@ static void check_object_consistency(str
 
        bmap->vdi_id = vdi_id;
        list_add_tail(&bmap->list, &sys->consistent_obj_list);
-       set_bit(data_oid_to_idx(hdr->oid), bmap->dobjs);
+       set_bit(data_oid_to_idx(hdr->obj.oid), bmap->dobjs);
        if (nr_bmaps >= MAX_DATA_OBJECT_BMAPS) {
                /* the first entry is the least recently used one */
                bmap = list_first_entry(&sys->consistent_obj_list,
@@ -94,7 +94,7 @@ static void check_object_consistency(str
 static void io_op_done(struct work *work)
 {
        struct request *req = container_of(work, struct request, work);
-       struct sd_obj_req *hdr = (struct sd_obj_req *)&req->rq;
+       struct sd_req *hdr = &req->rq;
 
        list_del(&req->request_list);
        sys->nr_outstanding_io--;
@@ -109,7 +109,7 @@ static void io_op_done(struct work *work
                        goto retry;
                break;
        case SD_RES_EIO:
-               if (is_access_local(req, hdr->oid)) {
+               if (is_access_local(req, hdr->obj.oid)) {
                        eprintf("leaving sheepdog cluster\n");
                        leave_cluster();
 
@@ -121,7 +121,7 @@ static void io_op_done(struct work *work
                }
                break;
        case SD_RES_SUCCESS:
-               if (req->check_consistency && is_data_obj(hdr->oid))
+               if (req->check_consistency && is_data_obj(hdr->obj.oid))
                        check_object_consistency(hdr);
                break;
        }
@@ -159,13 +159,12 @@ static void local_op_done(struct work *w
 static void do_local_request(struct work *work)
 {
        struct request *req = container_of(work, struct request, work);
-       struct sd_obj_rsp *rsp = (struct sd_obj_rsp *)&req->rp;
        int ret = SD_RES_SUCCESS;
 
        if (has_process_work(req->op))
                ret = do_process_work(req);
 
-       rsp->result = ret;
+       req->rp.result = ret;
 }
 
 static int check_epoch(struct request *req)
@@ -188,14 +187,13 @@ static int check_epoch(struct request *r
 
 static int check_request(struct request *req)
 {
-       struct sd_obj_req *hdr = (struct sd_obj_req *)&req->rq;
-
        /*
         * if we go for a cached object, we don't care if it is busy
         * or being recovered.
         */
-       if (sys->enable_write_cache && (hdr->flags & SD_FLAG_CMD_CACHE) &&
-           object_is_cached(hdr->oid))
+       if (sys->enable_write_cache &&
+           (req->rq.flags & SD_FLAG_CMD_CACHE) &&
+           object_is_cached(req->rq.obj.oid))
                return 0;
 
        if (!req->local_oid && !req->local_cow_oid)
@@ -255,8 +253,8 @@ void resume_pending_requests(void)
 
 static void queue_request(struct request *req)
 {
-       struct sd_req *hdr = (struct sd_req *)&req->rq;
-       struct sd_rsp *rsp = (struct sd_rsp *)&req->rp;
+       struct sd_req *hdr = &req->rq;
+       struct sd_rsp *rsp = &req->rp;
 
        req->op = get_sd_op(hdr->opcode);
        if (!req->op) {
Index: sheepdog/sheep/store.c
===================================================================
--- sheepdog.orig/sheep/store.c 2012-05-17 11:16:55.000000000 +0200
+++ sheepdog/sheep/store.c      2012-05-17 12:16:16.175964130 +0200
@@ -48,11 +48,10 @@ LIST_HEAD(store_drivers);
 
 static int do_local_io(struct request *req, uint32_t epoch)
 {
-       struct sd_obj_req *hdr = (struct sd_obj_req *)&req->rq;
-
-       hdr->epoch = epoch;
-       dprintf("%x, %" PRIx64" , %u\n", hdr->opcode, hdr->oid, epoch);
+       dprintf("%x, %" PRIx64" , %u\n",
+               req->rq.opcode, req->rq.obj.oid, epoch);
 
+       req->rq.epoch = epoch;
        return do_process_work(req);
 }
 
@@ -60,17 +59,18 @@ static int forward_read_obj_req(struct r
 {
        int i, fd, ret = SD_RES_SUCCESS;
        unsigned wlen, rlen;
-       struct sd_obj_req hdr = *(struct sd_obj_req *)&req->rq;
-       struct sd_obj_rsp *rsp = (struct sd_obj_rsp *)&hdr;
+       struct sd_req fwd_hdr;
+       struct sd_rsp *rsp = (struct sd_rsp *)&fwd_hdr;
        struct sd_vnode *v;
        struct sd_vnode *obj_vnodes[SD_MAX_COPIES];
-       uint64_t oid = hdr.oid;
+       uint64_t oid = req->rq.obj.oid;
        int nr_copies;
 
-       hdr.flags |= SD_FLAG_CMD_IO_LOCAL;
+       memcpy(&fwd_hdr, &req->rq, sizeof(fwd_hdr));
+       fwd_hdr.flags |= SD_FLAG_CMD_IO_LOCAL;
 
-       if (hdr.copies)
-               nr_copies = hdr.copies;
+       if (fwd_hdr.obj.copies)
+               nr_copies = fwd_hdr.obj.copies;
        else
                nr_copies = get_nr_copies(req->vnodes);
 
@@ -79,7 +79,7 @@ static int forward_read_obj_req(struct r
        for (i = 0; i < nr_copies; i++) {
                v = obj_vnodes[i];
                if (vnode_is_local(v)) {
-                       ret = do_local_io(req, hdr.epoch);
+                       ret = do_local_io(req, fwd_hdr.epoch);
                        if (ret != SD_RES_SUCCESS)
                                goto read_remote;
                        return ret;
@@ -92,16 +92,16 @@ read_remote:
                if (vnode_is_local(v))
                        continue;
 
-               fd = get_sheep_fd(v->addr, v->port, v->node_idx, hdr.epoch);
+               fd = get_sheep_fd(v->addr, v->port, v->node_idx, fwd_hdr.epoch);
                if (fd < 0) {
                        ret = SD_RES_NETWORK_ERROR;
                        continue;
                }
 
                wlen = 0;
-               rlen = hdr.data_length;
+               rlen = fwd_hdr.data_length;
 
-               ret = exec_req(fd, (struct sd_req *)&hdr, req->data, &wlen, 
&rlen);
+               ret = exec_req(fd, &fwd_hdr, req->data, &wlen, &rlen);
 
                if (ret) { /* network errors */
                        del_sheep_fd(fd);
@@ -121,11 +121,11 @@ int forward_write_obj_req(struct request
        int i, fd, ret, pollret;
        unsigned wlen;
        char name[128];
-       struct sd_obj_req hdr = *(struct sd_obj_req *)&req->rq;
-       struct sd_obj_rsp *rsp = (struct sd_obj_rsp *)&req->rp;
+       struct sd_req fwd_hdr;
+       struct sd_rsp *rsp = (struct sd_rsp *)&req->rp;
        struct sd_vnode *v;
        struct sd_vnode *obj_vnodes[SD_MAX_COPIES];
-       uint64_t oid = hdr.oid;
+       uint64_t oid = req->rq.obj.oid;
        int nr_copies;
        struct pollfd pfds[SD_MAX_REDUNDANCY];
        int nr_fds, local = 0;
@@ -137,9 +137,10 @@ int forward_write_obj_req(struct request
        for (i = 0; i < ARRAY_SIZE(pfds); i++)
                pfds[i].fd = -1;
 
-       hdr.flags |= SD_FLAG_CMD_IO_LOCAL;
+       memcpy(&fwd_hdr, &req->rq, sizeof(fwd_hdr));
+       fwd_hdr.flags |= SD_FLAG_CMD_IO_LOCAL;
 
-       wlen = hdr.data_length;
+       wlen = fwd_hdr.data_length;
 
        nr_copies = get_nr_copies(req->vnodes);
        oid_to_vnodes(req->vnodes, oid, nr_copies, obj_vnodes);
@@ -153,14 +154,14 @@ int forward_write_obj_req(struct request
                        continue;
                }
 
-               fd = get_sheep_fd(v->addr, v->port, v->node_idx, hdr.epoch);
+               fd = get_sheep_fd(v->addr, v->port, v->node_idx, fwd_hdr.epoch);
                if (fd < 0) {
                        eprintf("failed to connect to %s:%"PRIu32"\n", name, 
v->port);
                        ret = SD_RES_NETWORK_ERROR;
                        goto out;
                }
 
-               ret = send_req(fd, (struct sd_req *)&hdr, req->data, &wlen);
+               ret = send_req(fd, &fwd_hdr, req->data, &wlen);
                if (ret) { /* network errors */
                        del_sheep_fd(fd);
                        ret = SD_RES_NETWORK_ERROR;
@@ -174,7 +175,7 @@ int forward_write_obj_req(struct request
        }
 
        if (local) {
-               ret = do_local_io(req, hdr.epoch);
+               ret = do_local_io(req, fwd_hdr.epoch);
                rsp->result = ret;
 
                if (nr_fds == 0) {
@@ -297,16 +298,19 @@ static int fix_object_consistency(struct
 {
        int ret = SD_RES_NO_MEM;
        unsigned int data_length;
-       struct sd_obj_req *hdr = (struct sd_obj_req *)&req->rq;
-       struct sd_obj_req req_bak = *((struct sd_obj_req *)&req->rq);
-       struct sd_obj_rsp rsp_bak = *((struct sd_obj_rsp *)&req->rp);
+       struct sd_req *hdr = &req->rq;
+       struct sd_req req_bak;
+       struct sd_rsp rsp_bak;
        void *data = req->data, *buf;
-       uint64_t oid = hdr->oid;
+       uint64_t oid = hdr->obj.oid;
        int old_opcode = hdr->opcode;
 
-       if (is_vdi_obj(hdr->oid))
+       memcpy(&req_bak, &req->rq, sizeof(req_bak));
+       memcpy(&rsp_bak, &req->rp, sizeof(rsp_bak));
+
+       if (is_vdi_obj(oid))
                data_length = SD_INODE_SIZE;
-       else if (is_vdi_attr_obj(hdr->oid))
+       else if (is_vdi_attr_obj(oid))
                data_length = SD_ATTR_OBJ_SIZE;
        else
                data_length = SD_DATA_OBJ_SIZE;
@@ -318,12 +322,15 @@ static int fix_object_consistency(struct
        }
        memset(buf, 0, data_length);
 
-       req->data = buf;
-       hdr->offset = 0;
+
        hdr->data_length = data_length;
        hdr->opcode = SD_OP_READ_OBJ;
        hdr->flags = 0;
+       hdr->obj.offset = 0;
+
+       req->data = buf;
        req->op = get_sd_op(SD_OP_READ_OBJ);
+
        ret = forward_read_obj_req(req);
        if (ret != SD_RES_SUCCESS) {
                eprintf("failed to read object %x\n", ret);
@@ -332,7 +339,7 @@ static int fix_object_consistency(struct
 
        hdr->opcode = SD_OP_CREATE_AND_WRITE_OBJ;
        hdr->flags = SD_FLAG_CMD_WRITE;
-       hdr->oid = oid;
+       hdr->obj.oid = oid;
        req->op = get_sd_op(hdr->opcode);
        ret = forward_write_obj_req(req);
        if (ret != SD_RES_SUCCESS) {
@@ -343,16 +350,16 @@ out:
        free(buf);
        req->data = data;
        req->op = get_sd_op(old_opcode);
-       *((struct sd_obj_req *)&req->rq) = req_bak;
-       *((struct sd_obj_rsp *)&req->rp) = rsp_bak;
+
+       memcpy(&req->rq, &req_bak, sizeof(req_bak));
+       memcpy(&req->rp, &rsp_bak, sizeof(rsp_bak));
 
        return ret;
 }
 
 static int handle_gateway_request(struct request *req)
 {
-       struct sd_obj_req *hdr = (struct sd_obj_req *)&req->rq;
-       uint64_t oid = hdr->oid;
+       uint64_t oid = req->rq.obj.oid;
        uint32_t vid = oid_to_vid(oid);
        uint32_t idx = data_oid_to_idx(oid);
        struct object_cache *cache;
@@ -363,7 +370,7 @@ static int handle_gateway_request(struct
 
        cache = find_object_cache(vid, 1);
 
-       if (hdr->opcode == SD_OP_CREATE_AND_WRITE_OBJ)
+       if (req->rq.opcode == SD_OP_CREATE_AND_WRITE_OBJ)
                create = 1;
 
        if (object_cache_lookup(cache, idx, create) < 0) {
@@ -376,17 +383,16 @@ static int handle_gateway_request(struct
 
 static int bypass_object_cache(struct request *req)
 {
-       struct sd_obj_req *hdr = (struct sd_obj_req *)&req->rq;
-       uint64_t oid = hdr->oid;
+       uint64_t oid = req->rq.obj.oid;
 
-       if (!(hdr->flags & SD_FLAG_CMD_CACHE)) {
+       if (!(req->rq.flags & SD_FLAG_CMD_CACHE)) {
                uint32_t vid = oid_to_vid(oid);
                struct object_cache *cache;
 
                cache = find_object_cache(vid, 0);
                if (!cache)
                        return 1;
-               if (hdr->flags & SD_FLAG_CMD_WRITE) {
+               if (req->rq.flags & SD_FLAG_CMD_WRITE) {
                        object_cache_flush_and_delete(req->vnodes, cache);
                        return 1;
                } else  {
@@ -406,7 +412,7 @@ static int bypass_object_cache(struct re
         * For vmstate && vdi_attr object, we don't do caching
         */
        if (is_vmstate_obj(oid) || is_vdi_attr_obj(oid) ||
-           hdr->flags & SD_FLAG_CMD_COW)
+           req->rq.flags & SD_FLAG_CMD_COW)
                return 1;
        return 0;
 }
@@ -414,19 +420,18 @@ static int bypass_object_cache(struct re
 void do_io_request(struct work *work)
 {
        struct request *req = container_of(work, struct request, work);
+       uint32_t epoch;
        int ret = SD_RES_SUCCESS;
-       struct sd_obj_req *hdr = (struct sd_obj_req *)&req->rq;
-       struct sd_obj_rsp *rsp = (struct sd_obj_rsp *)&req->rp;
-       uint64_t oid = hdr->oid;
-       uint32_t opcode = hdr->opcode;
-       uint32_t epoch = hdr->epoch;
 
-       dprintf("%x, %" PRIx64" , %u\n", opcode, oid, epoch);
+       if (req->rq.flags & SD_FLAG_CMD_RECOVERY)
+               epoch = req->rq.obj.tgt_epoch;
+       else
+               epoch = req->rq.epoch;
 
-       if (hdr->flags & SD_FLAG_CMD_RECOVERY)
-               epoch = hdr->tgt_epoch;
+       dprintf("%x, %" PRIx64" , %u\n",
+               req->rq.opcode, req->rq.obj.oid, epoch);
 
-       if (hdr->flags & SD_FLAG_CMD_IO_LOCAL) {
+       if (req->rq.flags & SD_FLAG_CMD_IO_LOCAL) {
                ret = do_local_io(req, epoch);
        } else {
                if (!sys->enable_write_cache || bypass_object_cache(req)) {
@@ -436,7 +441,7 @@ void do_io_request(struct work *work)
                                if (ret != SD_RES_SUCCESS)
                                        goto out;
                        }
-                       if (hdr->flags & SD_FLAG_CMD_WRITE)
+                       if (req->rq.flags & SD_FLAG_CMD_WRITE)
                                ret = forward_write_obj_req(req);
                        else
                                ret = forward_read_obj_req(req);
@@ -446,22 +451,26 @@ void do_io_request(struct work *work)
 out:
        if (ret != SD_RES_SUCCESS)
                dprintf("failed: %x, %" PRIx64" , %u, %"PRIx32"\n",
-                       opcode, oid, epoch, ret);
-       rsp->result = ret;
+                       req->rq.opcode, req->rq.obj.oid, epoch, ret);
+       req->rp.result = ret;
 }
 
 int epoch_log_read_remote(uint32_t epoch, char *buf, int len)
 {
-       struct sd_obj_req hdr;
-       struct sd_obj_rsp *rsp = (struct sd_obj_rsp *)&hdr;
-       int fd, i, ret;
-       unsigned int rlen, wlen, nr, le = get_latest_epoch();
-       char host[128];
+       int i, ret;
+       unsigned int nr, le = get_latest_epoch();
        struct sd_node nodes[SD_MAX_NODES];
 
        nr = epoch_log_read(le, (char *)nodes, sizeof(nodes));
        nr /= sizeof(nodes[0]);
+
        for (i = 0; i < nr; i++) {
+               struct sd_req hdr;
+               struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
+               char host[128];
+               unsigned int rlen, wlen;
+               int fd;
+
                if (is_myself(nodes[i].addr, nodes[i].port))
                        continue;
 
@@ -474,9 +483,9 @@ int epoch_log_read_remote(uint32_t epoch
 
                memset(&hdr, 0, sizeof(hdr));
                hdr.opcode = SD_OP_GET_EPOCH;
-               hdr.tgt_epoch = epoch;
-               hdr.data_length = len;
-               rlen = hdr.data_length;
+               hdr.data_length = rlen = len;
+               hdr.obj.tgt_epoch = epoch;
+
                wlen = 0;
 
                ret = exec_req(fd, (struct sd_req *)&hdr, buf, &wlen, &rlen);
@@ -883,22 +892,24 @@ static int write_object_local(uint64_t o
 {
        int ret;
        struct request *req;
-       struct sd_obj_req *hdr;
+       struct sd_req *hdr;
 
        req = zalloc(sizeof(*req));
        if (!req)
                return SD_RES_NO_MEM;
-       hdr = (struct sd_obj_req *)&req->rq;
+       hdr = &req->rq;
 
-       hdr->oid = oid;
        if (create)
                hdr->opcode = SD_OP_CREATE_AND_WRITE_OBJ;
        else
                hdr->opcode = SD_OP_WRITE_OBJ;
-       hdr->copies = copies;
        hdr->flags = flags | SD_FLAG_CMD_WRITE;
-       hdr->offset = offset;
        hdr->data_length = datalen;
+
+       hdr->obj.oid = oid;
+       hdr->obj.offset = offset;
+       hdr->obj.copies = copies;
+
        req->data = data;
        req->op = get_sd_op(hdr->opcode);
 
@@ -915,7 +926,6 @@ static int write_inode_cache(uint64_t oi
 {
        int ret;
        struct request *req;
-       struct sd_obj_req *hdr;
        uint32_t vid = oid_to_vid(oid);
        uint32_t idx = data_oid_to_idx(oid);
        struct object_cache *cache;
@@ -927,24 +937,24 @@ static int write_inode_cache(uint64_t oi
        req = zalloc(sizeof(*req));
        if (!req)
                return SD_RES_NO_MEM;
-       hdr = (struct sd_obj_req *)&req->rq;
 
-       hdr->oid = oid;
        if (create)
-               hdr->opcode = SD_OP_CREATE_AND_WRITE_OBJ;
+               req->rq.opcode = SD_OP_CREATE_AND_WRITE_OBJ;
        else
-               hdr->opcode = SD_OP_WRITE_OBJ;
-       hdr->copies = copies;
-       hdr->flags = flags | SD_FLAG_CMD_WRITE;
-       hdr->offset = offset;
-       hdr->data_length = datalen;
+               req->rq.opcode = SD_OP_WRITE_OBJ;
+       req->rq.flags = flags | SD_FLAG_CMD_WRITE;
+       req->rq.data_length = datalen;
+
+       req->rq.obj.oid = oid;
+       req->rq.obj.offset = offset;
+       req->rq.obj.copies = copies;
+
        req->data = data;
-       req->op = get_sd_op(hdr->opcode);
+       req->op = get_sd_op(req->rq.opcode);
 
        ret = object_cache_rw(cache, idx, req);
 
        free(req);
-
        return ret;
 }
 
@@ -952,11 +962,8 @@ int write_object(struct vnode_info *vnod
                 uint64_t oid, char *data, unsigned int datalen,
                 uint64_t offset, uint16_t flags, int nr_copies, int create)
 {
-       struct sd_obj_req hdr;
-       struct sd_vnode *v;
        struct sd_vnode *obj_vnodes[SD_MAX_COPIES];
        int i, fd, ret;
-       char name[128];
 
        if (sys->enable_write_cache && object_is_cached(oid)) {
                ret = write_inode_cache(oid, data, datalen, offset,
@@ -969,7 +976,10 @@ int write_object(struct vnode_info *vnod
 
        oid_to_vnodes(vnodes, oid, nr_copies, obj_vnodes);
        for (i = 0; i < nr_copies; i++) {
+               struct sd_req hdr;
                unsigned rlen = 0, wlen = datalen;
+               struct sd_vnode *v;
+               char name[128];
 
                v = obj_vnodes[i];
                if (vnode_is_local(v)) {
@@ -1000,15 +1010,15 @@ int write_object(struct vnode_info *vnod
                else
                        hdr.opcode = SD_OP_WRITE_OBJ;
 
-               hdr.oid = oid;
-               hdr.copies = nr_copies;
-
                hdr.flags = flags;
                hdr.flags |= SD_FLAG_CMD_WRITE | SD_FLAG_CMD_IO_LOCAL;
                hdr.data_length = wlen;
-               hdr.offset = offset;
 
-               ret = exec_req(fd, (struct sd_req *)&hdr, data, &wlen, &rlen);
+               hdr.obj.oid = oid;
+               hdr.obj.offset = offset;
+               hdr.obj.copies = nr_copies;
+
+               ret = exec_req(fd, &hdr, data, &wlen, &rlen);
                close(fd);
                if (ret) {
                        eprintf("failed to update host %s\n", name);
@@ -1024,21 +1034,21 @@ static int read_object_local(uint64_t oi
 {
        int ret;
        struct request *req;
-       struct sd_obj_req *hdr;
 
        req = zalloc(sizeof(*req));
        if (!req)
                return SD_RES_NO_MEM;
-       hdr = (struct sd_obj_req *)&req->rq;
 
-       hdr->oid = oid;
-       hdr->opcode = SD_OP_READ_OBJ;
-       hdr->copies = copies;
-       hdr->flags = 0;
-       hdr->offset = offset;
-       hdr->data_length = datalen;
+       req->rq.opcode = SD_OP_READ_OBJ;
+       req->rq.flags = 0;
+       req->rq.data_length = datalen;
+
+       req->rq.obj.oid = oid;
+       req->rq.obj.copies = copies;
+       req->rq.obj.offset = offset;
+
        req->data = data;
-       req->op = get_sd_op(hdr->opcode);
+       req->op = get_sd_op(req->rq.opcode);
 
        ret = do_local_io(req, epoch);
 
@@ -1051,7 +1061,6 @@ static int read_object_cache(uint64_t oi
 {
        int ret;
        struct request *req;
-       struct sd_obj_req *hdr;
        uint32_t vid = oid_to_vid(oid);
        uint32_t idx = data_oid_to_idx(oid);
        struct object_cache *cache;
@@ -1064,15 +1073,16 @@ static int read_object_cache(uint64_t oi
        req = zalloc(sizeof(*req));
        if (!req)
                return SD_RES_NO_MEM;
-       hdr = (struct sd_obj_req *)&req->rq;
 
-       hdr->oid = oid;
-       hdr->opcode = SD_OP_READ_OBJ;
-       hdr->copies = copies;
-       hdr->offset = offset;
-       hdr->data_length = datalen;
+       req->rq.opcode = SD_OP_READ_OBJ;
+       req->rq.data_length = datalen;
+
+       req->rq.obj.oid = oid;
+       req->rq.obj.offset = offset;
+       req->rq.obj.copies = copies;
+
        req->data = data;
-       req->op = get_sd_op(hdr->opcode);
+       req->op = get_sd_op(req->rq.opcode);
 
        ret = object_cache_rw(cache, idx, req);
 
@@ -1085,8 +1095,6 @@ int read_object(struct vnode_info *vnode
                uint64_t oid, char *data, unsigned int datalen,
                uint64_t offset, int nr_copies)
 {
-       struct sd_obj_req hdr;
-       struct sd_obj_rsp *rsp = (struct sd_obj_rsp *)&hdr;
        struct sd_vnode *v;
        struct sd_vnode *obj_vnodes[SD_MAX_COPIES];
        char name[128];
@@ -1120,6 +1128,8 @@ int read_object(struct vnode_info *vnode
        }
 
        for (i = 0; i < nr_copies; i++) {
+               struct sd_req hdr;
+               struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
                unsigned wlen = 0, rlen = datalen;
 
                v = obj_vnodes[i];
@@ -1135,13 +1145,13 @@ int read_object(struct vnode_info *vnode
                memset(&hdr, 0, sizeof(hdr));
                hdr.epoch = node_version;
                hdr.opcode = SD_OP_READ_OBJ;
-               hdr.oid = oid;
-
                hdr.flags =  SD_FLAG_CMD_IO_LOCAL;
                hdr.data_length = rlen;
-               hdr.offset = offset;
 
-               ret = exec_req(fd, (struct sd_req *)&hdr, data, &wlen, &rlen);
+               hdr.obj.oid = oid;
+               hdr.obj.offset = offset;
+
+               ret = exec_req(fd, &hdr, data, &wlen, &rlen);
                close(fd);
 
                if (ret) {
@@ -1161,16 +1171,17 @@ int read_object(struct vnode_info *vnode
 int remove_object(struct vnode_info *vnodes, uint32_t node_version,
                  uint64_t oid, int nr)
 {
-       char name[128];
-       struct sd_obj_req hdr;
-       struct sd_obj_rsp *rsp = (struct sd_obj_rsp *)&hdr;
-       struct sd_vnode *v;
        struct sd_vnode *obj_vnodes[SD_MAX_COPIES];
-       int i = 0, fd, ret, err = 0;
+       int err = 0, i = 0;
 
        oid_to_vnodes(vnodes, oid, nr, obj_vnodes);
        for (i = 0; i < nr; i++) {
+               struct sd_req hdr;
+               struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
+               struct sd_vnode *v;
                unsigned wlen = 0, rlen = 0;
+               char name[128];
+               int fd, ret;
 
                v = obj_vnodes[i];
                addr_to_str(name, sizeof(name), v->addr, 0);
@@ -1184,12 +1195,12 @@ int remove_object(struct vnode_info *vno
                memset(&hdr, 0, sizeof(hdr));
                hdr.epoch = node_version;
                hdr.opcode = SD_OP_REMOVE_OBJ;
-               hdr.oid = oid;
-
                hdr.flags = 0;
                hdr.data_length = rlen;
 
-               ret = exec_req(fd, (struct sd_req *)&hdr, NULL, &wlen, &rlen);
+               hdr.obj.oid = oid;
+
+               ret = exec_req(fd, &hdr, NULL, &wlen, &rlen);
                close(fd);
 
                if (ret)
Index: sheepdog/sheep/recovery.c
===================================================================
--- sheepdog.orig/sheep/recovery.c      2012-05-17 11:28:16.055991594 +0200
+++ sheepdog/sheep/recovery.c   2012-05-17 12:14:41.539965033 +0200
@@ -196,8 +196,8 @@ static int recover_object_from_replica(u
                                       struct sd_vnode *entry,
                                       uint32_t epoch, uint32_t tgt_epoch)
 {
-       struct sd_obj_req hdr;
-       struct sd_obj_rsp *rsp = (struct sd_obj_rsp *)&hdr;
+       struct sd_req hdr;
+       struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
        char name[128];
        unsigned wlen = 0, rlen;
        int fd, ret = -1;
@@ -241,12 +241,13 @@ static int recover_object_from_replica(u
 
        memset(&hdr, 0, sizeof(hdr));
        hdr.opcode = SD_OP_READ_OBJ;
-       hdr.oid = oid;
        hdr.epoch = epoch;
        hdr.flags = SD_FLAG_CMD_RECOVERY | SD_FLAG_CMD_IO_LOCAL;
-       hdr.tgt_epoch = tgt_epoch;
        hdr.data_length = rlen;
 
+       hdr.obj.oid = oid;
+       hdr.obj.tgt_epoch = tgt_epoch;
+
        ret = exec_req(fd, (struct sd_req *)&hdr, buf, &wlen, &rlen);
 
        close(fd);
@@ -257,7 +258,7 @@ static int recover_object_from_replica(u
                goto out;
        }
 
-       rsp = (struct sd_obj_rsp *)&hdr;
+       rsp = (struct sd_rsp *)&hdr;
 
        if (rsp->result == SD_RES_SUCCESS) {
                iocb.epoch = epoch;
-- 
sheepdog mailing list
sheepdog@lists.wpkg.org
http://lists.wpkg.org/mailman/listinfo/sheepdog

Reply via email to