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 |