[sheepdog] [PATCH 1/2] sheep/http: refactor kv_read_object()

Robin Dong robin.k.dong at gmail.com
Mon Dec 23 08:17:37 CET 2013


Reviewed-by: Robin Dong <sanbai at taobao.com>


2013/12/20 Liu Yuan <namei.unix at gmail.com>

> Also fix a API problem that return CONETENT_LENGTH for get operation
>
> Signed-off-by: Liu Yuan <namei.unix at gmail.com>
> ---
>  sheep/http/kv.c    | 210
> +++++++++++++++++++++++++----------------------------
>  sheep/http/swift.c |  12 ++-
>  2 files changed, 110 insertions(+), 112 deletions(-)
>
> diff --git a/sheep/http/kv.c b/sheep/http/kv.c
> index 0ba87a4..e5e1b6d 100644
> --- a/sheep/http/kv.c
> +++ b/sheep/http/kv.c
> @@ -29,7 +29,7 @@ struct bucket_inode_hdr {
>  struct bucket_inode {
>         union {
>                 struct bucket_inode_hdr hdr;
> -               uint8_t data[SD_MAX_BUCKET_NAME << 1];
> +               uint8_t data[BLOCK_SIZE];
>         };
>  };
>
> @@ -814,18 +814,18 @@ struct find_object_arg {
>  };
>
>  static void find_object_cb(struct http_request *req, const char *bucket,
> -                          const char *object, void *opaque)
> +                          const char *name, void *opaque)
>  {
>         struct find_object_arg *foarg = (struct find_object_arg *)opaque;
>
> -       if (!strncmp(foarg->object_name, object, SD_MAX_OBJECT_NAME))
> +       if (!strncmp(foarg->object_name, name, SD_MAX_OBJECT_NAME))
>                 foarg->found = true;
>  }
>
>  static bool kv_find_object(struct http_request *req, const char *account,
> -                          const char *bucket, const char *object)
> +                          const char *bucket, const char *name)
>  {
> -       struct find_object_arg arg = {false, object};
> +       struct find_object_arg arg = {false, name};
>         kv_list_objects(req, account, bucket, find_object_cb, &arg);
>         return arg.found;
>  }
> @@ -1059,6 +1059,82 @@ static int onode_free_data(struct kv_onode *onode)
>         return ret;
>  }
>
> +static int onode_read_extents(struct kv_onode *onode, struct http_request
> *req)
> +{
> +       struct onode_extent *ext;
> +       uint64_t size, total, total_size, offset, done = 0;
> +       uint32_t i;
> +       int ret;
> +       char *data_buf = NULL;
> +
> +       data_buf = xmalloc(READ_WRITE_BUFFER);
> +       total_size = onode->hdr.size;
> +       for (i = 0; i < onode->hdr.nr_extent; i++) {
> +               ext = onode->o_extent + i;
> +               total = min(ext->count * SD_DATA_OBJ_SIZE, total_size);
> +               offset = ext->start * SD_DATA_OBJ_SIZE;
> +               while (done < total) {
> +                       size = MIN(total - done, READ_WRITE_BUFFER);
> +                       ret = vdi_read_write(onode->hdr.data_vid, data_buf,
> +                                            size, offset, true);
> +                       if (ret != SD_RES_SUCCESS) {
> +                               sd_err("Failed to read for vid %"PRIx32,
> +                                      onode->hdr.data_vid);
> +                               goto out;
> +                       }
> +                       http_request_write(req, data_buf, size);
> +                       done += size;
> +                       offset += size;
> +                       total_size -= size;
> +               }
> +       }
> +out:
> +       free(data_buf);
> +       return ret;
> +}
> +
> +static int onode_lookup(struct kv_onode *onode, uint32_t onode_vid,
> +                       const char *name)
> +{
> +       uint64_t hval;
> +       uint32_t i;
> +       int ret;
> +
> +       sys->cdrv->lock(onode_vid);
> +       hval = sd_hash(name, strlen(name));
> +       for (i = 0; i < MAX_DATA_OBJS; i++) {
> +               uint32_t idx = (hval + i) % MAX_DATA_OBJS;
> +               uint64_t oid = vid_to_data_oid(onode_vid, idx);
> +
> +               ret = sd_read_object(oid, (char *)onode, sizeof(*onode),
> 0);
> +               if (ret != SD_RES_SUCCESS)
> +                       goto out;
> +               if (strcmp(onode->hdr.name, name) == 0)
> +                       break;
> +       }
> +
> +       if (i == MAX_DATA_OBJS)
> +               ret = SD_RES_NO_OBJ;
> +out:
> +       sys->cdrv->unlock(onode_vid);
> +       return ret;
> +
> +}
> +
> +static int onode_read_data(struct kv_onode *onode, struct http_request
> *req)
> +{
> +       int ret;
> +
> +       if (!onode->hdr.inlined)
> +               return onode_read_extents(onode, req);
> +
> +       ret = http_request_write(req, onode->data, onode->hdr.size);
> +       if (ret != onode->hdr.size)
> +               return SD_RES_SYSTEM_ERROR;
> +
> +       return SD_RES_SUCCESS;
> +}
> +
>  /*
>   * user object name -> struct kv_onode -> sheepdog objects -> user data
>   *
> @@ -1105,121 +1181,33 @@ out:
>         return ret;
>  }
>
> -static int kv_read_extent_onode(struct http_request *req,
> -                               struct kv_onode *onode)
> -{
> -       struct onode_extent *ext;
> -       uint64_t size, total, total_size, offset, done = 0;
> -       uint32_t i;
> -       int ret;
> -       char *data_buf = NULL;
> -
> -       data_buf = xmalloc(READ_WRITE_BUFFER);
> -       total_size = onode->hdr.size;
> -       for (i = 0; i < onode->hdr.nr_extent; i++) {
> -               ext = onode->o_extent + i;
> -               total = min(ext->count * SD_DATA_OBJ_SIZE, total_size);
> -               offset = ext->start * SD_DATA_OBJ_SIZE;
> -               while (done < total) {
> -                       size = MIN(total - done, READ_WRITE_BUFFER);
> -                       ret = vdi_read_write(onode->hdr.data_vid, data_buf,
> -                                            size, offset, true);
> -                       if (ret != SD_RES_SUCCESS) {
> -                               sd_err("Failed to read for vid %"PRIx32,
> -                                      onode->hdr.data_vid);
> -                               goto out;
> -                       }
> -                       http_request_write(req, data_buf, size);
> -                       done += size;
> -                       offset += size;
> -                       total_size -= size;
> -               }
> -       }
> -out:
> -       free(data_buf);
> -       return ret;
> -}
> -
> -static int do_kv_read_object(struct http_request *req, const char
> *obj_name,
> -                            struct kv_onode *onode, uint32_t vid,
> uint32_t idx)
> -{
> -       uint64_t oid = vid_to_data_oid(vid, idx);
> -       int ret;
> -
> -       ret = sd_read_object(oid, (char *)onode, sizeof(*onode), 0);
> -       switch (ret) {
> -       case SD_RES_SUCCESS:
> -               break;
> -       case SD_RES_NO_OBJ:
> -               sd_info("object %s doesn't exist", obj_name);
> -               http_response_header(req, NOT_FOUND);
> -               goto out;
> -       default:
> -               sd_err("failed to read %s, %s", req->uri,
> sd_strerror(ret));
> -               http_response_header(req, INTERNAL_SERVER_ERROR);
> -               goto out;
> -       }
> -
> -       if (strcmp(onode->hdr.name, obj_name) == 0) {
> -               http_response_header(req, OK);
> -               /* for inlined onode */
> -               if (onode->hdr.inlined)
> -                       http_request_write(req, onode->data,
> onode->hdr.size);
> -               else {
> -                       sys->cdrv->unlock(vid);
> -                       ret = kv_read_extent_onode(req, onode);
> -                       sys->cdrv->lock(vid);
> -                       if (ret != SD_RES_SUCCESS) {
> -                               sd_err("Failed to read extent onode");
> -                               goto out;
> -                       }
> -               }
> -       } else
> -               ret = SD_RES_OBJ_TAKEN;
> -out:
> -       return ret;
> -}
> -
>  int kv_read_object(struct http_request *req, const char *account,
> -                  const char *bucket, const char *object)
> +                  const char *bucket, const char *name)
>  {
>         struct kv_onode *onode = NULL;
> -       int ret, i;
> -       uint64_t hval;
> -       uint32_t vid;
>         char vdi_name[SD_MAX_VDI_LEN];
> +       uint32_t onode_vid;
> +       int ret;
>
> -       snprintf(vdi_name, SD_MAX_VDI_LEN, "%s/%s", account, bucket);
> -       ret = kv_lookup_vdi(vdi_name, &vid);
> -       if (ret < 0)
> -               goto out;
> -
> -       if (!kv_find_object(req, account, bucket, object))
> +       if (!kv_find_object(req, account, bucket, name))
>                 return SD_RES_NO_OBJ;
>
> -       onode = xzalloc(sizeof(*onode));
> -
> -       sys->cdrv->lock(vid);
> -       hval = sd_hash(object, strlen(object));
> -       for (i = 0; i < MAX_DATA_OBJS; i++) {
> -               uint32_t idx = (hval + i) % MAX_DATA_OBJS;
> +       snprintf(vdi_name, SD_MAX_VDI_LEN, "%s/%s", account, bucket);
> +       ret = kv_lookup_vdi(vdi_name, &onode_vid);
> +       if (ret != SD_RES_SUCCESS)
> +               return ret;
>
> -               ret = do_kv_read_object(req, object, onode, vid, idx);
> -               switch (ret) {
> -               case SD_RES_SUCCESS:
> -                       goto out;
> -               case SD_RES_OBJ_TAKEN:
> -                       break;
> -               default:
> -                       ret = -1;
> -                       goto out;
> -               }
> -       }
> +       onode = xzalloc(sizeof(*onode));
> +       ret = onode_lookup(onode, onode_vid, name);
> +       if (ret != SD_RES_SUCCESS)
> +               goto out;
>
> -       if (i >= MAX_DATA_OBJS)
> -               ret = -1;
> +       req->data_length = onode->hdr.size;
> +       http_response_header(req, OK);
> +       ret = onode_read_data(onode, req);
> +       if (ret != SD_RES_SUCCESS)
> +               sd_err("failed to read data for %s", name);
>  out:
> -       sys->cdrv->unlock(vid);
>         free(onode);
>         return ret;
>  }
> @@ -1346,7 +1334,7 @@ int kv_list_objects(struct http_request *req, const
> char *account,
>
>         snprintf(vdi_name, SD_MAX_VDI_LEN, "%s/%s", account, bucket);
>         ret = kv_lookup_vdi(vdi_name, &vid);
> -       if (ret < 0)
> +       if (ret != SD_RES_SUCCESS)
>                 goto out;
>
>         inode = xmalloc(sizeof(*inode));
> diff --git a/sheep/http/swift.c b/sheep/http/swift.c
> index fc25cc7..7e27acf 100644
> --- a/sheep/http/swift.c
> +++ b/sheep/http/swift.c
> @@ -178,9 +178,19 @@ static void swift_get_object(struct http_request
> *req, const char *account,
>                              const char *container, const char *object)
>  {
>         int ret;
> +
>         ret = kv_read_object(req, account, container, object);
> -       if (ret)
> +       switch (ret) {
> +       case SD_RES_SUCCESS:
> +               break;
> +       case SD_RES_NO_VDI:
> +       case SD_RES_NO_OBJ:
>                 http_response_header(req, NOT_FOUND);
> +               break;
> +       default:
> +               http_response_header(req, INTERNAL_SERVER_ERROR);
> +               break;
> +       }
>  }
>
>  static void swift_put_object(struct http_request *req, const char
> *account,
> --
> 1.8.1.2
>
> --
> sheepdog mailing list
> sheepdog at lists.wpkg.org
> http://lists.wpkg.org/mailman/listinfo/sheepdog
>



-- 
--
Best Regard
Robin Dong
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.wpkg.org/pipermail/sheepdog/attachments/20131223/6c5e492a/attachment-0004.html>


More information about the sheepdog mailing list