The SD_OP_REMOVE_OBJ command needs the same gateway handling as the write
commands, namely we need to find all sheep daemon that have the OID and
then forward the remove request to each of them and issue a peer remove
request.

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

---
 include/internal_proto.h |    1 
 sheep/gateway.c          |   69 +++++++++++++++++++++++++++++++++++++++++++++++
 sheep/ops.c              |   13 ++++++--
 sheep/sheep_priv.h       |    2 +
 4 files changed, 81 insertions(+), 4 deletions(-)

Index: sheepdog/include/internal_proto.h
===================================================================
--- sheepdog.orig/include/internal_proto.h	2012-07-04 16:02:14.443698778 +0200
+++ sheepdog/include/internal_proto.h	2012-07-04 16:02:22.737032062 +0200
@@ -58,6 +58,7 @@
 #define SD_OP_CREATE_AND_WRITE_PEER 0xa3
 #define SD_OP_READ_PEER      0xa4
 #define SD_OP_WRITE_PEER     0xa5
+#define SD_OP_REMOVE_PEER    0xa6
 
 /* 0x0010 was SD_FLAG_CMD_IO_LOCAL */
 #define SD_FLAG_CMD_RECOVERY 0x0020
Index: sheepdog/sheep/gateway.c
===================================================================
--- sheepdog.orig/sheep/gateway.c	2012-07-04 16:02:14.443698778 +0200
+++ sheepdog/sheep/gateway.c	2012-07-04 16:02:22.737032062 +0200
@@ -302,3 +302,72 @@ int gateway_create_and_write_obj(struct
 {
 	return do_gateway_write_obj(req, true);
 }
+
+int gateway_remove_obj(struct request *req)
+{
+	int i, err_ret = SD_RES_SUCCESS, ret, local = -1;
+	unsigned wlen;
+	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 = req->rq.obj.oid;
+	int nr_copies;
+	struct write_info wi;
+
+	dprintf("%"PRIx64"\n", oid);
+
+	write_info_init(&wi);
+	memcpy(&fwd_hdr, &req->rq, sizeof(fwd_hdr));
+	fwd_hdr.opcode = SD_OP_REMOVE_PEER;
+
+	wlen = fwd_hdr.data_length;
+
+	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 sockfd *sfd;
+
+		v = obj_vnodes[i];
+		if (vnode_is_local(v)) {
+			local = i;
+			continue;
+		}
+
+		sfd = sheep_get_sockfd(&v->nid);
+		if (!sfd) {
+			err_ret = SD_RES_NETWORK_ERROR;
+			break;
+		}
+
+		ret = send_req(sfd->fd, &fwd_hdr, req->data, &wlen);
+		if (ret) {
+			sheep_del_sockfd(&v->nid, sfd);
+			err_ret = SD_RES_NETWORK_ERROR;
+			dprintf("fail %d\n", ret);
+			break;
+		}
+		write_info_advance(&wi, v, sfd);
+	}
+
+	if (local != -1 && err_ret == SD_RES_SUCCESS) {
+		v = obj_vnodes[local];
+
+		ret = peer_remove_obj(req);
+
+		if (ret != SD_RES_SUCCESS) {
+			eprintf("fail to write local %"PRIx32"\n", ret);
+			err_ret = ret;
+		}
+	}
+
+	dprintf("nr_sent %d, err %x\n", wi.nr_sent, err_ret);
+	if (wi.nr_sent > 0) {
+		ret = wait_forward_write(&wi, rsp);
+		if (ret != SD_RES_SUCCESS)
+			err_ret = ret;
+	}
+
+	return err_ret;
+}
Index: sheepdog/sheep/ops.c
===================================================================
--- sheepdog.orig/sheep/ops.c	2012-07-04 16:02:14.443698778 +0200
+++ sheepdog/sheep/ops.c	2012-07-04 16:02:32.013698673 +0200
@@ -640,7 +640,7 @@ out:
 	return ret;
 }
 
-static int store_remove_obj(struct request *req)
+int peer_remove_obj(struct request *req)
 {
 	uint64_t oid = req->rq.obj.oid;
 
@@ -934,12 +934,12 @@ static struct sd_op_template sd_ops[] =
 		.process_work = gateway_write_obj,
 	},
 
-	/* peer I/O operations */
 	[SD_OP_REMOVE_OBJ] = {
-		.type = SD_OP_TYPE_PEER,
-		.process_work = store_remove_obj,
+		.type = SD_OP_TYPE_GATEWAY,
+		.process_work = gateway_remove_obj,
 	},
 
+	/* peer I/O operations */
 	[SD_OP_CREATE_AND_WRITE_PEER] = {
 		.type = SD_OP_TYPE_PEER,
 		.process_work = peer_create_and_write_obj,
@@ -954,6 +954,11 @@ static struct sd_op_template sd_ops[] =
 		.type = SD_OP_TYPE_PEER,
 		.process_work = peer_write_obj,
 	},
+
+	[SD_OP_REMOVE_PEER] = {
+		.type = SD_OP_TYPE_PEER,
+		.process_work = peer_remove_obj,
+	},
 };
 
 struct sd_op_template *get_sd_op(uint8_t opcode)
Index: sheepdog/sheep/sheep_priv.h
===================================================================
--- sheepdog.orig/sheep/sheep_priv.h	2012-07-04 16:02:14.443698778 +0200
+++ sheepdog/sheep/sheep_priv.h	2012-07-04 16:02:22.737032062 +0200
@@ -369,11 +369,13 @@ static inline int sys_can_halt(void)
 int gateway_read_obj(struct request *req);
 int gateway_write_obj(struct request *req);
 int gateway_create_and_write_obj(struct request *req);
+int gateway_remove_obj(struct request *req);
 
 /* backend store */
 int peer_read_obj(struct request *req);
 int peer_write_obj(struct request *req);
 int peer_create_and_write_obj(struct request *req);
+int peer_remove_obj(struct request *req);
 
 /* object_cache */
 


