Signed-off-by: MORITA Kazutaka <[email protected]>
---
 sheep/vdi.c |  255 +++++++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 171 insertions(+), 84 deletions(-)

diff --git a/sheep/vdi.c b/sheep/vdi.c
index b6ffeed..3655005 100644
--- a/sheep/vdi.c
+++ b/sheep/vdi.c
@@ -23,19 +23,45 @@ static int create_vdi_obj(uint32_t epoch, char *name, 
uint32_t new_vid, uint64_t
 {
        struct sheepdog_vnode_list_entry entries[SD_MAX_VNODES];
        /* we are not called concurrently */
-       static struct sheepdog_inode new, base, cur;
+       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;
 
+       new = zalloc(sizeof(*new));
+       if (!new) {
+               eprintf("oom\n");
+               return SD_RES_NO_MEM;
+       }
+
+       if (base_vid) {
+               base = zalloc(sizeof(*base));
+               if (!base) {
+                       eprintf("oom\n");
+                       ret = SD_RES_NO_MEM;
+                       goto out;
+               }
+       }
+
+       if (is_snapshot && cur_vid != base_vid) {
+               cur = zalloc(SD_INODE_HEADER_SIZE);
+               if (!cur) {
+                       eprintf("oom\n");
+                       ret = SD_RES_NO_MEM;
+                       goto out;
+               }
+       }
+
        get_ordered_sd_vnode_list(entries, &nr_vnodes, &nr_zones);
 
        if (base_vid) {
                ret = read_object(entries, nr_vnodes, nr_zones, epoch,
-                                 vid_to_vdi_oid(base_vid), (char *)&base,
-                                 sizeof(base), 0, copies);
-               if (ret < 0)
-                       return SD_RES_BASE_VDI_READ;
+                                 vid_to_vdi_oid(base_vid), (char *)base,
+                                 sizeof(*base), 0, copies);
+               if (ret < 0) {
+                       ret = SD_RES_BASE_VDI_READ;
+                       goto out;
+               }
        }
 
        gettimeofday(&tv, NULL);
@@ -46,73 +72,78 @@ static int create_vdi_obj(uint32_t epoch, char *name, 
uint32_t new_vid, uint64_t
                                name, cur_vid, base_vid);
 
                        ret = read_object(entries, nr_vnodes, nr_zones, epoch,
-                                         vid_to_vdi_oid(cur_vid), (char *)&cur,
+                                         vid_to_vdi_oid(cur_vid), (char *)cur,
                                          SD_INODE_HEADER_SIZE, 0, copies);
                        if (ret < 0) {
                                vprintf(SDOG_ERR "failed\n");
-                               return SD_RES_BASE_VDI_READ;
+                               ret = SD_RES_BASE_VDI_READ;
+                               goto out;
                        }
 
-                       cur.snap_ctime = (uint64_t) tv.tv_sec << 32 | 
tv.tv_usec * 1000;
+                       cur->snap_ctime = (uint64_t) tv.tv_sec << 32 | 
tv.tv_usec * 1000;
                } else
-                       base.snap_ctime = (uint64_t) tv.tv_sec << 32 | 
tv.tv_usec * 1000;
+                       base->snap_ctime = (uint64_t) tv.tv_sec << 32 | 
tv.tv_usec * 1000;
        }
 
