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