[Sheepdog] [PATCH] use unions for protocol requests and responses

Christoph Hellwig hch at infradead.org
Thu Apr 26 18:16:04 CEST 2012


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 <hch at lst.de>

---
 collie/cluster.c         |   14 +--
 collie/common.c          |   26 +++---
 collie/vdi.c             |   79 +++++++++---------
 include/sheepdog_proto.h |   85 ++++++--------------
 sheep/group.c            |   14 +--
 sheep/object_cache.c     |   35 ++++----
 sheep/ops.c              |   67 ++++++---------
 sheep/sdnet.c            |   61 +++++++-------
 sheep/store.c            |  198 ++++++++++++++++++++++++-----------------------
 9 files changed, 278 insertions(+), 301 deletions(-)

Index: sheepdog/collie/cluster.c
===================================================================
--- sheepdog.orig/collie/cluster.c	2012-04-26 18:03:55.296555626 +0200
+++ sheepdog/collie/cluster.c	2012-04-26 18:05:07.916557485 +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(int 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(int 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-04-26 18:03:55.296555626 +0200
+++ sheepdog/collie/common.c	2012-04-26 18:05:07.916557485 +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-04-26 18:03:55.296555626 +0200
+++ sheepdog/collie/vdi.c	2012-04-26 18:05:07.916557485 +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];
 	struct epoch_log *logs;
@@ -838,7 +838,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)
@@ -931,8 +931,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;
@@ -957,9 +957,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)
@@ -967,7 +968,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;
@@ -978,9 +979,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-04-26 18:03:55.296555626 +0200
+++ sheepdog/include/sheepdog_proto.h	2012-04-26 18:05:07.916557485 +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-04-26 18:04:45.224556904 +0200
+++ sheepdog/sheep/group.c	2012-04-26 18:05:07.920557486 +0200
@@ -58,8 +58,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];
 };
 
@@ -237,8 +237,9 @@ void do_cluster_request(struct work *wor
 		return;
 	}
 
-	msg->req = *((struct sd_vdi_req *)&req->rq);
-	msg->rsp = *((struct sd_vdi_rsp *)&req->rp);
+	memcpy(&msg->req, &req->rq, sizeof(msg->req));
+	memcpy(&msg->rsp, &req->rp, sizeof(msg->rsp));
+
 	if (has_process_main(req->op))
 		memcpy(msg->data, req->data, hdr->data_length);
 
