[sheepdog] [PATCH] sheep: rework get_vdis_from to reduce network overhead
Hitoshi Mitake
mitake.hitoshi at gmail.com
Sun Jul 27 10:48:02 CEST 2014
On Fri, Jul 4, 2014 at 7:30 PM, Ruoyu <liangry at ucweb.com> wrote:
> Current get_vdis_from function prepare a buffer large enough (4M)
> to get vdi state. It is not elegant and transfers too much between
> sheep nodes.
>
> Signed-off-by: Ruoyu <liangry at ucweb.com>
> ---
> sheep/group.c | 18 ++++++++++++++----
> sheep/ops.c | 4 +---
> sheep/sheep_priv.h | 3 ++-
> sheep/vdi.c | 35 ++++++++++++++++++++++++-----------
> 4 files changed, 41 insertions(+), 19 deletions(-)
Applied, thanks.
Hitoshi
>
> diff --git a/sheep/group.c b/sheep/group.c
> index adfd798..6b1ec5d 100644
> --- a/sheep/group.c
> +++ b/sheep/group.c
> @@ -471,21 +471,31 @@ static int get_vdis_from(struct sd_node *node)
> struct sd_req hdr;
> struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
> struct vdi_state *vs = NULL;
> - int i, ret = SD_RES_SUCCESS;
> + int i, ret;
> unsigned int rlen;
> int count;
>
> if (node_is_local(node))
> - goto out;
> + return SD_RES_SUCCESS;
>
> - rlen = SD_DATA_OBJ_SIZE; /* FIXME */
> +#define DEFAULT_VDI_STATE_COUNT 512
> + rlen = DEFAULT_VDI_STATE_COUNT * sizeof(struct vdi_state);
> vs = xzalloc(rlen);
> +retry:
> sd_init_req(&hdr, SD_OP_GET_VDI_COPIES);
> hdr.data_length = rlen;
> hdr.epoch = sys_epoch();
> ret = sheep_exec_req(&node->nid, &hdr, (char *)vs);
> - if (ret != SD_RES_SUCCESS)
> + switch (ret) {
> + case SD_RES_SUCCESS:
> + break;
> + case SD_RES_BUFFER_SMALL:
> + rlen *= 2;
> + vs = xrealloc(vs, rlen);
> + goto retry;
> + default:
> goto out;
> + }
>
> count = rsp->data_length / sizeof(*vs);
> for (i = 0; i < count; i++) {
> diff --git a/sheep/ops.c b/sheep/ops.c
> index fb26077..d76a0bb 100644
> --- a/sheep/ops.c
> +++ b/sheep/ops.c
> @@ -412,9 +412,7 @@ static int local_read_vdis(const struct sd_req *req, struct sd_rsp *rsp,
> static int local_get_vdi_copies(const struct sd_req *req, struct sd_rsp *rsp,
> void *data)
> {
> - rsp->data_length = fill_vdi_state_list(data);
> -
> - return SD_RES_SUCCESS;
> + return fill_vdi_state_list(req, rsp, data);
> }
>
> static int local_stat_sheep(struct request *req)
> diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
> index 02f75ad..3f25bec 100644
> --- a/sheep/sheep_priv.h
> +++ b/sheep/sheep_priv.h
> @@ -327,7 +327,8 @@ int init_base_path(const char *dir);
> int init_disk_space(const char *d);
> int lock_base_dir(const char *d);
>
> -int fill_vdi_state_list(void *data);
> +int fill_vdi_state_list(const struct sd_req *hdr,
> + struct sd_rsp *rsp, void *data);
> bool oid_is_readonly(uint64_t oid);
> int get_vdi_copy_number(uint32_t vid);
> int get_vdi_copy_policy(uint32_t vid);
> diff --git a/sheep/vdi.c b/sheep/vdi.c
> index b58b538..747c810 100644
> --- a/sheep/vdi.c
> +++ b/sheep/vdi.c
> @@ -172,25 +172,38 @@ int add_vdi_state(uint32_t vid, int nr_copies, bool snapshot, uint8_t cp)
> return SD_RES_SUCCESS;
> }
>
> -int fill_vdi_state_list(void *data)
> +int fill_vdi_state_list(const struct sd_req *hdr,
> + struct sd_rsp *rsp, void *data)
> {
> - int nr = 0;
> - struct vdi_state *vs = data;
> +#define DEFAULT_VDI_STATE_COUNT 512
> + int last = 0, end = DEFAULT_VDI_STATE_COUNT;
> struct vdi_state_entry *entry;
> + struct vdi_state *vs = xzalloc(end * sizeof(struct vdi_state));
>
> sd_read_lock(&vdi_state_lock);
> rb_for_each_entry(entry, &vdi_state_root, node) {
> - memset(vs, 0, sizeof(*vs));
> - vs->vid = entry->vid;
> - vs->nr_copies = entry->nr_copies;
> - vs->snapshot = entry->snapshot;
> - vs->copy_policy = entry->copy_policy;
> - vs++;
> - nr++;
> + if (last >= end) {
> + end *= 2;
> + vs = xrealloc(vs, end * sizeof(struct vdi_state));
> + }
> +
> + vs[last].vid = entry->vid;
> + vs[last].nr_copies = entry->nr_copies;
> + vs[last].snapshot = entry->snapshot;
> + vs[last].copy_policy = entry->copy_policy;
> + last++;
> }
> sd_rw_unlock(&vdi_state_lock);
>
> - return nr * sizeof(*vs);
> + if (hdr->data_length < last * sizeof(struct vdi_state)) {
> + free(vs);
> + return SD_RES_BUFFER_SMALL;
> + }
> +
> + rsp->data_length = last * sizeof(struct vdi_state);
> + memcpy(data, vs, rsp->data_length);
> + free(vs);
> + return SD_RES_SUCCESS;
> }
>
> static inline bool vdi_is_deleted(struct sd_inode *inode)
> --
> 1.8.3.2
>
>
> --
> sheepdog mailing list
> sheepdog at lists.wpkg.org
> http://lists.wpkg.org/mailman/listinfo/sheepdog
More information about the sheepdog
mailing list