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

Reply via email to