[Sheepdog] [PATCH 1/7] sheep: allocate memory dynamically instead of statically
MORITA Kazutaka
morita.kazutaka at lab.ntt.co.jp
Thu Aug 4 10:40:55 CEST 2011
Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
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
More information about the sheepdog
mailing list