At Fri, 22 Aug 2014 13:32:42 +0900,
Hitoshi Mitake wrote:
> 
> The recent new GC algorithm requires mutual exclusion between inode
> update and and snapshot creation. This patch let sheeps prevent inode
> update requests during snapshot creation with VDI locking information.
> 
> Signed-off-by: Hitoshi Mitake <mitake.hito...@lab.ntt.co.jp>
> ---
>  dog/vdi.c | 131 
> +++++++++++++++++++++++++++++++++++++++++++-------------------
>  1 file changed, 91 insertions(+), 40 deletions(-)

Applied.

Thanks,
Hitoshi

> 
> diff --git a/dog/vdi.c b/dog/vdi.c
> index cd85b65..19da73e 100644
> --- a/dog/vdi.c
> +++ b/dog/vdi.c
> @@ -517,6 +517,47 @@ out:
>       return ret;
>  }
>  
> +static struct vdi_state *get_vdi_state(int *count)
> +{
> +     int ret;
> +     struct sd_req hdr;
> +     struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
> +     struct vdi_state *vs = NULL;
> +     unsigned int rlen;
> +
> +#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;
> +
> +     ret = dog_exec_req(&sd_nid, &hdr, (char *)vs);
> +     if (ret < 0)
> +             goto fail;
> +
> +     switch (ret) {
> +     case SD_RES_SUCCESS:
> +             break;
> +     case SD_RES_BUFFER_SMALL:
> +             rlen *= 2;
> +             vs = xrealloc(vs, rlen);
> +             goto retry;
> +     default:
> +             sd_err("failed to execute SD_OP_GET_VDI_COPIES: %s",
> +                    sd_strerror(ret));
> +             goto fail;
> +     }
> +
> +     *count = rsp->data_length / sizeof(*vs);
> +     return vs;
> +
> +fail:
> +     free(vs);
> +     vs = NULL;
> +     return NULL;
> +}
> +
>  static int vdi_snapshot(int argc, char **argv)
>  {
>       const char *vdiname = argv[optind++];
> @@ -525,6 +566,10 @@ static int vdi_snapshot(int argc, char **argv)
>       char buf[SD_INODE_HEADER_SIZE];
>       struct sd_inode *inode = (struct sd_inode *)buf;
>       struct sd_req hdr;
> +     struct vdi_state *vs = NULL;
> +     int vs_count = 0;
> +     struct node_id owners[SD_MAX_COPIES];
> +     int nr_owners = 0, nr_issued_prevent_inode_update = 0;
>  
>       if (vdi_cmd_data.snapshot_id != 0) {
>               sd_err("Please specify a non-integer value for "
> @@ -541,11 +586,43 @@ static int vdi_snapshot(int argc, char **argv)
>               return EXIT_FAILURE;
>       }
>  
> -     sd_init_req(&hdr, SD_OP_PREVENT_INODE_UPDATE);
> -     ret = dog_exec_req(&sd_nid, &hdr, NULL);
> -     if (ret < 0) {
> -             sd_err("preventing inode update failed");
> +     vs = get_vdi_state(&vs_count);
> +     if (!vs)
>               return EXIT_FAILURE;
> +
> +     for (int i = 0; i < vs_count; i++) {
> +             struct vdi_state *s = &vs[i];
> +
> +             if (s->vid != vid)
> +                     continue;
> +
> +             if (s->lock_state == LOCK_STATE_LOCKED) {
> +                     /* QEMU is using it */
> +                     memset(&owners[0], 0, sizeof(owners[0]));
> +                     memcpy(&owners[0], &s->lock_owner, sizeof(owners[0]));
> +                     nr_owners = 1;
> +             } else {
> +                     /* tgt is using it */
> +                     for (int j = 0; j < s->nr_participants; i++) {
> +                             memset(&owners[nr_owners], 0,
> +                                    sizeof(owners[nr_owners]));
> +                             memcpy(&owners[nr_owners],
> +                                    &s->participants[nr_owners],
> +                                    sizeof(owners[nr_owners]));
> +                             nr_owners++;
> +                     }
> +             }
> +     }
> +
> +     for (int i = 0; i < nr_owners; i++) {
> +             sd_init_req(&hdr, SD_OP_PREVENT_INODE_UPDATE);
> +             ret = dog_exec_req(&owners[i], &hdr, NULL);
> +             if (ret < 0) {
> +                     sd_err("preventing inode update failed");
> +                     goto out;
> +             }
> +
> +             nr_issued_prevent_inode_update++;
>       }
>  
>       ret = dog_write_object(vid_to_vdi_oid(vid), 0,
> @@ -555,7 +632,7 @@ static int vdi_snapshot(int argc, char **argv)
>                              0, inode->nr_copies, inode->copy_policy,
>                              false, false);
>       if (ret != SD_RES_SUCCESS)
> -             return EXIT_FAILURE;
> +             goto out;
>  
>       ret = do_vdi_create(vdiname, inode->vdi_size, vid, &new_vid, true,
>                           inode->nr_copies, inode->copy_policy,
> @@ -569,11 +646,12 @@ static int vdi_snapshot(int argc, char **argv)
>                              " VDI ID of newly created snapshot: %x\n", 
> new_vid, vid);
>       }
>  
> -     sd_init_req(&hdr, SD_OP_ALLOW_INODE_UPDATE);
> -     ret = dog_exec_req(&sd_nid, &hdr, NULL);
> -     if (ret < 0) {
> -             sd_err("allowing inode update failed");
> -             return EXIT_FAILURE;
> +out:
> +     for (int i = 0; i < nr_issued_prevent_inode_update; i++) {
> +             sd_init_req(&hdr, SD_OP_ALLOW_INODE_UPDATE);
> +             ret = dog_exec_req(&owners[i], &hdr, NULL);
> +             if (ret < 0)
> +                     sd_err("allowing inode update failed");
>       }
>  
>       return ret;
> @@ -2716,41 +2794,14 @@ static int vdi_alter_copy(int argc, char **argv)
>  
>  static int lock_list(int argc, char **argv)
>  {
> -     struct sd_req hdr;
> -     struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
>       struct vdi_state *vs = NULL;
> -     unsigned int rlen;
> -     int ret, count;
> +     int ret = 0, count = 0;
>  
> -#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;
> -
> -     ret = dog_exec_req(&sd_nid, &hdr, (char *)vs);
> -     if (ret < 0)
> -             return EXIT_SYSFAIL;
> -
> -     switch (ret) {
> -     case SD_RES_SUCCESS:
> -             break;
> -     case SD_RES_BUFFER_SMALL:
> -             rlen *= 2;
> -             vs = xrealloc(vs, rlen);
> -             goto retry;
> -     default:
> -             sd_err("failed to execute SD_OP_GET_VDI_COPIES: %s",
> -                    sd_strerror(ret));
> -             goto out;
> -     }
> +     vs = get_vdi_state(&count);
>  
>       init_tree();
>       if (parse_vdi(construct_vdi_tree, SD_INODE_HEADER_SIZE, NULL) < 0)
> -             return EXIT_SYSFAIL;
> -
> -     count = rsp->data_length / sizeof(*vs);
> +             goto out;
>  
>       printf("VDI | owner node\n");
>       for (int i = 0; i < count; i++) {
> -- 
> 1.8.3.2
> 
-- 
sheepdog mailing list
sheepdog@lists.wpkg.org
http://lists.wpkg.org/mailman/listinfo/sheepdog

Reply via email to