-       memset(&new, 0, sizeof(new));
-
-       strncpy(new.name, name, sizeof(new.name));
-       new.vdi_id = new_vid;
-       new.ctime = (uint64_t) tv.tv_sec << 32 | tv.tv_usec * 1000;
-       new.vdi_size = size;
-       new.copy_policy = 0;
-       new.nr_copies = copies;
-       new.block_size_shift = find_next_bit(&block_size, BITS_PER_LONG, 0);
-       new.snap_id = snapid;
+       strncpy(new->name, name, sizeof(new->name));
+       new->vdi_id = new_vid;
+       new->ctime = (uint64_t) tv.tv_sec << 32 | tv.tv_usec * 1000;
+       new->vdi_size = size;
+       new->copy_policy = 0;
+       new->nr_copies = copies;
+       new->block_size_shift = find_next_bit(&block_size, BITS_PER_LONG, 0);
+       new->snap_id = snapid;
 
        if (base_vid) {
                int i;
 
-               new.parent_vdi_id = base_vid;
-               memcpy(new.data_vdi_id, base.data_vdi_id, 
sizeof(new.data_vdi_id));
+               new->parent_vdi_id = base_vid;
+               memcpy(new->data_vdi_id, base->data_vdi_id, 
sizeof(new->data_vdi_id));
 
-               for (i = 0; i < ARRAY_SIZE(base.child_vdi_id); i++) {
-                       if (!base.child_vdi_id[i]) {
-                               base.child_vdi_id[i] = new_vid;
+               for (i = 0; i < ARRAY_SIZE(base->child_vdi_id); i++) {
+                       if (!base->child_vdi_id[i]) {
+                               base->child_vdi_id[i] = new_vid;
                                break;
                        }
                }
 
-               if (i == ARRAY_SIZE(base.child_vdi_id))
-                       return SD_RES_NO_BASE_VDI;
-
+               if (i == ARRAY_SIZE(base->child_vdi_id)) {
+                       ret = SD_RES_NO_BASE_VDI;
+                       goto out;
+               }
        }
 
        if (is_snapshot && cur_vid != base_vid) {
                ret = write_object(entries, nr_vnodes, nr_zones, epoch,
-                                  vid_to_vdi_oid(cur_vid), (char *)&cur,
+                                  vid_to_vdi_oid(cur_vid), (char *)cur,
                                   SD_INODE_HEADER_SIZE, 0, copies, 0);
                if (ret != 0) {
                        vprintf(SDOG_ERR "failed\n");
-                       return SD_RES_BASE_VDI_READ;
+                       ret = SD_RES_BASE_VDI_READ;
+                       goto out;
                }
        }
 
        if (base_vid) {
                ret = write_object(entries, nr_vnodes, nr_zones, epoch,
-                                  vid_to_vdi_oid(base_vid), (char *)&base,
+                                  vid_to_vdi_oid(base_vid), (char *)base,
                                   SD_INODE_HEADER_SIZE, 0, copies, 0);
                if (ret != 0) {
                        vprintf(SDOG_ERR "failed\n");
-                       return SD_RES_BASE_VDI_WRITE;
+                       ret = SD_RES_BASE_VDI_WRITE;
+                       goto out;
                }
        }
 
        ret = write_object(entries, nr_vnodes, nr_zones, epoch,
-                          vid_to_vdi_oid(new_vid), (char *)&new, sizeof(new),
+                          vid_to_vdi_oid(new_vid), (char *)new, sizeof(*new),
                           0, copies, 1);
        if (ret != 0)
-               return SD_RES_VDI_WRITE;
-
+               ret = SD_RES_VDI_WRITE;
+out:
+       free(new);
+       free(cur);
+       free(base);
        return ret;
 }
 
@@ -122,11 +153,18 @@ static int find_first_vdi(uint32_t epoch, unsigned long 
start, unsigned long end
                          unsigned int *nr_copies)
 {
        struct sheepdog_vnode_list_entry entries[SD_MAX_VNODES];
-       static struct sheepdog_inode inode;
+       struct sheepdog_inode *inode = NULL;
        unsigned long i;
        int nr_vnodes, nr_zones, nr_reqs;
        int ret, vdi_found = 0;
 
+       inode = malloc(SD_INODE_HEADER_SIZE);
+       if (!inode) {
+               eprintf("oom\n");
+               ret = SD_RES_NO_MEM;
+               goto out;
+       }
+
        get_ordered_sd_vnode_list(entries, &nr_vnodes, &nr_zones);
 
        nr_reqs = sys->nr_sobjs;
@@ -135,35 +173,42 @@ static int find_first_vdi(uint32_t epoch, unsigned long 
start, unsigned long end
 
        for (i = start; i >= end; i--) {
                ret = read_object(entries, nr_vnodes, nr_zones, epoch,
-                                 vid_to_vdi_oid(i), (char *)&inode,
+                                 vid_to_vdi_oid(i), (char *)inode,
                                  SD_INODE_HEADER_SIZE, 0, nr_reqs);
-               if (ret < 0)
-                       return SD_RES_EIO;
+               if (ret < 0) {
+                       ret = SD_RES_EIO;
+                       goto out;
+               }
 
-               if (inode.name[0] == '\0') {
+               if (inode->name[0] == '\0') {
                        *deleted_nr = i;
                        continue; /* deleted */
                }
 
-               if (!strncmp(inode.name, name, strlen(inode.name))) {
+               if (!strncmp(inode->name, name, strlen(inode->name))) {
                        vdi_found = 1;
                        if (tag && tag[0] &&
-                           strncmp(inode.tag, tag, sizeof(inode.tag)) != 0)
+                           strncmp(inode->tag, tag, sizeof(inode->tag)) != 0)
                                continue;
-                       if (snapid && snapid != inode.snap_id)
+                       if (snapid && snapid != inode->snap_id)
                                continue;
 
-                       *next_snap = inode.snap_id + 1;
-                       *vid = inode.vdi_id;
-                       *nr_copies = inode.nr_copies;
-                       return SD_RES_SUCCESS;
+                       *next_snap = inode->snap_id + 1;
+                       *vid = inode->vdi_id;
+                       *nr_copies = inode->nr_copies;
+                       ret = SD_RES_SUCCESS;
+                       goto out;
                }
        }
 
        if (vdi_found)
-               return SD_RES_NO_TAG;
+               ret = SD_RES_NO_TAG;
+       else
+               ret = SD_RES_NO_VDI;
+out:
+       free(inode);
 
-       return SD_RES_NO_VDI;
+       return ret;
 }
 
 
@@ -299,19 +344,28 @@ int del_vdi(uint32_t epoch, char *data, int data_len, 
uint32_t *vid,
        int ret;
        struct sheepdog_vnode_list_entry entries[SD_MAX_VNODES];
        int nr_vnodes, nr_zones, nr_reqs;
-       static struct sheepdog_inode inode;
+       struct sheepdog_inode *inode = NULL;
+
+       inode = malloc(SD_INODE_HEADER_SIZE);
+       if (!inode) {
+               eprintf("oom\n");
+               ret = SD_RES_NO_MEM;
+               goto out;
+       }
 
        if (data_len == SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN)
                tag = data + SD_MAX_VDI_LEN;
        else if (data_len == SD_MAX_VDI_LEN)
                tag = NULL;
-       else
-               return SD_RES_INVALID_PARMS;
+       else {
+               ret = SD_RES_INVALID_PARMS;
+               goto out;
+       }
 
        ret = do_lookup_vdi(epoch, name, strlen(name), vid, tag, snapid,
                            &dummy0, &dummy1, &dummy2, nr_copies);
        if (ret != SD_RES_SUCCESS)
-               return ret;
+               goto out;
 
        get_ordered_sd_vnode_list(entries, &nr_vnodes, &nr_zones);
        nr_reqs = sys->nr_sobjs;
@@ -319,24 +373,28 @@ int del_vdi(uint32_t epoch, char *data, int data_len, 
uint32_t *vid,
                nr_reqs = nr_zones;
 
        ret = read_object(entries, nr_vnodes, nr_zones, epoch,
-                         vid_to_vdi_oid(*vid), (char *)&inode,
+                         vid_to_vdi_oid(*vid), (char *)inode,
                          SD_INODE_HEADER_SIZE, 0, nr_reqs);
-       if (ret < 0)
-               return SD_RES_EIO;
+       if (ret < 0) {
+               ret = SD_RES_EIO;
+               goto out;
+       }
 
-       memset(inode.name, 0, sizeof(inode.name));
+       memset(inode->name, 0, sizeof(inode->name));
 
        ret = write_object(entries, nr_vnodes, nr_zones, epoch,
-                          vid_to_vdi_oid(*vid), (char *)&inode,
+                          vid_to_vdi_oid(*vid), (char *)inode,
                           SD_INODE_HEADER_SIZE, 0, nr_reqs, 0);
-       if (ret != 0)
-               return SD_RES_EIO;
+       if (ret != 0) {
+               ret = SD_RES_EIO;
+               goto out;
+       }
 
        ret = start_deletion(*vid, epoch);
-       if (ret != SD_RES_SUCCESS)
-               return ret;
+out:
+       free(inode);
 
-       return SD_RES_SUCCESS;
+       return ret;
 }
 
 int read_vdis(char *data, int len, unsigned int *rsp_len)
@@ -372,10 +430,16 @@ static void delete_one(struct work *work, int idx)
        struct sheepdog_vnode_list_entry entries[SD_MAX_VNODES];
        int nr_vnodes, nr_zones;
        int ret, i;
-       static struct sheepdog_inode inode;
+       struct sheepdog_inode *inode = NULL;
 
        eprintf("%d %d, %16x\n", dw->done, dw->count, vdi_id);
 
+       inode = malloc(sizeof(*inode));
+       if (!inode) {
+               eprintf("oom\n");
+               goto out;
+       }
+
        /*
         * FIXME: can't use get_ordered_sd_node_list() here since this
         * is called in threads and not serialized with cpg_event so
@@ -384,22 +448,24 @@ static void delete_one(struct work *work, int idx)
        get_ordered_sd_vnode_list(entries, &nr_vnodes, &nr_zones);
 
        ret = read_object(entries, nr_vnodes, nr_zones, dw->epoch,
-                         vid_to_vdi_oid(vdi_id), (void *)&inode, sizeof(inode),
+                         vid_to_vdi_oid(vdi_id), (void *)inode, sizeof(*inode),
                          0, sys->nr_sobjs);
 
-       if (ret != sizeof(inode)) {
+       if (ret != sizeof(*inode)) {
                eprintf("cannot find vdi object\n");
-               return;
+               goto out;
        }
 
        for (i = 0; i < MAX_DATA_OBJS; i++) {
-               if (!inode.data_vdi_id[i])
+               if (!inode->data_vdi_id[i])
                        continue;
 
                remove_object(entries, nr_vnodes, nr_zones, dw->epoch,
-                             vid_to_data_oid(inode.data_vdi_id[i], i),
-                             inode.nr_copies);
+                             vid_to_data_oid(inode->data_vdi_id[i], i),
+                             inode->nr_copies);
        }
+out:
+       free(inode);
 }
 
 static void delete_one_done(struct work *work, int idx)
@@ -430,36 +496,46 @@ static int fill_vdi_list(struct deletion_work *dw,
                         int nr_vnodes, int nr_zones, uint32_t root_vid)
 {
        int ret, i;
-       static struct sheepdog_inode inode;
+       struct sheepdog_inode *inode = NULL;
        int done = dw->count;
        uint32_t vid;
 
+       inode = malloc(SD_INODE_HEADER_SIZE);
+       if (!inode) {
+               eprintf("oom\n");
+               goto err;
+       }
+
        ((uint32_t *)dw->buf)[dw->count++] = root_vid;
 again:
        vid = ((uint32_t *)dw->buf)[done++];
        ret = read_object(entries, nr_vnodes, nr_zones, dw->epoch,
-                         vid_to_vdi_oid(vid), (void *)&inode,
+                         vid_to_vdi_oid(vid), (char *)inode,
                          SD_INODE_HEADER_SIZE, 0, sys->nr_sobjs);
 
        if (ret != SD_INODE_HEADER_SIZE) {
                eprintf("cannot find vdi object\n");
-               return 0;
+               goto err;
        }
 
-       if (inode.name[0] != '\0')
-               return 1;
+       if (inode->name[0] != '\0')
+               goto out;
 
-       for (i = 0; i < ARRAY_SIZE(inode.child_vdi_id); i++) {
-               if (!inode.child_vdi_id[i])
+       for (i = 0; i < ARRAY_SIZE(inode->child_vdi_id); i++) {
+               if (!inode->child_vdi_id[i])
                        continue;
 
-               ((uint32_t *)dw->buf)[dw->count++] = inode.child_vdi_id[i];
+               ((uint32_t *)dw->buf)[dw->count++] = inode->child_vdi_id[i];
        }
 
        if (((uint32_t *)dw->buf)[done])
                goto again;
-
+err:
+       free(inode);
        return 0;
+out:
+       free(inode);
+       return 1;
 }
 
 static uint64_t get_vdi_root(struct sheepdog_vnode_list_entry *entries,
@@ -467,24 +543,35 @@ static uint64_t get_vdi_root(struct 
sheepdog_vnode_list_entry *entries,
                             uint32_t vid)
 {
        int ret;
-       static struct sheepdog_inode inode;
+       struct sheepdog_inode *inode = NULL;
 
+       inode = malloc(SD_INODE_HEADER_SIZE);
+       if (!inode) {
+               eprintf("oom\n");
+               vid = 0;
+               goto out;
+       }
 next:
        ret = read_object(entries, nr_vnodes, nr_zones, epoch,
-                         vid_to_vdi_oid(vid), (void *)&inode,
+                         vid_to_vdi_oid(vid), (char *)inode,
                          SD_INODE_HEADER_SIZE, 0, sys->nr_sobjs);
 
        if (ret != SD_INODE_HEADER_SIZE) {
                eprintf("cannot find vdi object\n");
-               return 0;
+               vid = 0;
+               goto out;
        }
 
-       if (!inode.parent_vdi_id)
-               return vid;
+       if (!inode->parent_vdi_id)
+               goto out;
 
-       vid = inode.parent_vdi_id;
+       vid = inode->parent_vdi_id;
 
        goto next;
+out:
+       free(inode);
+
+       return vid;
 }
 
 int start_deletion(uint32_t vid, uint32_t epoch)
-- 
1.7.2.5

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

Reply via email to