@@ -1022,7 +1023,6 @@ static void process_request_queue(void)
 
 	list_for_each_entry_safe(cevent, n, &sys->request_queue, event_list) {
 		struct request *req = container_of(cevent, struct request, cev);
-		struct sd_obj_req *hdr = (struct sd_obj_req *)&req->rq;
 
 		list_del(&cevent->event_list);
 
@@ -1033,7 +1033,7 @@ static void process_request_queue(void)
 				copies = req->vnodes->nr_zones;
 
 			if (!(req->rq.flags & SD_FLAG_CMD_IO_LOCAL) &&
-			    object_is_cached(hdr->oid)) {
+			    object_is_cached(req->rq.obj.oid)) {
 				/* If we have cache of it we are at its service. */
 				list_add_tail(&req->r_wlist, &sys->outstanding_req_list);
 				sys->nr_outstanding_io++;
@@ -1045,7 +1045,7 @@ static void process_request_queue(void)
 			sys->nr_outstanding_io++;
 
 			if (need_consistency_check(req->rq.opcode, req->rq.flags))
-				set_consistency_check(req, hdr->oid);
+				set_consistency_check(req, req->rq.obj.oid);
 
 			if (req->rq.flags & SD_FLAG_CMD_IO_LOCAL)
 				queue_work(sys->io_wqueue, &req->work);
Index: sheepdog/sheep/object_cache.c
===================================================================
--- sheepdog.orig/sheep/object_cache.c	2012-04-26 18:03:55.296555626 +0200
+++ sheepdog/sheep/object_cache.c	2012-04-26 18:05:07.920557486 +0200
@@ -309,23 +309,26 @@ 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;
 	int ret;
 
-	dprintf("%08"PRIx32", len %"PRIu32", off %"PRIu64"\n", idx, hdr->data_length, hdr->offset);
-	if (hdr->flags & SD_FLAG_CMD_WRITE) {
-		ret = write_cache_object(oc->vid, idx, req->data, hdr->data_length, hdr->offset);
+	dprintf("%08"PRIx32", len %"PRIu32", off %"PRIu64"\n", idx,
+		 req->rq.data_length, req->rq.obj.offset);
+	if (req->rq.flags & SD_FLAG_CMD_WRITE) {
+		ret = write_cache_object(oc->vid, idx, req->data,
+					 req->rq.data_length,
+					 req->rq.obj.offset);
 		if (ret != SD_RES_SUCCESS)
 			goto out;
 		pthread_mutex_lock(&oc->lock);
 		add_to_dirty_tree_and_list(oc, idx, 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,
+					req->rq.data_length,
+					req->rq.obj.offset);
 		if (ret != SD_RES_SUCCESS)
 			goto out;
-		rsp->data_length = hdr->data_length;
+		req->rp.data_length = req->rq.data_length;
 	}
 out:
 	return ret;
@@ -372,8 +375,8 @@ int object_cache_pull(struct object_cach
 	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 vnode_info *vnodes = get_vnode_info();
 	struct sd_vnode *v;
 	void *buf;
@@ -427,10 +430,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);
@@ -470,7 +473,7 @@ static uint64_t idx_to_oid(uint32_t vid,
 static int push_cache_object(uint32_t vid, uint32_t idx, 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;
 	unsigned data_length;
 	int ret = SD_RES_NO_MEM;
@@ -494,13 +497,15 @@ static int push_cache_object(uint32_t vi
 	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_sobjs;
+	hdr->data_length = data_length;
 	hdr->epoch = sys->epoch;
+
+	hdr->obj.oid = oid;
+	hdr->obj.offset = 0;
+	hdr->obj.copies = sys->nr_sobjs;
+
 	fake_req.data = buf;
 	fake_req.op = get_sd_op(hdr->opcode);
 	fake_req.vnodes = get_vnode_info();
Index: sheepdog/sheep/ops.c
===================================================================
--- sheepdog.orig/sheep/ops.c	2012-04-26 18:03:55.296555626 +0200
+++ sheepdog/sheep/ops.c	2012-04-26 18:05:07.920557486 +0200
@@ -57,17 +57,15 @@ struct flush_work {
 static int cluster_new_vdi(const struct sd_req *req, struct sd_rsp *rsp,
 			   void *data)
 {
-	const struct sd_vdi_req *hdr = (const struct sd_vdi_req *)req;
-	struct sd_vdi_rsp *vdi_rsp = (struct sd_vdi_rsp *)rsp;
 	uint32_t vid = 0, nr_copies = sys->nr_sobjs;
 	int ret;
 
-	ret = add_vdi(hdr->epoch, data, hdr->data_length, hdr->vdi_size, &vid,
-		      hdr->base_vdi_id, hdr->copies,
-		      hdr->snapid, &nr_copies);
+	ret = add_vdi(req->epoch, data, req->data_length, req->vdi.vdi_size,
+		      &vid, req->vdi.base_vdi_id, req->obj.copies,
+		      req->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;
 }
@@ -75,9 +73,8 @@ static int cluster_new_vdi(const struct
 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);
@@ -85,30 +82,26 @@ static int post_cluster_new_vdi(const st
 	return SD_RES_SUCCESS;
 }
 
-static int cluster_del_vdi(const struct sd_req *req, struct sd_rsp *rsp,
+static int cluster_del_vdi(const struct sd_req *hdr, struct sd_rsp *rsp,
 			   void *data)
 {
-	const struct sd_vdi_req *hdr = (const struct sd_vdi_req *)req;
-	struct sd_vdi_rsp *vdi_rsp = (struct sd_vdi_rsp *)rsp;
 	uint32_t vid = 0, nr_copies = sys->nr_sobjs;
 	int ret;
 
 	ret = del_vdi(hdr->epoch, data, hdr->data_length, &vid,
-		      hdr->snapid, &nr_copies);
+		      hdr->vdi.snapid, &nr_copies);
 
 	if (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(const struct sd_req *req, struct sd_rsp *rsp,
+static int cluster_get_vdi_info(const struct sd_req *hdr, struct sd_rsp *rsp,
 				void *data)
 {
-	const struct sd_vdi_req *hdr = (const struct sd_vdi_req *)req;
-	struct sd_vdi_rsp *vdi_rsp = (struct sd_vdi_rsp *)rsp;
 	uint32_t vid = 0, nr_copies = sys->nr_sobjs;
 	void *tag;
 	int ret;
@@ -123,13 +116,13 @@ static int cluster_get_vdi_info(const st
 	else
 		return SD_RES_INVALID_PARMS;
 
-	ret = lookup_vdi(hdr->epoch, data, tag, &vid, hdr->snapid,
+	ret = lookup_vdi(hdr->epoch, data, tag, &vid, 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;
 }
@@ -197,11 +190,9 @@ static int cluster_shutdown(const struct
 	return SD_RES_SUCCESS;
 }
 
-static int cluster_get_vdi_attr(const struct sd_req *req, struct sd_rsp *rsp,
+static int cluster_get_vdi_attr(const struct sd_req *hdr, struct sd_rsp *rsp,
 				void *data)
 {
-	const struct sd_vdi_req *hdr = (const struct sd_vdi_req *)req;
-	struct sd_vdi_rsp *vdi_rsp = (struct sd_vdi_rsp *)rsp;
 	uint32_t vid = 0, attrid = 0, nr_copies = sys->nr_sobjs;
 	uint64_t ctime = 0;
 	int ret;
@@ -209,7 +200,7 @@ static int cluster_get_vdi_attr(const st
 
 	vattr = data;
 	ret = lookup_vdi(hdr->epoch, vattr->name, vattr->tag,
-			 &vid, hdr->snapid, &nr_copies, &ctime);
+			 &vid, hdr->vdi.snapid, &nr_copies, &ctime);
 	if (ret != SD_RES_SUCCESS)
 		return ret;
 
@@ -223,9 +214,9 @@ static int cluster_get_vdi_attr(const st
 			   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;
 }
@@ -363,18 +354,18 @@ static int local_get_obj_list(const stru
 static int local_get_epoch(const struct sd_req *req, struct sd_rsp *rsp,
 			   void *data)
 {
-	const struct sd_obj_req *obj_req = (const struct sd_obj_req *)req;
-	struct sd_obj_rsp *obj_rsp = (struct sd_obj_rsp *)rsp;
-	int epoch = obj_req->tgt_epoch;
+	int epoch = req->obj.tgt_epoch;
 	int len, ret;
+
 	dprintf("%d\n", epoch);
-	len = epoch_log_read(epoch, (char *)data, obj_req->data_length);
+
+	len = epoch_log_read(epoch, (char *)data, req->data_length);
 	if (len == -1) {
 		ret = SD_RES_NO_TAG;
-		obj_rsp->data_length = 0;
+		rsp->data_length = 0;
 	} else {
 		ret = SD_RES_SUCCESS;
-		obj_rsp->data_length = len;
+		rsp->data_length = len;
 	}
 	return ret;
 }
@@ -463,9 +454,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);
@@ -507,8 +497,7 @@ static void flush_vdi_done(struct work *
 
 static int local_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;
+	uint64_t oid = req->obj.oid;
 	uint32_t vid = oid_to_vid(oid);
 	struct object_cache *cache = find_object_cache(vid, 0);
 
Index: sheepdog/sheep/sdnet.c
===================================================================
--- sheepdog.orig/sheep/sdnet.c	2012-04-26 18:04:45.224556904 +0200
+++ sheepdog/sheep/sdnet.c	2012-04-26 18:05:07.924557486 +0200
@@ -60,31 +60,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, hdr->copies))
-		req->local_oid = hdr->oid;
+	if (is_access_local(req, hdr->obj.oid, hdr->obj.copies))
+		req->local_oid = hdr->obj.oid;
 
-	if (hdr->cow_oid)
-		if (is_access_local(req, hdr->cow_oid, hdr->copies))
-			req->local_cow_oid = hdr->cow_oid;
+	if (hdr->obj.cow_oid)
+		if (is_access_local(req, hdr->obj.cow_oid, hdr->obj.copies))
+			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;
@@ -101,7 +101,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,
@@ -114,7 +114,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->r_wlist);
 	sys->nr_outstanding_io--;
@@ -129,7 +129,7 @@ static void io_op_done(struct work *work
 			goto retry;
 		break;
 	case SD_RES_EIO:
-		if (is_access_local(req, hdr->oid, 0)) {
+		if (is_access_local(req, hdr->obj.oid, 0)) {
 			eprintf("leaving sheepdog cluster\n");
 			leave_cluster();
 
@@ -141,7 +141,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;
 	}
@@ -184,13 +184,12 @@ static void cluster_op_done(struct work
 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->op, &req->rq, &req->rp, req->data);
 
-	rsp->result = ret;
+	req->rp.result = ret;
 }
 
 static int check_epoch(struct request *req)
@@ -674,7 +673,7 @@ 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_req hdr;
 	struct sd_vnode *v;
 	int i, fd, ret;
 	char name[128];
@@ -711,15 +710,16 @@ 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.copies = nr_copies;
+		hdr.obj.offset = offset;
+
+		ret = exec_req(fd, &hdr, data, &wlen, &rlen);
 		close(fd);
 		if (ret) {
 			eprintf("failed to update host %s\n", name);
@@ -734,8 +734,8 @@ 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_req hdr;
+	struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
 	struct sd_vnode *v;
 	char name[128];
 	int i = 0, fd, ret, last_error = SD_RES_SUCCESS;
@@ -774,13 +774,14 @@ 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) {
@@ -801,8 +802,8 @@ int remove_object(struct vnode_info *vno
 		  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_req hdr;
+	struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
 	struct sd_vnode *v;
 	int i = 0, fd, ret;
 
@@ -822,12 +823,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.obj.oid = oid;
 
 		hdr.flags = 0;
 		hdr.data_length = rlen;
 
-		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/sheep/store.c
===================================================================
--- sheepdog.orig/sheep/store.c	2012-04-26 18:03:55.296555626 +0200
+++ sheepdog/sheep/store.c	2012-04-26 18:05:07.924557486 +0200
@@ -227,8 +227,8 @@ static int read_copy_from_replica(struct
 	unsigned wlen, rlen;
 	char name[128];
 	struct sd_vnode *v;
-	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;
 	struct siocb iocb;
 	int fd;
 
@@ -259,18 +259,18 @@ static int read_copy_from_replica(struct
 		if (fd < 0)
 			continue;
 
+		rlen = SD_DATA_OBJ_SIZE;
+		wlen = 0;
+
 		memset(&hdr, 0, sizeof(hdr));
 		hdr.opcode = SD_OP_READ_OBJ;
-		hdr.oid = oid;
 		hdr.epoch = epoch;
-
-		rlen = SD_DATA_OBJ_SIZE;
-		wlen = 0;
 		hdr.flags = SD_FLAG_CMD_IO_LOCAL;
 		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);
+		ret = exec_req(fd, &hdr, buf, &wlen, &rlen);
 
 		close(fd);
 
@@ -302,16 +302,17 @@ 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 hdr;
+	struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
 	struct sd_vnode *v;
-	uint64_t oid = hdr.oid;
+	uint64_t oid = req->rq.obj.oid;
 	int nr_copies;
 
+	memcpy(&hdr, &req->rq, sizeof(hdr));
 	hdr.flags |= SD_FLAG_CMD_IO_LOCAL;
 
-	if (hdr.copies)
-		nr_copies = hdr.copies;
+	if (hdr.obj.copies)
+		nr_copies = hdr.obj.copies;
 	else
 		nr_copies = get_nr_copies(req->vnodes);
 
@@ -341,7 +342,7 @@ read_remote:
 		wlen = 0;
 		rlen = hdr.data_length;
 
-		ret = exec_req(fd, (struct sd_req *)&hdr, req->data, &wlen, &rlen);
+		ret = exec_req(fd, &hdr, req->data, &wlen, &rlen);
 
 		if (ret) { /* network errors */
 			del_sheep_fd(fd);
@@ -361,10 +362,10 @@ 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 hdr;
+	struct sd_rsp *rsp = (struct sd_rsp *)&req->rp;
 	struct sd_vnode *v;
-	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;
@@ -376,6 +377,7 @@ int forward_write_obj_req(struct request
 	for (i = 0; i < ARRAY_SIZE(pfds); i++)
 		pfds[i].fd = -1;
 
+	memcpy(&hdr, &req->rq, sizeof(hdr));
 	hdr.flags |= SD_FLAG_CMD_IO_LOCAL;
 
 	wlen = hdr.data_length;
@@ -398,7 +400,7 @@ int forward_write_obj_req(struct request
 			goto out;
 		}
 
-		ret = send_req(fd, (struct sd_req *)&hdr, req->data, &wlen);
+		ret = send_req(fd, &hdr, req->data, &wlen);
 		if (ret) { /* network errors */
 			del_sheep_fd(fd);
 			ret = SD_RES_NETWORK_ERROR;
@@ -537,22 +539,24 @@ int write_object_local(uint64_t oid, cha
 {
 	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);
 
@@ -568,19 +572,21 @@ int read_object_local(uint64_t oid, char
 {
 	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;
 	hdr->opcode = SD_OP_READ_OBJ;
-	hdr->copies = copies;
 	hdr->flags = 0;
-	hdr->offset = offset;
 	hdr->data_length = datalen;
+
+	hdr->obj.oid = oid;
+	hdr->obj.copies = copies;
+	hdr->obj.offset = offset;
+
 	req->data = data;
 	req->op = get_sd_op(hdr->opcode);
 
@@ -592,13 +598,12 @@ int read_object_local(uint64_t oid, char
 
 int store_remove_obj(const struct sd_req *req, struct sd_rsp *rsp, void *data)
 {
-	struct sd_obj_req *hdr = (struct sd_obj_req *)req;
-	uint32_t epoch = hdr->epoch;
+	uint32_t epoch = req->epoch;
 	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, req->obj.oid);
 	if (unlink(buf.buf) < 0) {
 		if (errno == ENOENT) {
 			ret = SD_RES_NO_OBJ;
@@ -608,7 +613,7 @@ int store_remove_obj(const struct sd_req
 		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, req->obj.oid))
 		obj_list_cache.cache_size--;
 	pthread_rwlock_unlock(&obj_list_cache.lock);
  out:
@@ -618,51 +623,50 @@ int store_remove_obj(const struct sd_req
 
 int store_read_obj(const struct sd_req *req, struct sd_rsp *rsp, void *data)
 {
-	struct sd_obj_req *hdr = (struct sd_obj_req *)req;
-	struct sd_obj_rsp *rsps = (struct sd_obj_rsp *)rsp;
+	struct sd_rsp *rsps = (struct sd_rsp *)rsp;
 	struct request *request = (struct request *)data;
 	int ret;
-	uint32_t epoch = hdr->epoch;
+	uint32_t epoch = req->epoch;
 	struct siocb iocb;
 
 	memset(&iocb, 0, sizeof(iocb));
 	iocb.epoch = epoch;
-	iocb.flags = hdr->flags;
-	ret = sd_store->open(hdr->oid, &iocb, 0);
+	iocb.flags = req->flags;
+	ret = sd_store->open(req->obj.oid, &iocb, 0);
 	if (ret != SD_RES_SUCCESS)
 		return ret;
 
 	iocb.buf = request->data;
-	iocb.length = hdr->data_length;
-	iocb.offset = hdr->offset;
-	ret = sd_store->read(hdr->oid, &iocb);
+	iocb.length = req->data_length;
+	iocb.offset = req->obj.offset;
+	ret = sd_store->read(req->obj.oid, &iocb);
 	if (ret != SD_RES_SUCCESS)
 		goto out;
 
-	rsps->data_length = hdr->data_length;
-	rsps->copies = sys->nr_sobjs;
+	rsps->data_length = req->data_length;
+	rsps->obj.copies = sys->nr_sobjs;
 out:
-	sd_store->close(hdr->oid, &iocb);
+	sd_store->close(req->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, const 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;
@@ -676,9 +680,8 @@ static int do_write_obj(struct siocb *io
 	return ret;
 }
 
-int store_write_obj(const struct sd_req *req, struct sd_rsp *rsp, void *data)
+int store_write_obj(const struct sd_req *hdr, struct sd_rsp *rsp, void *data)
 {
-	struct sd_obj_req *hdr = (struct sd_obj_req *)req;
 	struct request *request = (struct request *)data;
 	int ret;
 	uint32_t epoch = hdr->epoch;
@@ -687,30 +690,30 @@ int store_write_obj(const struct sd_req
 	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, request->data);
 
-	sd_store->close(hdr->oid, &iocb);
+	sd_store->close(hdr->obj.oid, &iocb);
 	return ret;
 }
 
-int store_create_and_write_obj(const struct sd_req *req, struct sd_rsp *rsp, void *data)
+int store_create_and_write_obj(const struct sd_req *hdr, struct sd_rsp *rsp,
+		void *data)
 {
-	struct sd_obj_req *hdr = (struct sd_obj_req *)req;
 	struct request *request = (struct request *)data;
-	struct sd_obj_req cow_hdr;
+	struct sd_req cow_hdr;
 	int ret;
 	uint32_t epoch = hdr->epoch;
 	char *buf = NULL;
 	struct siocb iocb;
 	unsigned data_length;
 
-	if (is_vdi_obj(hdr->oid))
+	if (is_vdi_obj(hdr->obj.oid))
 		data_length = SD_INODE_SIZE;
-	else if (is_vdi_attr_obj(hdr->oid))
+	else if (is_vdi_attr_obj(hdr->obj.oid))
 		data_length = SD_ATTR_OBJ_SIZE;
 	else
 		data_length = SD_DATA_OBJ_SIZE;
@@ -719,11 +722,12 @@ int store_create_and_write_obj(const str
 	iocb.epoch = epoch;
 	iocb.flags = hdr->flags;
 	iocb.length = data_length;
-	ret = sd_store->open(hdr->oid, &iocb, 1);
+	ret = sd_store->open(hdr->obj.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",
+			hdr->obj.oid, hdr->obj.cow_oid);
 
 		buf = valloc(SD_DATA_OBJ_SIZE);
 		if (!buf) {
@@ -731,16 +735,17 @@ int store_create_and_write_obj(const str
 			goto out;
 		}
 		if (hdr->data_length != SD_DATA_OBJ_SIZE) {
-			ret = read_copy_from_replica(request, hdr->epoch, hdr->cow_oid, buf);
+			ret = read_copy_from_replica(request, hdr->epoch,
+						     hdr->obj.cow_oid, buf);
 			if (ret != SD_RES_SUCCESS) {
 				eprintf("failed to read cow object\n");
 				goto out;
 			}
 		}
 
-		memcpy(buf + hdr->offset, request->data, hdr->data_length);
+		memcpy(buf + hdr->obj.offset, request->data, hdr->data_length);
 		memcpy(&cow_hdr, hdr, sizeof(cow_hdr));
-		cow_hdr.offset = 0;
+		cow_hdr.obj.offset = 0;
 		cow_hdr.data_length = SD_DATA_OBJ_SIZE;
 
 		ret = do_write_obj(&iocb, &cow_hdr, epoch, buf);
@@ -748,20 +753,20 @@ int store_create_and_write_obj(const str
 		ret = do_write_obj(&iocb, hdr, epoch, request->data);
 
 	if (SD_RES_SUCCESS == ret)
-		check_and_insert_objlist_cache(hdr->oid);
+		check_and_insert_objlist_cache(hdr->obj.oid);
 out:
 	if (buf)
 		free(buf);
-	sd_store->close(hdr->oid, &iocb);
+	sd_store->close(hdr->obj.oid, &iocb);
 	return ret;
 }
 
 static int do_local_io(struct request *req, uint32_t epoch)
 {
-	struct sd_obj_req *hdr = (struct sd_obj_req *)&req->rq;
+	struct sd_req *hdr = &req->rq;
 
 	hdr->epoch = epoch;
-	dprintf("%x, %" PRIx64" , %u\n", hdr->opcode, hdr->oid, epoch);
+	dprintf("%x, %" PRIx64" , %u\n", hdr->opcode, hdr->obj.oid, epoch);
 
 	return do_process_work(req->op, &req->rq, &req->rp, req);
 }
@@ -770,16 +775,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(hdr->obj.oid))
 		data_length = SD_INODE_SIZE;
-	else if (is_vdi_attr_obj(hdr->oid))
+	else if (is_vdi_attr_obj(hdr->obj.oid))
 		data_length = SD_ATTR_OBJ_SIZE;
 	else
 		data_length = SD_DATA_OBJ_SIZE;
@@ -792,7 +800,7 @@ static int fix_object_consistency(struct
 	memset(buf, 0, data_length);
 
 	req->data = buf;
-	hdr->offset = 0;
+	hdr->obj.offset = 0;
 	hdr->data_length = data_length;
 	hdr->opcode = SD_OP_READ_OBJ;
 	hdr->flags = 0;
@@ -805,7 +813,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) {
@@ -816,16 +824,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;
+	struct sd_req *hdr = &req->rq;
+	uint64_t oid = hdr->obj.oid;
 	uint32_t vid = oid_to_vid(oid);
 	uint32_t idx = data_oid_to_idx(oid);
 	struct object_cache *cache;
@@ -847,9 +855,9 @@ static int handle_gateway_request(struct
 	return object_cache_rw(cache, idx, req);
 }
 
-static int bypass_object_cache(struct sd_obj_req *hdr)
+static int bypass_object_cache(struct sd_req *hdr)
 {
-	uint64_t oid = hdr->oid;
+	uint64_t oid = hdr->obj.oid;
 
 	if (!(hdr->flags & SD_FLAG_CMD_CACHE)) {
 		uint32_t vid = oid_to_vid(oid);
@@ -887,16 +895,16 @@ void do_io_request(struct work *work)
 {
 	struct request *req = container_of(work, struct request, work);
 	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;
+	struct sd_req *hdr = &req->rq;
+	struct sd_rsp *rsp = (struct sd_rsp *)&req->rp;
+	uint64_t oid = hdr->obj.oid;
 	uint32_t opcode = hdr->opcode;
 	uint32_t epoch = hdr->epoch;
 
 	dprintf("%x, %" PRIx64" , %u\n", opcode, oid, epoch);
 
 	if (hdr->flags & SD_FLAG_CMD_RECOVERY)
-		epoch = hdr->tgt_epoch;
+		epoch = hdr->obj.tgt_epoch;
 
 	if (hdr->flags & SD_FLAG_CMD_IO_LOCAL) {
 		ret = do_local_io(req, epoch);
@@ -924,8 +932,8 @@ out:
 
 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;
+	struct sd_req hdr;
+	struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
 	int fd, i, ret;
 	unsigned int rlen, wlen, nr, le = get_latest_epoch();
 	char host[128];
@@ -946,12 +954,12 @@ 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;
+		hdr.obj.tgt_epoch = epoch;
 		rlen = hdr.data_length;
 		wlen = 0;
 
-		ret = exec_req(fd, (struct sd_req *)&hdr, buf, &wlen, &rlen);
+		ret = exec_req(fd, &hdr, buf, &wlen, &rlen);
 		close(fd);
 
 		if (ret)
@@ -1320,8 +1328,8 @@ static int recover_object_from_replica(u
 				       struct sd_vnode *entry,
 				       int epoch, int 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;
@@ -1365,13 +1373,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);
+	ret = exec_req(fd, &hdr, buf, &wlen, &rlen);
 
 	close(fd);
 
@@ -1381,7 +1389,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;



More information about the sheepdog mailing list