Signed-off-by: MORITA Kazutaka <[email protected]>
---
 sheep/store.c |  120 +++++++++++++++++++++++++++++++++++++++-----------------
 sheep/vdi.c   |  103 ++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 159 insertions(+), 64 deletions(-)

diff --git a/sheep/store.c b/sheep/store.c
index cdf6a94..9318eed 100644
--- a/sheep/store.c
+++ b/sheep/store.c
@@ -519,10 +519,14 @@ int update_epoch_store(uint32_t epoch)
 int write_object_local(uint64_t oid, char *data, unsigned int datalen,
                       uint64_t offset, int copies, uint32_t epoch, int create)
 {
-       struct request req;
-       struct sd_obj_req *hdr = (struct sd_obj_req *)&req.rq;
+       int ret;
+       struct request *req;
+       struct sd_obj_req *hdr;
 
-       memset(&req, 0, sizeof(req));
+       req = zalloc(sizeof(*req));
+       if (!req)
+               return SD_RES_NO_MEM;
+       hdr = (struct sd_obj_req *)&req->rq;
 
        hdr->oid = oid;
        if (create)
@@ -533,20 +537,29 @@ int write_object_local(uint64_t oid, char *data, unsigned 
int datalen,
        hdr->flags = SD_FLAG_CMD_WRITE;
        hdr->offset = offset;
        hdr->data_length = datalen;
-       req.data = data;
+       req->data = data;
+
+       ret = store_queue_request_local(req, epoch);
 
-       return store_queue_request_local(&req, epoch);
+       free(req);
+
+       return ret;
 }
 
 int read_object_local(uint64_t oid, char *data, unsigned int datalen,
                      uint64_t offset, int copies, uint32_t epoch)
 {
        int ret;
-       struct request req;
-       struct sd_obj_req *hdr = (struct sd_obj_req *)&req.rq;
-       struct sd_obj_rsp *rsp = (struct sd_obj_rsp *)&req.rp;
+       struct request *req;
+       struct sd_obj_req *hdr;
+       struct sd_obj_rsp *rsp;
+       unsigned int rsp_data_length;
 
-       memset(&req, 0, sizeof(req));
+       req = zalloc(sizeof(*req));
+       if (!req)
+               return -SD_RES_NO_MEM;
+       hdr = (struct sd_obj_req *)&req->rq;
+       rsp = (struct sd_obj_rsp *)&req->rp;
 
        hdr->oid = oid;
        hdr->opcode = SD_OP_READ_OBJ;
@@ -554,17 +567,20 @@ int read_object_local(uint64_t oid, char *data, unsigned 
int datalen,
        hdr->flags = 0;
        hdr->offset = offset;
        hdr->data_length = datalen;
-       req.data = data;
+       req->data = data;
 
-       ret = store_queue_request_local(&req, epoch);
+       ret = store_queue_request_local(req, epoch);
+
+       rsp_data_length = rsp->data_length;
+       free(req);
 
        if (ret != 0)
                return -ret;
 
-       if (rsp->data_length != datalen)
+       if (rsp_data_length != datalen)
                return -SD_RES_EIO;
 
-       return rsp->data_length;
+       return rsp_data_length;
 }
 
 static int store_queue_request_local(struct request *req, uint32_t epoch)
@@ -1195,12 +1211,19 @@ static int __recover_one(struct recovery_work *rw,
        char name[128];
        unsigned wlen = 0, rlen;
        int fd, ret;
-       struct sheepdog_vnode_list_entry old_entry[SD_MAX_VNODES],
-               cur_entry[SD_MAX_VNODES], next_entry[SD_MAX_VNODES];
+       struct sheepdog_vnode_list_entry *old_entry, *cur_entry, *next_entry;
        int next_nr, next_copies;
        int tgt_idx = -1;
        int old_idx;
 
+       old_entry = malloc(sizeof(*old_entry) * SD_MAX_VNODES);
+       cur_entry = malloc(sizeof(*cur_entry) * SD_MAX_VNODES);
+       next_entry = malloc(sizeof(*next_entry) * SD_MAX_VNODES);
+       if (!old_entry || !cur_entry || !next_entry) {
+               eprintf("oom\n");
+               goto err;
+       }
+
        memcpy(old_entry, _old_entry, sizeof(*old_entry) * old_nr);
        memcpy(cur_entry, _cur_entry, sizeof(*cur_entry) * cur_nr);
 next:
@@ -1211,7 +1234,7 @@ next:
                                cur_entry, cur_nr, cur_idx, cur_copies, 
copy_idx);
        if (tgt_idx < 0) {
                eprintf("cannot find target node, %"PRIx64"\n", oid);
-               return -1;
+               goto err;
        }
        e = old_entry + tgt_idx;
 
@@ -1224,13 +1247,13 @@ next:
                         epoch, oid);
                dprintf("link from %s to %s\n", old, new);
                if (link(old, new) == 0)
-                       return 0;
+                       goto out;
 
                if (errno == ENOENT) {
                        next_nr = epoch_log_read(tgt_epoch - 1, buf, buf_len);
                        if (next_nr <= 0) {
                                eprintf("no previous epoch, %"PRIu32"\n", 
tgt_epoch - 1);
-                               return -1;
+                               goto err;
                        }
                        next_nr /= sizeof(struct sheepdog_node_list_entry);
                        next_copies = get_max_copies((struct 
sheepdog_node_list_entry *)buf,
@@ -1241,7 +1264,7 @@ next:
                }
 
                eprintf("cannot recover from local, %s, %s\n", old, new);
-               return -1;
+               goto err;
        }
 
        addr_to_str(name, sizeof(name), e->addr, 0);
@@ -1249,7 +1272,7 @@ next:
        fd = connect_to(name, e->port);
        if (fd < 0) {
                eprintf("failed to connect to %s:%"PRIu32"\n", name, e->port);
-               return -1;
+               goto err;
        }
 
        if (is_vdi_obj(oid))
@@ -1273,7 +1296,7 @@ next:
 
        if (ret < 0) {
                eprintf("%"PRIu32"\n", rsp->result);
-               return -1;
+               goto err;
        }
 
        rsp = (struct sd_obj_rsp *)&hdr;
@@ -1290,20 +1313,20 @@ next:
                fd = open(tmp_path, flags, def_fmode);
                if (fd < 0) {
                        eprintf("failed to open %s, %s\n", tmp_path, 
strerror(errno));
-                       return -1;
+                       goto err;
                }
 
                ret = write(fd, buf, rlen);
                if (ret != rlen) {
                        eprintf("failed to write object\n");
-                       return -1;
+                       goto err;
                }
 
                ret = fsetxattr(fd, ANAME_COPIES, &rsp->copies,
                                sizeof(rsp->copies), 0);
                if (ret) {
                        eprintf("couldn't set xattr\n");
-                       return -1;
+                       goto err;
                }
 
                close(fd);
@@ -1312,22 +1335,22 @@ next:
                ret = rename(tmp_path, path);
                if (ret < 0) {
                        eprintf("failed to rename %s to %s, %m\n", tmp_path, 
path);
-                       return -1;
+                       goto err;
                }
                dprintf("recovered oid %"PRIx64" to epoch %"PRIu32"\n", oid, 
epoch);
-               return 0;
+               goto out;
        }
 
        if (rsp->result == SD_RES_NEW_NODE_VER || rsp->result == 
SD_RES_OLD_NODE_VER
            || rsp->result == SD_RES_NETWORK_ERROR) {
                eprintf("try again, %"PRIu32", %"PRIx64"\n", rsp->result, oid);
                rw->retry = 1;
-               return 0;
+               goto out;
        }
 
        if (rsp->result != SD_RES_NO_OBJ || rsp->data_length == 0) {
                eprintf("%"PRIu32"\n", rsp->result);
-               return -1;
+               goto err;
        }
        next_nr = rsp->data_length / sizeof(struct sheepdog_node_list_entry);
        next_copies = get_max_copies((struct sheepdog_node_list_entry *)buf, 
next_nr);
@@ -1340,7 +1363,7 @@ not_found:
                        break;
        if (copy_idx == old_copies) {
                eprintf("bug: cannot find the proper copy_idx\n");
-               return -1;
+               goto err;
        }
 
        dprintf("%"PRIu32", %"PRIu32", %"PRIu32", %"PRIu32", %"PRIu32", 
%"PRIu32"\n", rsp->result, rsp->data_length, tgt_idx,
@@ -1356,6 +1379,16 @@ not_found:
 
        tgt_epoch--;
        goto next;
+out:
+       free(old_entry);
+       free(cur_entry);
+       free(next_entry);
+       return 0;
+err:
+       free(old_entry);
+       free(cur_entry);
+       free(next_entry);
+       return -1;
 }
 
 static void recover_one(struct work *work, int idx)
