[sheepdog] [PATCH 1/2] sheep/http: refactor kv_read_object()
Liu Yuan
namei.unix at gmail.com
Fri Dec 20 16:30:02 CET 2013
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
More information about the sheepdog
mailing list