[sheepdog] [PATCH 1/2] sheep/http: implement HEAD operation for bucket

Liu Yuan namei.unix at gmail.com
Wed Dec 25 10:06:29 CET 2013


Signed-off-by: Liu Yuan <namei.unix at gmail.com>
---
 sheep/http/http.h  |  3 ++-
 sheep/http/kv.c    | 62 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 sheep/http/swift.c | 16 +++++++++++++-
 3 files changed, 74 insertions(+), 7 deletions(-)

diff --git a/sheep/http/http.h b/sheep/http/http.h
index dea34e0..40ff307 100644
--- a/sheep/http/http.h
+++ b/sheep/http/http.h
@@ -126,7 +126,8 @@ int kv_list_accounts(struct http_request *req,
 
 /* Bucket operations */
 int kv_create_bucket(const char *account, const char *bucket);
-int kv_read_bucket(const char *account, const char *bucket);
+int kv_read_bucket(struct http_request *req, const char *account,
+		   const char *bucket);
 int kv_update_bucket(const char *account, const char *bucket);
 int kv_delete_bucket(const char *account, const char *bucket);
 int kv_iterate_bucket(const char *account,
diff --git a/sheep/http/kv.c b/sheep/http/kv.c
index 5fde277..7f681f0 100644
--- a/sheep/http/kv.c
+++ b/sheep/http/kv.c
@@ -18,7 +18,7 @@
 
 struct kv_bnode {
 	char name[SD_MAX_BUCKET_NAME];
-	uint64_t obj_count;
+	uint64_t object_count;
 	uint64_t bytes_used;
 	uint64_t oid;
 };
@@ -320,7 +320,7 @@ static int bucket_create(const char *account, uint32_t account_vid,
 
 	pstrcpy(bnode.name, sizeof(bnode.name), bucket);
 	bnode.bytes_used = 0;
-	bnode.obj_count = 0;
+	bnode.object_count = 0;
 	ret = bnode_create(&bnode, account_vid);
 	if (ret != SD_RES_SUCCESS)
 		goto err;
@@ -355,6 +355,32 @@ out:
 	return ret;
 }
 
+static int bnode_update(const char *account, const char *bucket, uint64_t used)
+{
+	uint32_t account_vid;
+	struct kv_bnode bnode;
+	int ret;
+
+	ret = sd_lookup_vdi(account, &account_vid);
+	if (ret != SD_RES_SUCCESS) {
+		sd_err("Failed to find account %s", account);
+		return ret;
+	}
+
+	ret = bnode_lookup(&bnode, account_vid, bucket);
+	if (ret != SD_RES_SUCCESS)
+		return ret;
+
+	bnode.object_count++;
+	bnode.bytes_used += used;
+	ret = sd_write_object(bnode.oid, (char *)&bnode, sizeof(bnode), 0, 0);
+	if (ret != SD_RES_SUCCESS) {
+		sd_err("failed to update bnode for %s", bucket);
+		return ret;
+	}
+	return SD_RES_SUCCESS;
+}
+
 static int bucket_delete(const char *account, uint32_t avid, const char *bucket)
 {
 	struct kv_bnode bnode;
@@ -470,10 +496,29 @@ out:
 	return ret;
 }
 
-int kv_read_bucket(const char *account, const char *bucket)
+int kv_read_bucket(struct http_request *req, const char *account,
+		   const char *bucket)
 {
-	/* TODO: read metadata of the bucket */
-	return -1;
+	uint32_t account_vid;
+	struct kv_bnode bnode;
+	int ret;
+
+	ret = sd_lookup_vdi(account, &account_vid);
+	if (ret != SD_RES_SUCCESS) {
+		sd_err("Failed to find account %s", account);
+		return ret;
+	}
+
+	ret = bnode_lookup(&bnode, account_vid, bucket);
+	if (ret != SD_RES_SUCCESS)
+		goto out;
+	http_request_writef(req, "X-Container-Object-Count: %"PRIu64"\n",
+			    bnode.object_count);
+
+	http_request_writef(req, "X-Container-Bytes-Used: %"PRIu64"\n",
+			    bnode.bytes_used);
+out:
+	return ret;
 }
 
 int kv_update_bucket(const char *account, const char *bucket)
@@ -948,6 +993,13 @@ int kv_create_object(struct http_request *req, const char *account,
 	if (ret != SD_RES_SUCCESS) {
 		sd_err("failed to create onode for %s", name);
 		onode_free_data(onode);
+		goto out;
+	}
+
+	ret = bnode_update(account, bucket, req->data_length);
+	if (ret != SD_RES_SUCCESS) {
+		ret = onode_delete(onode);
+		goto out;
 	}
 out:
 	free(onode);
diff --git a/sheep/http/swift.c b/sheep/http/swift.c
index 01e864a..c3985be 100644
--- a/sheep/http/swift.c
+++ b/sheep/http/swift.c
@@ -95,7 +95,21 @@ static void swift_delete_account(struct http_request *req, const char *account)
 static void swift_head_container(struct http_request *req, const char *account,
 				 const char *container)
 {
-	http_response_header(req, NOT_IMPLEMENTED);
+	int ret;
+
+	ret = kv_read_bucket(req, account, container);
+	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;
+	default:
+		http_response_header(req, INTERNAL_SERVER_ERROR);
+		break;
+	}
 }
 
 static void swift_get_container_cb(const char *object, void *opaque)
-- 
1.8.1.2




More information about the sheepdog mailing list