From: Liu Yuan <[email protected]> Nothing intersting, these functions are basically wrappers of sheep.c.
Signed-off-by: Liu Yuan <[email protected]> --- lib/shared/sheep.c | 3 +- lib/shared/sheepdog.h | 10 ++- lib/shared/vdi.c | 185 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 195 insertions(+), 3 deletions(-) create mode 100644 lib/shared/vdi.c diff --git a/lib/shared/sheep.c b/lib/shared/sheep.c index 3afe6f5..4c1b1f1 100644 --- a/lib/shared/sheep.c +++ b/lib/shared/sheep.c @@ -112,7 +112,8 @@ int sd_run_sdreq(struct sd_cluster *c, struct sd_req *hdr, void *data) static void aio_end_request(struct sd_request *req, int ret) { - + req->ret = ret; + eventfd_xwrite(req->efd, 1); } static void aio_rw_done(struct sheep_aiocb *aiocb) diff --git a/lib/shared/sheepdog.h b/lib/shared/sheepdog.h index c2c072c..f0be852 100644 --- a/lib/shared/sheepdog.h +++ b/lib/shared/sheepdog.h @@ -23,6 +23,7 @@ #include "util.h" #include <arpa/inet.h> +#include <sys/eventfd.h> struct sd_cluster { int sockfd; @@ -50,6 +51,8 @@ struct sd_request { size_t length; off_t offset; bool write; + int efd; + int ret; }; struct sd_vdi { @@ -57,12 +60,15 @@ struct sd_vdi { struct sd_inode *inode; uint32_t vid; struct sd_rw_lock lock; + char *name; }; -int sd_init(void); -void sd_free(void); struct sd_cluster *sd_connect(char *host); int sd_disconnect(struct sd_cluster *sd); int sd_run_sdreq(struct sd_cluster *c, struct sd_req *hdr, void *data); +struct sd_vdi *sd_vdi_open(struct sd_cluster *sd, char *name); +int sd_vdi_read(struct sd_vdi *vdi, void *buf, size_t count, off_t offset); +int sd_vdi_write(struct sd_vdi *vdi, void *buf, size_t count, off_t offset); +int sd_vdi_close(struct sd_vdi *vdi); #endif diff --git a/lib/shared/vdi.c b/lib/shared/vdi.c new file mode 100644 index 0000000..d40bd4b --- /dev/null +++ b/lib/shared/vdi.c @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2015 China Mobile Inc. + * + * Liu Yuan <[email protected]> + * + * 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 "sheepdog.h" + +static int lock_vdi(struct sd_vdi *vdi) +{ + struct sd_req hdr = {}; + struct sd_rsp *rsp = (struct sd_rsp *)&hdr; + int ret; + + hdr.opcode = SD_OP_LOCK_VDI; + hdr.data_length = SD_MAX_VDI_LEN; + hdr.flags = SD_FLAG_CMD_WRITE; + ret = sd_run_sdreq(vdi->cluster, &hdr, vdi->name); + if (ret < 0) + return ret; + + vdi->vid = rsp->vdi.vdi_id; + + return 0; +} + +static int unlock_vdi(struct sd_vdi *vdi) +{ + struct sd_req hdr = {}; + int ret; + + hdr.opcode = SD_OP_RELEASE_VDI; + hdr.vdi.type = LOCK_TYPE_NORMAL; + hdr.vdi.base_vdi_id = vdi->vid; + ret = sd_run_sdreq(vdi->cluster, &hdr, NULL); + if (ret < 0) + return ret; + return 0; +} + +static struct sd_vdi *alloc_vdi(struct sd_cluster *c, char *name) +{ + struct sd_vdi *new = xzalloc(sizeof(*new)); + + new->cluster = c; + new->name = name; + new->inode = xmalloc(sizeof(struct sd_inode)); + sd_init_rw_lock(&new->lock); + + return new; +} + +static void free_vdi(struct sd_vdi *vdi) +{ + sd_destroy_rw_lock(&vdi->lock); + free(vdi->inode); + free(vdi); +} + +struct sd_vdi *sd_vdi_open(struct sd_cluster *c, char *name) +{ + struct sd_req hdr = {}; + struct sd_vdi *new = alloc_vdi(c, name); + int ret; + + ret = lock_vdi(new); + if (ret < 0) { + errno = -ret; + goto out_free; + } + + hdr.opcode = SD_OP_READ_OBJ; + hdr.data_length = SD_INODE_SIZE; + hdr.obj.oid = vid_to_vdi_oid(new->vid); + hdr.obj.offset = 0; + ret = sd_run_sdreq(c, &hdr, new->inode); + if (ret < 0) { + errno = -ret; + goto out_unlock; + } + + if (vdi_is_snapshot(new->inode)) { + errno = EINVAL; + goto out_unlock; + } + + return new; +out_unlock: + unlock_vdi(new); +out_free: + free_vdi(new); + return NULL; +} + +static void queue_request(struct sd_request *req) +{ + struct sd_cluster *c = req->vdi->cluster; + + sd_write_lock(&c->request_lock); + list_add_tail(&req->list, &c->request_list); + sd_rw_unlock(&c->request_lock); + + eventfd_xwrite(c->request_fd, 1); +} + +static void free_request(struct sd_request *req) +{ + close(req->efd); + free(req); +} + +static struct sd_request *alloc_request(struct sd_vdi *vdi, void *buf, + size_t count, off_t offset, bool write) +{ + struct sd_request *req; + int fd; + + fd = eventfd(0, 0); + if (fd < 0) + return ERR_PTR(-errno); + req = xzalloc(sizeof(*req)); + req->efd = fd; + req->data = buf; + req->length = count; + req->offset = offset; + req->write = write; + INIT_LIST_NODE(&req->list); + req->vdi = vdi; + + return req; +} + +int sd_vdi_read(struct sd_vdi *vdi, void *buf, size_t count, off_t offset) +{ + struct sd_request *req = alloc_request(vdi, buf, count, offset, false); + int ret; + + if (IS_ERR(req)) + return PTR_ERR(req); + + queue_request(req); + + eventfd_xread(req->efd); + ret = req->ret; + free_request(req); + + return ret; +} + +int sd_vdi_write(struct sd_vdi *vdi, void *buf, size_t count, off_t offset) +{ + struct sd_request *req = alloc_request(vdi, buf, count, offset, true); + int ret; + + if (IS_ERR(req)) + return PTR_ERR(req); + + queue_request(req); + + eventfd_xread(req->efd); + ret = req->ret; + free_request(req); + + return ret; +} + +int sd_vdi_close(struct sd_vdi *vdi) +{ + int ret; + + ret = unlock_vdi(vdi); + if (ret < 0) { + fprintf(stderr, "failed to unlock %s\n", vdi->name); + return ret; + } + free_vdi(vdi); + return 0; +} -- 1.9.1 -- sheepdog mailing list [email protected] https://lists.wpkg.org/mailman/listinfo/sheepdog
