[Sheepdog] [PATCH] sheep: unify create_and_write logic for cow and regular object

Liu Yuan namei.unix at gmail.com
Tue Nov 15 08:47:20 CET 2011


From: Liu Yuan <tailai.ly at taobao.com>

store_create_and_write_obj_cow() and store_create_and_write_obj() share
a lot of logic, it is neat to unify them.

 - rename read_from_other_sheep() into read_copy_from_cluster(). This is more
 descriptive.
 - use fallocate() for cow object creation too.

Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
---
 Hi Kazum, 
 this is based on the candy helper patch set. use strbuf for buf manangement.

 sheep/store.c |   96 +++++++++++++++++++-------------------------------------
 1 files changed, 33 insertions(+), 63 deletions(-)

diff --git a/sheep/store.c b/sheep/store.c
index c142bc3..cb1efd6 100644
--- a/sheep/store.c
+++ b/sheep/store.c
@@ -24,6 +24,7 @@
 #include <time.h>
 
 #include "sheep_priv.h"
+#include "strbuf.h"
 
 struct sheepdog_config {
 	uint64_t ctime;
@@ -232,8 +233,8 @@ out:
 	return ret;
 }
 
-static int read_from_other_sheep(struct request *req, uint32_t epoch,
-				  uint64_t oid, char *buf, int copies)
+static int read_copy_from_cluster(struct request *req, uint32_t epoch, uint64_t oid,
+		     char *buf, int copies)
 {
 	int ret;
 	unsigned int rlen;
@@ -671,58 +672,6 @@ static int store_write_obj(struct request *req, uint32_t epoch)
 	return ret;
 }
 
-static int store_create_and_write_obj_cow(struct request *req, uint32_t epoch)
-{
-	struct sd_obj_req *hdr = (struct sd_obj_req *)&req->rq;
-	int ret = SD_RES_SUCCESS;
-	int fd = -1;
-	char *buf = NULL;
-
-	if (!hdr->copies) {
-		eprintf("the number of copies cannot be zero\n");
-		return SD_RES_INVALID_PARMS;
-	}
-
-	fd = ob_open(epoch, hdr->oid, O_CREAT|O_TRUNC, &ret);
-	if (fd < 0)
-		return ret;
-
-	dprintf("%" PRIu64 ", %" PRIx64 "\n", hdr->oid, hdr->cow_oid);
-
-	buf = valloc(SD_DATA_OBJ_SIZE);
-	if (!buf) {
-		eprintf("failed to allocate memory\n");
-		ret = SD_RES_NO_MEM;
-		goto out;
-	}
-	ret = read_from_other_sheep(req, hdr->epoch, hdr->cow_oid, buf,
-				     hdr->copies);
-	if (ret) {
-		eprintf("failed to read old object\n");
-		ret = SD_RES_EIO;
-		goto out;
-	}
-	ret = pwrite64(fd, buf, SD_DATA_OBJ_SIZE, 0);
-	if (ret != SD_DATA_OBJ_SIZE) {
-		if (errno == ENOSPC)
-			ret = SD_RES_NO_SPACE;
-		else {
-			eprintf("%m\n");
-			ret = SD_RES_EIO;
-		}
-		goto out;
-	}
-	free(buf);
-	buf = NULL;
-
-	ret = store_write_obj_fd(fd, req, epoch);
-out:
-	if (buf)
-		free(buf);
-	close(fd);
-	return ret;
-}
-
 static int store_write_last_sector(int fd)
 {
 	const int size = SECTOR_SIZE;
@@ -749,21 +698,25 @@ static int store_write_last_sector(int fd)
 	return SD_RES_SUCCESS;
 }
 
+
 static int store_create_and_write_obj(struct request *req, uint32_t epoch)
 {
 	struct sd_obj_req *hdr = (struct sd_obj_req *)&req->rq;
-	int ret = SD_RES_SUCCESS;
-	int fd = -1;
+	int ret;
+	int fd;
+	struct strbuf buf;
+
+	dprintf("%" PRIu64 ", %" PRIx64 "\n", hdr->oid, hdr->cow_oid);
 
 	if (!hdr->copies) {
 		eprintf("the number of copies cannot be zero\n");
 		return SD_RES_INVALID_PARMS;
 	}
 
+	strbuf_init(&buf, SD_DATA_OBJ_SIZE);
 	fd = ob_open(epoch, hdr->oid, O_CREAT|O_TRUNC, &ret);
 	if (fd < 0)
-		return ret;
-
+		goto out_open;
 	/*
 	 * Preallocate the whole object to get a better filesystem layout.
 	 */
@@ -776,10 +729,30 @@ static int store_create_and_write_obj(struct request *req, uint32_t epoch)
 
 		ret = store_write_last_sector(fd);
 	}
-
+	if (hdr->flags & SD_FLAG_CMD_COW) {
+		ret = read_copy_from_cluster(req, hdr->epoch, hdr->cow_oid, buf.buf,
+				hdr->copies);
+		if (ret) {
+			eprintf("failed to read old object\n");
+			ret = SD_RES_EIO;
+			goto out;
+		}
+		ret = pwrite64(fd, buf.buf, SD_DATA_OBJ_SIZE, 0);
+		if (ret != SD_DATA_OBJ_SIZE) {
+			if (errno == ENOSPC)
+				ret = SD_RES_NO_SPACE;
+			else {
+				eprintf("%m\n");
+				ret = SD_RES_EIO;
+			}
+			goto out;
+		}
+	}
 	ret = store_write_obj_fd(fd, req, epoch);
 out:
 	close(fd);
+out_open:
+	strbuf_release(&buf);
 	return ret;
 }
 
@@ -801,10 +774,7 @@ static int store_queue_request_local(struct request *req, uint32_t epoch)
 		ret = store_read_obj(req, epoch);
 		break;
 	case SD_OP_CREATE_AND_WRITE_OBJ:
-		if (hdr->flags & SD_FLAG_CMD_COW)
-			ret = store_create_and_write_obj_cow(req, epoch);
-		else
-			ret = store_create_and_write_obj(req, epoch);
+		ret = store_create_and_write_obj(req, epoch);
 		break;
 	}
 
-- 
1.7.6.1




More information about the sheepdog mailing list