@@ -1364,10 +1397,8 @@ static void recover_one(struct work *work, int idx)
        char *buf = NULL;
        int ret;
        uint64_t oid = rw->oids[rw->done];
-       struct sheepdog_node_list_entry old_nodes[SD_MAX_NODES];
-       struct sheepdog_node_list_entry cur_nodes[SD_MAX_NODES];
-       struct sheepdog_vnode_list_entry old_vnodes[SD_MAX_VNODES];
-       struct sheepdog_vnode_list_entry cur_vnodes[SD_MAX_VNODES];
+       struct sheepdog_node_list_entry *old_nodes, *cur_nodes;
+       struct sheepdog_vnode_list_entry *old_vnodes, *cur_vnodes;
        int old_nr_nodes, cur_nr_nodes, old_nr_vnodes, cur_nr_vnodes;
        int old_copies, cur_copies;
        uint32_t epoch = rw->epoch;
@@ -1376,6 +1407,15 @@ static void recover_one(struct work *work, int idx)
 
        eprintf("%"PRIu32" %"PRIu32", %16"PRIx64"\n", rw->done, rw->count, oid);
 
+       old_nodes = malloc(sizeof(*old_nodes) * SD_MAX_NODES);
+       cur_nodes = malloc(sizeof(*cur_nodes) * SD_MAX_NODES);
+       old_vnodes = malloc(sizeof(*old_vnodes) * SD_MAX_VNODES);
+       cur_vnodes = malloc(sizeof(*cur_vnodes) * SD_MAX_VNODES);
+       if (!old_nodes || !cur_nodes || !old_vnodes || !cur_vnodes) {
+               eprintf("oom\n");
+               goto out;
+       }
+
        fd = ob_open(epoch, oid, 0, &ret);
        if (fd != -1) {
                /* the object is already recovered */
@@ -1451,8 +1491,11 @@ static void recover_one(struct work *work, int idx)
 fail:
        eprintf("failed to recover object %"PRIx64"\n", oid);
 out:
-       if (buf)
-               free(buf);
+       free(old_nodes);
+       free(cur_nodes);
+       free(old_vnodes);
+       free(cur_vnodes);
+       free(buf);
 }
 
 static struct recovery_work *suspended_recovery_work;
