[sheepdog] [PATCH v4 RESEND 4/8] sheepdev: add sheep.c to process the sheepdog protocol
levin li
levin108 at gmail.com
Wed Jan 23 09:16:13 CET 2013
From: levin li <xingke.lwp at taobao.com>
Signed-off-by: levin li <xingke.lwp at taobao.com>
---
sheepdev/Kbuild | 3 +-
sheepdev/sheep.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++++++++
sheepdev/sheepdev.h | 8 +++
3 files changed, 196 insertions(+), 1 deletion(-)
create mode 100644 sheepdev/sheep.c
diff --git a/sheepdev/Kbuild b/sheepdev/Kbuild
index 16bac26..20855c6 100644
--- a/sheepdev/Kbuild
+++ b/sheepdev/Kbuild
@@ -5,8 +5,9 @@ ccflags-y := -I$(PWD)/../include
obj-m := $(MODULE_NAME).o
-sheepdev-objs := device.o proc.o connect.o
+sheepdev-objs := device.o proc.o connect.o sheep.o
device.o : sheepdev.h sheepdog_proto.h
proc.o : sheepdev.h
+sheep.o : sheepdev.h sheepdog_proto.h
connect.o : sheepdev.h sheepdog_proto.h
diff --git a/sheepdev/sheep.c b/sheepdev/sheep.c
new file mode 100644
index 0000000..39f00f9
--- /dev/null
+++ b/sheepdev/sheep.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2013 Taobao Inc.
+ *
+ * Levin Li <xingke.lwp at taobao.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "sheepdev.h"
+
+static int read_object(struct sheepdev *dev, uint64_t oid, void *data,
+ unsigned int datalen, uint64_t offset)
+{
+ struct sd_req hdr;
+ struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
+ int ret;
+
+ memset(&hdr, 0, sizeof(hdr));
+ hdr.opcode = SD_OP_READ_OBJ;
+ hdr.id = 0;
+ hdr.data_length = datalen;
+
+ hdr.obj.oid = oid;
+ hdr.obj.offset = offset;
+
+ ret = exec_req(dev->sock, &hdr, data);
+
+ if (ret < 0) {
+ DBPRT("Failed to read object %llx\n", oid);
+ return SD_RES_EIO;
+ }
+
+ if (rsp->result != SD_RES_SUCCESS) {
+ DBPRT("Failed to read object %llx,%d\n", oid,
+ rsp->result);
+ return SD_RES_EIO;
+ }
+
+ return SD_RES_SUCCESS;
+}
+
+int send_read_req(struct sheepdev *dev, uint64_t oid,
+ unsigned int datalen, uint64_t offset)
+{
+ struct sd_req hdr;
+ int ret;
+
+ memset(&hdr, 0, sizeof(hdr));
+ hdr.opcode = SD_OP_READ_OBJ;
+ hdr.id = dev->req_id;
+ hdr.data_length = datalen;
+
+ hdr.obj.oid = oid;
+ hdr.obj.offset = offset;
+
+ ret = send_req(dev->sock, &hdr, NULL, 0);
+
+ if (dev->req_id > UINT_MAX)
+ dev->req_id = 1;
+ else
+ dev->req_id++;
+
+ if (ret < 0) {
+ DBPRT("Failed to read object %llx\n", oid);
+ return SD_RES_EIO;
+ }
+
+ return SD_RES_SUCCESS;
+}
+
+int send_write_req(struct sheepdev *dev, uint64_t oid, uint64_t cow_oid,
+ void *data, unsigned int datalen, uint64_t offset,
+ int create)
+{
+ struct sd_req hdr;
+ int ret;
+
+ memset(&hdr, 0, sizeof(hdr));
+ if (create)
+ hdr.opcode = SD_OP_CREATE_AND_WRITE_OBJ;
+ else
+ hdr.opcode = SD_OP_WRITE_OBJ;
+
+ hdr.id = dev->req_id;
+ hdr.data_length = datalen;
+ hdr.flags = SD_FLAG_CMD_WRITE | SD_FLAG_CMD_DIRECT;
+ if (cow_oid)
+ hdr.flags |= SD_FLAG_CMD_COW;
+
+ hdr.obj.oid = oid;
+ hdr.obj.cow_oid = cow_oid;
+ hdr.obj.offset = offset;
+ hdr.obj.copies = dev->inode->nr_copies;
+
+ ret = send_req(dev->sock, &hdr, data, datalen);
+
+ if (dev->req_id > UINT_MAX)
+ dev->req_id = 1;
+ else
+ dev->req_id++;
+
+ if (ret < 0) {
+ DBPRT("Failed to write object %llx\n", oid);
+ return SD_RES_EIO;
+ }
+
+ return SD_RES_SUCCESS;
+}
+
+static int find_vdi_name(struct sheepdev *dev, const char *vdiname,
+ uint32_t snapid, const char *tag)
+{
+ int ret;
+ struct sd_req hdr;
+ struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
+ char buf[SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN];
+
+ memset(buf, 0, sizeof(buf));
+ strncpy(buf, vdiname, SD_MAX_VDI_LEN);
+ strncpy(buf + SD_MAX_VDI_LEN, tag, SD_MAX_VDI_TAG_LEN);
+
+ memset(&hdr, 0, sizeof(hdr));
+ hdr.opcode = SD_OP_LOCK_VDI;
+ hdr.data_length = SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN;
+ hdr.flags = SD_FLAG_CMD_WRITE;
+ hdr.vdi.snapid = snapid;
+
+ ret = exec_req(dev->sock, &hdr, buf);
+ if (ret)
+ return -EIO;
+
+ if (rsp->result != SD_RES_SUCCESS) {
+ DBPRT("Cannot get VDI info for %s %d %s\n",
+ vdiname, snapid, tag);
+ return -EIO;
+ }
+
+ dev->vid = rsp->vdi.vdi_id;
+
+ return 0;
+}
+
+int sheep_vdi_setup(struct sheepdev *dev)
+{
+ int ret;
+ struct sheepdog_inode *inode;
+
+ inode = vmalloc(sizeof(*inode));
+ if (!inode)
+ return -ENOMEM;
+ memset(inode, 0 , sizeof(*inode));
+
+ ret = connect_to(&dev->sock, dev->ip_addr, dev->port);
+ if (ret) {
+ ret = -EFAULT;
+ goto out;
+ }
+
+ ret = find_vdi_name(dev, dev->vdiname, dev->snapshot_id,
+ dev->snapshot_tag);
+ if (ret)
+ goto out;
+
+ ret = read_object(dev, vid_to_vdi_oid(dev->vid), inode,
+ SD_INODE_SIZE, 0);
+ if (ret != SD_RES_SUCCESS) {
+ ret = -EIO;
+ goto out;
+ }
+
+ dev->size = inode->vdi_size;
+ dev->sectors = dev->size / KERNEL_SECTOR_SIZE;
+ dev->snapshot_id = inode->snap_id;
+ strncpy(dev->snapshot_tag, inode->tag, SD_MAX_VDI_TAG_LEN);
+ dev->inode = inode;
+
+ return 0;
+out:
+ vfree(inode);
+ return ret;
+}
diff --git a/sheepdev/sheepdev.h b/sheepdev/sheepdev.h
index 323178c..91a55ea 100644
--- a/sheepdev/sheepdev.h
+++ b/sheepdev/sheepdev.h
@@ -92,4 +92,12 @@ int exec_req(struct socket *sock, struct sd_req *hdr, void *data);
int sheep_proc_init(void);
void sheep_proc_destroy(void);
+/* sheep.c */
+int send_read_req(struct sheepdev *sheepdev, uint64_t oid,
+ unsigned int datalen, uint64_t offset);
+int send_write_req(struct sheepdev *sheepdev, uint64_t oid, uint64_t cow_oid,
+ void *data, unsigned int datalen, uint64_t offset,
+ int create);
+int sheep_vdi_setup(struct sheepdev *sheep_dev);
+
#endif
--
1.7.11.7
More information about the sheepdog
mailing list