From: levin li <xingke....@taobao.com>

Signed-off-by: levin li <xingke....@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....@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

-- 
sheepdog mailing list
sheepdog@lists.wpkg.org
http://lists.wpkg.org/mailman/listinfo/sheepdog

Reply via email to