@@ -1685,11 +1728,12 @@ static int fill_obj_list(struct recovery_work *rw,
        int i, j;
        uint8_t *buf = NULL;
        size_t buf_size = SD_DATA_OBJ_SIZE; /* FIXME */
-       struct sheepdog_vnode_list_entry vnodes[SD_MAX_VNODES];
+       struct sheepdog_vnode_list_entry *vnodes;
        int nr_vnodes, retry_cnt = 0;
 
+       vnodes = malloc(sizeof(*vnodes) * SD_MAX_VNODES);
        buf = malloc(buf_size);
-       if (!buf)
+       if (!buf || !vnodes)
                goto fail;
 
        nr_vnodes = nodes_to_vnodes(cur_entry, cur_nr, vnodes);
@@ -1722,9 +1766,11 @@ static int fill_obj_list(struct recovery_work *rw,
                                          rw->count, (uint64_t *)buf, nr, 
nr_objs);
        }
 
+       free(vnodes);
        free(buf);
        return 0;
 fail:
+       free(vnodes);
        free(buf);
        rw->retry = 1;
        return -1;
diff --git a/sheep/vdi.c b/sheep/vdi.c
index 3655005..4291416 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -21,17 +21,25 @@ static int create_vdi_obj(uint32_t epoch, char *name, 
uint32_t new_vid, uint64_t
                          uint32_t base_vid, uint32_t cur_vid, uint32_t copies,
                          uint32_t snapid, int is_snapshot)
 {
-       struct sheepdog_vnode_list_entry entries[SD_MAX_VNODES];
+       struct sheepdog_vnode_list_entry *entries;
        /* we are not called concurrently */
        struct sheepdog_inode *new = NULL, *base = NULL, *cur = NULL;
        struct timeval tv;
        int ret, nr_vnodes, nr_zones;
        unsigned long block_size = SD_DATA_OBJ_SIZE;
 
+       entries = malloc(sizeof(*entries) * SD_MAX_VNODES);
+       if (!entries) {
+               eprintf("oom\n");
+               ret = SD_RES_NO_MEM;
+               goto out;
+       }
+
        new = zalloc(sizeof(*new));
        if (!new) {
                eprintf("oom\n");
-               return SD_RES_NO_MEM;
+               ret = SD_RES_NO_MEM;
+               goto out;
        }
 
        if (base_vid) {
@@ -141,6 +149,7 @@ static int create_vdi_obj(uint32_t epoch, char *name, 
uint32_t new_vid, uint64_t
        if (ret != 0)
                ret = SD_RES_VDI_WRITE;
 out:
+       free(entries);
        free(new);
        free(cur);
        free(base);
@@ -152,14 +161,15 @@ static int find_first_vdi(uint32_t epoch, unsigned long 
start, unsigned long end
                          unsigned long *deleted_nr, uint32_t *next_snap,
                          unsigned int *nr_copies)
 {
-       struct sheepdog_vnode_list_entry entries[SD_MAX_VNODES];
+       struct sheepdog_vnode_list_entry *entries;
        struct sheepdog_inode *inode = NULL;
        unsigned long i;
        int nr_vnodes, nr_zones, nr_reqs;
        int ret, vdi_found = 0;
 
+       entries = malloc(sizeof(*entries) * SD_MAX_VNODES);
        inode = malloc(SD_INODE_HEADER_SIZE);
-       if (!inode) {
+       if (!inode || !entries) {
                eprintf("oom\n");
                ret = SD_RES_NO_MEM;
                goto out;
@@ -207,6 +217,7 @@ static int find_first_vdi(uint32_t epoch, unsigned long 
start, unsigned long end
                ret = SD_RES_NO_VDI;
 out:
        free(inode);
+       free(entries);
 
        return ret;
 }
@@ -342,12 +353,13 @@ int del_vdi(uint32_t epoch, char *data, int data_len, 
uint32_t *vid,
        uint32_t dummy0;
        unsigned long dummy1, dummy2;
        int ret;
-       struct sheepdog_vnode_list_entry entries[SD_MAX_VNODES];
+       struct sheepdog_vnode_list_entry *entries;
        int nr_vnodes, nr_zones, nr_reqs;
        struct sheepdog_inode *inode = NULL;
 
        inode = malloc(SD_INODE_HEADER_SIZE);
-       if (!inode) {
+       entries = malloc(sizeof(*entries) * SD_MAX_VNODES);
+       if (!inode || !entries) {
                eprintf("oom\n");
                ret = SD_RES_NO_MEM;
                goto out;
@@ -393,6 +405,7 @@ int del_vdi(uint32_t epoch, char *data, int data_len, 
uint32_t *vid,
        ret = start_deletion(*vid, epoch);
 out:
        free(inode);
+       free(entries);
 
        return ret;
 }
@@ -427,15 +440,16 @@ static void delete_one(struct work *work, int idx)
 {
        struct deletion_work *dw = container_of(work, struct deletion_work, 
work);
        uint32_t vdi_id = *(((uint32_t *)dw->buf) + dw->count - dw->done - 1);
-       struct sheepdog_vnode_list_entry entries[SD_MAX_VNODES];
+       struct sheepdog_vnode_list_entry *entries;
        int nr_vnodes, nr_zones;
        int ret, i;
        struct sheepdog_inode *inode = NULL;
 
        eprintf("%d %d, %16x\n", dw->done, dw->count, vdi_id);
 
+       entries = malloc(sizeof(*entries) * SD_MAX_VNODES);
        inode = malloc(sizeof(*inode));
-       if (!inode) {
+       if (!inode || !entries) {
                eprintf("oom\n");
                goto out;
        }
@@ -465,6 +479,7 @@ static void delete_one(struct work *work, int idx)
                              inode->nr_copies);
        }
 out:
+       free(entries);
        free(inode);
 }
 
@@ -576,19 +591,27 @@ out:
 
 int start_deletion(uint32_t vid, uint32_t epoch)
 {
-       struct deletion_work *dw;
-       struct sheepdog_vnode_list_entry entries[SD_MAX_VNODES];
+       struct deletion_work *dw = NULL;
+       struct sheepdog_vnode_list_entry *entries;
        int nr_vnodes, nr_zones, ret;
        uint32_t root_vid;
 
+       entries = malloc(sizeof(*entries) * SD_MAX_VNODES);
+       if (!entries) {
+               eprintf("oom\n");
+               ret = SD_RES_NO_MEM;
+               goto err;
+       }
        dw = zalloc(sizeof(struct deletion_work));
-       if (!dw)
-               return SD_RES_NO_MEM;
+       if (!dw) {
+               ret = SD_RES_NO_MEM;
+               goto err;
+       }
 
        dw->buf = zalloc(1 << 20); /* FIXME: handle larger buffer */
        if (!dw->buf) {
-               free(dw);
-               return SD_RES_NO_MEM;
+               ret = SD_RES_NO_MEM;
+               goto err;
        }
 
        dw->count = 0;
@@ -601,8 +624,10 @@ int start_deletion(uint32_t vid, uint32_t epoch)
        get_ordered_sd_vnode_list(entries, &nr_vnodes, &nr_zones);
 
        root_vid = get_vdi_root(entries, nr_vnodes, nr_zones, dw->epoch, 
dw->vid);
-       if (!root_vid)
-               return SD_RES_EIO;
+       if (!root_vid) {
+               ret = SD_RES_EIO;
+               goto err;
+       }
 
        ret = fill_vdi_list(dw, entries, nr_vnodes, nr_zones, root_vid);
        if (ret)
@@ -611,30 +636,48 @@ int start_deletion(uint32_t vid, uint32_t epoch)
        dprintf("%d\n", dw->count);
 
        if (dw->count == 0)
-               return SD_RES_SUCCESS;
+               goto out;
 
        if (!list_empty(&deletion_work_list)) {
                list_add_tail(&dw->dw_siblings, &deletion_work_list);
-               return SD_RES_SUCCESS;
+               goto out;
        }
 
        list_add_tail(&dw->dw_siblings, &deletion_work_list);
        queue_work(&dw->work);
+out:
+       free(entries);
 
        return SD_RES_SUCCESS;
+err:
+       free(entries);
+       if (dw)
+               free(dw->buf);
+       free(dw);
+
+       return ret;
 }
 
 int get_vdi_attr(uint32_t epoch, char *data, int data_len, uint32_t vid,
                 uint32_t *attrid, int copies, int creat, int excl)
 {
-       struct sheepdog_vnode_list_entry entries[SD_MAX_VNODES];
+       struct sheepdog_vnode_list_entry *entries;
        char attr_buf[SD_ATTR_HEADER_SIZE];
        uint64_t oid;
        uint32_t end;
        int ret, nr_zones, nr_vnodes;
 
-       if (data_len != SD_ATTR_HEADER_SIZE)
-               return SD_RES_INVALID_PARMS;
+       entries = malloc(sizeof(*entries) * SD_MAX_VNODES);
+       if (!entries) {
+               eprintf("oom\n");
+               ret = SD_RES_NO_MEM;
+               goto out;
+       }
+
+       if (data_len != SD_ATTR_HEADER_SIZE) {
+               ret = SD_RES_INVALID_PARMS;
+               goto out;
+       }
 
        get_ordered_sd_vnode_list(entries, &nr_vnodes, &nr_zones);
 
@@ -651,9 +694,10 @@ int get_vdi_attr(uint32_t epoch, char *data, int data_len, 
uint32_t vid,
                        ret = write_object(entries, nr_vnodes, nr_zones, epoch, 
oid, data,
                                           data_len, 0, copies, 1);
                        if (ret)
-                               return SD_RES_EIO;
-
-                       return SD_RES_SUCCESS;
+                               ret = SD_RES_EIO;
+                       else
+                               ret = SD_RES_SUCCESS;
+                       goto out;
                }
 
                if (ret < 0)
@@ -661,14 +705,19 @@ int get_vdi_attr(uint32_t epoch, char *data, int 
data_len, uint32_t vid,
 
                if (memcmp(attr_buf, data, sizeof(attr_buf)) == 0) {
                        if (excl)
-                               return SD_RES_VDI_EXIST;
+                               ret = SD_RES_VDI_EXIST;
                        else
-                               return SD_RES_SUCCESS;
+                               ret = SD_RES_SUCCESS;
+                       goto out;
                }
 
                (*attrid)++;
        }
 
        dprintf("there is no space for new vdis\n");
-       return SD_RES_FULL_VDI;
+       ret = SD_RES_FULL_VDI;
+out:
+       free(entries);
+
+       return ret;
 }
-- 
1.7.2.5

-- 
sheepdog mailing list
[email protected]
http://lists.wpkg.org/mailman/listinfo/sheepdog

Reply via email to