[sheepdog] [PATCH v2 3/3] sheep/http: refacotor kv_{read, delete}_account
Liu Yuan
namei.unix at gmail.com
Thu Dec 26 04:41:01 CET 2013
Also fixes swift_get{account, container} when target doesn't exist.
Signed-off-by: Liu Yuan <namei.unix at gmail.com>
---
include/internal_proto.h | 2 +-
sheep/http/http.h | 4 +--
sheep/http/kv.c | 55 ++++++++++++++++++++++-----------
sheep/http/swift.c | 80 +++++++++++++++++++++++++++++-------------------
4 files changed, 88 insertions(+), 53 deletions(-)
diff --git a/include/internal_proto.h b/include/internal_proto.h
index ac4e3f8..2aefb2d 100644
--- a/include/internal_proto.h
+++ b/include/internal_proto.h
@@ -124,7 +124,7 @@
#define SD_RES_AGAIN 0x8F /* Ask to try again */
#define SD_RES_STALE_OBJ 0x90 /* Object may be stale */
#define SD_RES_CLUSTER_ERROR 0x91 /* Cluster driver error */
-#define SD_RES_OBJ_TAKEN 0x92 /* Object ID is taken up */
+#define SD_RES_VDI_NOT_EMPTY 0x92 /* VDI is not empty */
#define SD_CLUSTER_FLAG_STRICT 0x0001 /* Strict mode for write */
diff --git a/sheep/http/http.h b/sheep/http/http.h
index 52f5b36..493e10f 100644
--- a/sheep/http/http.h
+++ b/sheep/http/http.h
@@ -116,9 +116,9 @@ int http_request_writef(struct http_request *req, const char *fmt, ...);
/* Account operations */
int kv_create_account(const char *account);
-int kv_read_account(const char *account, uint32_t *nr_buckets);
+int kv_read_account_meta(struct http_request *req, const char *account);
int kv_update_account(const char *account);
-int kv_delete_account(const char *account);
+int kv_delete_account(struct http_request *req, const char *account);
int kv_list_accounts(struct http_request *req,
void (*cb)(struct http_request *req, const char *account,
void *opaque),
diff --git a/sheep/http/kv.c b/sheep/http/kv.c
index 408ea7f..7a2f433 100644
--- a/sheep/http/kv.c
+++ b/sheep/http/kv.c
@@ -55,7 +55,9 @@ typedef void (*bucket_iter_cb)(const char *bucket, void *opaque);
struct bucket_iterater_arg {
void *opaque;
bucket_iter_cb cb;
- uint32_t count;
+ uint64_t bucket_count;
+ uint64_t object_count;
+ uint64_t bytes_used;
};
static int kv_create_hyper_volume(const char *name, uint32_t *vdi_id)
@@ -139,45 +141,55 @@ static void bucket_iterater(void *data, enum btree_node_type type, void *arg)
return;
if (biarg->cb)
biarg->cb(bnode.name, biarg->opaque);
- biarg->count++;
+ biarg->bucket_count++;
+ biarg->object_count += bnode.object_count;
+ biarg->bytes_used += bnode.bytes_used;
}
}
-/* get number of buckets in this account */
-static int kv_get_account(const char *account, uint32_t *nr_buckets)
+static int read_account_meta(const char *account, uint64_t *bucket_count,
+ uint64_t *object_count, uint64_t *used)
{
- struct sd_inode inode;
- uint64_t oid;
+ struct sd_inode *inode = NULL;
+ struct bucket_iterater_arg arg = {};
uint32_t account_vid;
- struct bucket_iterater_arg arg = {NULL, NULL, 0};
+ uint64_t oid;
int ret;
ret = sd_lookup_vdi(account, &account_vid);
if (ret != SD_RES_SUCCESS)
goto out;
- /* read account vdi out */
oid = vid_to_vdi_oid(account_vid);
- ret = sd_read_object(oid, (char *)&inode, sizeof(struct sd_inode), 0);
+ inode = xmalloc(sizeof(*inode));
+ ret = sd_read_object(oid, (char *)inode, sizeof(struct sd_inode), 0);
if (ret != SD_RES_SUCCESS) {
sd_err("Failed to read inode header %lx", oid);
goto out;
}
- traverse_btree(sheep_bnode_reader, &inode, bucket_iterater, &arg);
- if (nr_buckets)
- *nr_buckets = arg.count;
+ traverse_btree(sheep_bnode_reader, inode, bucket_iterater, &arg);
+ *object_count = arg.object_count;
+ *bucket_count = arg.bucket_count;
+ *used = arg.bytes_used;
out:
+ free(inode);
return ret;
}
-int kv_read_account(const char *account, uint32_t *nr_buckets)
+int kv_read_account_meta(struct http_request *req, const char *account)
{
+ uint64_t bcount, ocount, used;
int ret;
- ret = kv_get_account(account, nr_buckets);
+ ret = read_account_meta(account, &bcount, &ocount, &used);
if (ret != SD_RES_SUCCESS)
- sd_err("Failed to get number of buckets in %s", account);
+ return ret;
+
+ http_request_writef(req, "X-Account-Container-Count: %"PRIu64"\n",
+ bcount);
+ http_request_writef(req, "X-Account-Object-Count: %"PRIu64"\n", ocount);
+ http_request_writef(req, "X-Account-Bytes-Used: %"PRIu64"\n", used);
return ret;
}
@@ -187,14 +199,21 @@ int kv_update_account(const char *account)
return -1;
}
-int kv_delete_account(const char *account)
+int kv_delete_account(struct http_request *req, const char *account)
{
+ uint64_t bcount, ocount, used;
int ret;
+ ret = read_account_meta(account, &bcount, &ocount, &used);
+ if (ret != SD_RES_SUCCESS)
+ return ret;
+
+ if (bcount)
+ return SD_RES_VDI_NOT_EMPTY;
+
ret = sd_delete_vdi(account);
if (ret != SD_RES_SUCCESS)
sd_err("Failed to delete vdi %s", account);
-
return ret;
}
@@ -561,7 +580,7 @@ out:
int kv_iterate_bucket(const char *account, bucket_iter_cb cb, void *opaque)
{
struct sd_inode account_inode;
- struct bucket_iterater_arg arg = {opaque, cb, 0};
+ struct bucket_iterater_arg arg = {opaque, cb, 0, 0, 0};
uint32_t account_vid;
uint64_t oid;
int ret;
diff --git a/sheep/http/swift.c b/sheep/http/swift.c
index a2b2e89..1655f9e 100644
--- a/sheep/http/swift.c
+++ b/sheep/http/swift.c
@@ -16,17 +16,13 @@
static void swift_head_account(struct http_request *req, const char *account)
{
- uint32_t nr_buckets;
int ret;
- ret = kv_read_account(account, &nr_buckets);
- if (ret)
- http_response_header(req, UNAUTHORIZED);
- else {
- http_request_writef(req, "X-Account-Container-Count: %u\n",
- nr_buckets);
+ ret = kv_read_account_meta(req, account);
+ if (ret == SD_RES_SUCCESS)
http_response_header(req, NO_CONTENT);
- }
+ else
+ http_response_header(req, UNAUTHORIZED);
}
static void swift_get_account_cb(const char *bucket, void *opaque)
@@ -39,11 +35,22 @@ static void swift_get_account_cb(const char *bucket, void *opaque)
static void swift_get_account(struct http_request *req, const char *account)
{
struct strbuf buf = STRBUF_INIT;
+ int ret;
- kv_iterate_bucket(account, swift_get_account_cb, &buf);
- req->data_length = buf.len;
- http_response_header(req, OK);
- http_request_write(req, buf.buf, buf.len);
+ ret = kv_iterate_bucket(account, swift_get_account_cb, &buf);
+ switch (ret) {
+ case SD_RES_SUCCESS:
+ req->data_length = buf.len;
+ http_response_header(req, OK);
+ http_request_write(req, buf.buf, buf.len);
+ break;
+ case SD_RES_NO_VDI:
+ http_response_header(req, NOT_FOUND);
+ break;
+ default:
+ http_response_header(req, INTERNAL_SERVER_ERROR);
+ break;
+ }
strbuf_release(&buf);
}
@@ -67,27 +74,24 @@ static void swift_post_account(struct http_request *req, const char *account)
static void swift_delete_account(struct http_request *req, const char *account)
{
- uint32_t nr_buckets;
int ret;
- ret = kv_read_account(account, &nr_buckets);
- if (ret) {
- http_response_header(req, INTERNAL_SERVER_ERROR);
- return;
- }
-
- if (nr_buckets) {
- /* return HTTP_CONFLICT when the account is not empty */
+ ret = kv_delete_account(req, account);
+ switch (ret) {
+ case SD_RES_SUCCESS:
+ http_response_header(req, NO_CONTENT);
+ break;
+ case SD_RES_NO_VDI:
+ case SD_RES_NO_OBJ:
+ http_response_header(req, NOT_FOUND);
+ break;
+ case SD_RES_VDI_NOT_EMPTY:
http_response_header(req, CONFLICT);
- return;
- }
-
- ret = kv_delete_account(account);
- if (ret) {
+ break;
+ default:
http_response_header(req, INTERNAL_SERVER_ERROR);
- return;
+ break;
}
- http_response_header(req, OK);
}
/* Operations on Containers */
@@ -123,11 +127,23 @@ static void swift_get_container(struct http_request *req, const char *account,
const char *container)
{
struct strbuf buf = STRBUF_INIT;
+ int ret;
- kv_iterate_object(account, container, swift_get_container_cb, &buf);
- req->data_length = buf.len;
- http_response_header(req, OK);
- http_request_write(req, buf.buf, buf.len);
+ ret = kv_iterate_object(account, container, swift_get_container_cb,
+ &buf);
+ switch (ret) {
+ case SD_RES_SUCCESS:
+ req->data_length = buf.len;
+ http_response_header(req, OK);
+ http_request_write(req, buf.buf, buf.len);
+ break;
+ case SD_RES_NO_VDI:
+ http_response_header(req, NOT_FOUND);
+ break;
+ default:
+ http_response_header(req, INTERNAL_SERVER_ERROR);
+ break;
+ }
strbuf_release(&buf);
}
--
1.8.1.2
More information about the sheepdog
mailing list