<div dir="ltr">I think we should add check in <span style="font-family:arial,sans-serif;font-size:14px">kv_delete_bucket() because users can't delete a bucket which still contains objects.</span></div><div class="gmail_extra">
<br><br><div class="gmail_quote">2013/12/26 Liu Yuan <span dir="ltr"><<a href="mailto:namei.unix@gmail.com" target="_blank">namei.unix@gmail.com</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Signed-off-by: Liu Yuan <<a href="mailto:namei.unix@gmail.com">namei.unix@gmail.com</a>><br>
---<br>
sheep/http/http.h | 3 +-<br>
sheep/http/kv.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++----<br>
sheep/http/swift.c | 16 ++++++++++-<br>
3 files changed, 92 insertions(+), 7 deletions(-)<br>
<br>
diff --git a/sheep/http/http.h b/sheep/http/http.h<br>
index dea34e0..40ff307 100644<br>
--- a/sheep/http/http.h<br>
+++ b/sheep/http/http.h<br>
@@ -126,7 +126,8 @@ int kv_list_accounts(struct http_request *req,<br>
<br>
/* Bucket operations */<br>
int kv_create_bucket(const char *account, const char *bucket);<br>
-int kv_read_bucket(const char *account, const char *bucket);<br>
+int kv_read_bucket(struct http_request *req, const char *account,<br>
+ const char *bucket);<br>
int kv_update_bucket(const char *account, const char *bucket);<br>
int kv_delete_bucket(const char *account, const char *bucket);<br>
int kv_iterate_bucket(const char *account,<br>
diff --git a/sheep/http/kv.c b/sheep/http/kv.c<br>
index 5fde277..a58310f 100644<br>
--- a/sheep/http/kv.c<br>
+++ b/sheep/http/kv.c<br>
@@ -18,7 +18,7 @@<br>
<br>
struct kv_bnode {<br>
char name[SD_MAX_BUCKET_NAME];<br>
- uint64_t obj_count;<br>
+ uint64_t object_count;<br>
uint64_t bytes_used;<br>
uint64_t oid;<br>
};<br>
@@ -320,7 +320,7 @@ static int bucket_create(const char *account, uint32_t account_vid,<br>
<br>
pstrcpy(<a href="http://bnode.name" target="_blank">bnode.name</a>, sizeof(<a href="http://bnode.name" target="_blank">bnode.name</a>), bucket);<br>
bnode.bytes_used = 0;<br>
- bnode.obj_count = 0;<br>
+ bnode.object_count = 0;<br>
ret = bnode_create(&bnode, account_vid);<br>
if (ret != SD_RES_SUCCESS)<br>
goto err;<br>
@@ -355,6 +355,39 @@ out:<br>
return ret;<br>
}<br>
<br>
+static int bnode_update(const char *account, const char *bucket, uint64_t used,<br>
+ bool create)<br>
+{<br>
+ uint32_t account_vid;<br>
+ struct kv_bnode bnode;<br>
+ int ret;<br>
+<br>
+ ret = sd_lookup_vdi(account, &account_vid);<br>
+ if (ret != SD_RES_SUCCESS) {<br>
+ sd_err("Failed to find account %s", account);<br>
+ return ret;<br>
+ }<br>
+<br>
+ ret = bnode_lookup(&bnode, account_vid, bucket);<br>
+ if (ret != SD_RES_SUCCESS)<br>
+ return ret;<br>
+<br>
+ if (create) {<br>
+ bnode.object_count++;<br>
+ bnode.bytes_used += used;<br>
+ } else {<br>
+ bnode.object_count--;<br>
+ bnode.bytes_used -= used;<br>
+ }<br>
+<br>
+ ret = sd_write_object(bnode.oid, (char *)&bnode, sizeof(bnode), 0, 0);<br>
+ if (ret != SD_RES_SUCCESS) {<br>
+ sd_err("failed to update bnode for %s", bucket);<br>
+ return ret;<br>
+ }<br>
+ return SD_RES_SUCCESS;<br>
+}<br>
+<br>
static int bucket_delete(const char *account, uint32_t avid, const char *bucket)<br>
{<br>
struct kv_bnode bnode;<br>
@@ -470,10 +503,29 @@ out:<br>
return ret;<br>
}<br>
<br>
-int kv_read_bucket(const char *account, const char *bucket)<br>
+int kv_read_bucket(struct http_request *req, const char *account,<br>
+ const char *bucket)<br>
{<br>
- /* TODO: read metadata of the bucket */<br>
- return -1;<br>
+ uint32_t account_vid;<br>
+ struct kv_bnode bnode;<br>
+ int ret;<br>
+<br>
+ ret = sd_lookup_vdi(account, &account_vid);<br>
+ if (ret != SD_RES_SUCCESS) {<br>
+ sd_err("Failed to find account %s", account);<br>
+ return ret;<br>
+ }<br>
+<br>
+ ret = bnode_lookup(&bnode, account_vid, bucket);<br>
+ if (ret != SD_RES_SUCCESS)<br>
+ goto out;<br>
+ http_request_writef(req, "X-Container-Object-Count: %"PRIu64"\n",<br>
+ bnode.object_count);<br>
+<br>
+ http_request_writef(req, "X-Container-Bytes-Used: %"PRIu64"\n",<br>
+ bnode.bytes_used);<br>
+out:<br>
+ return ret;<br>
}<br>
<br>
int kv_update_bucket(const char *account, const char *bucket)<br>
@@ -948,6 +1000,13 @@ int kv_create_object(struct http_request *req, const char *account,<br>
if (ret != SD_RES_SUCCESS) {<br>
sd_err("failed to create onode for %s", name);<br>
onode_free_data(onode);<br>
+ goto out;<br>
+ }<br>
+<br>
+ ret = bnode_update(account, bucket, req->data_length, true);<br>
+ if (ret != SD_RES_SUCCESS) {<br>
+ ret = onode_delete(onode);<br>
+ goto out;<br>
}<br>
out:<br>
free(onode);<br>
@@ -1000,6 +1059,17 @@ int kv_delete_object(const char *account, const char *bucket, const char *name)<br>
goto out;<br>
<br>
ret = onode_delete(onode);<br>
+ if (ret != SD_RES_SUCCESS)<br>
+ goto out;<br>
+<br>
+ /*<br>
+ * If bnode is deleted successfully, we consider it successful deletion<br>
+ * even if bnode_update() fails.<br>
+ *<br>
+ * FIXME: make bnode metadata consistent<br>
+ */<br>
+ if (bnode_update(account, bucket, onode->size, false) != SD_RES_SUCCESS)<br>
+ sd_err("failed to update bnode for %s/%s", account, bucket);<br>
out:<br>
free(onode);<br>
return ret;<br>
diff --git a/sheep/http/swift.c b/sheep/http/swift.c<br>
index 01e864a..c3985be 100644<br>
--- a/sheep/http/swift.c<br>
+++ b/sheep/http/swift.c<br>
@@ -95,7 +95,21 @@ static void swift_delete_account(struct http_request *req, const char *account)<br>
static void swift_head_container(struct http_request *req, const char *account,<br>
const char *container)<br>
{<br>
- http_response_header(req, NOT_IMPLEMENTED);<br>
+ int ret;<br>
+<br>
+ ret = kv_read_bucket(req, account, container);<br>
+ switch (ret) {<br>
+ case SD_RES_SUCCESS:<br>
+ http_response_header(req, NO_CONTENT);<br>
+ break;<br>
+ case SD_RES_NO_VDI:<br>
+ case SD_RES_NO_OBJ:<br>
+ http_response_header(req, NOT_FOUND);<br>
+ break;<br>
+ default:<br>
+ http_response_header(req, INTERNAL_SERVER_ERROR);<br>
+ break;<br>
+ }<br>
}<br>
<br>
static void swift_get_container_cb(const char *object, void *opaque)<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.8.1.2<br>
<br>
--<br>
sheepdog mailing list<br>
<a href="mailto:sheepdog@lists.wpkg.org">sheepdog@lists.wpkg.org</a><br>
<a href="http://lists.wpkg.org/mailman/listinfo/sheepdog" target="_blank">http://lists.wpkg.org/mailman/listinfo/sheepdog</a><br>
</font></span></blockquote></div><br><br clear="all"><div><br></div>-- <br>--<br>Best Regard<br>Robin Dong
</div>