[Sheepdog] [PATCH] store, simple: refactor open function
Liu Yuan
namei.unix at gmail.com
Fri Jan 20 09:15:03 CET 2012
From: Liu Yuan <tailai.ly at taobao.com>
This is necessary when adding tracer to sheep. After the refactoring,
the tracer works fine as expected. Without, there will be a segfault.
---
Hi Kazum,
I think now tracer would works well on your box. I have tested it on debian squeeze.
sheep/simple_store.c | 105 +++++++++++++++++++++++++++-----------------------
1 files changed, 57 insertions(+), 48 deletions(-)
diff --git a/sheep/simple_store.c b/sheep/simple_store.c
index 3597926..3698e47 100644
--- a/sheep/simple_store.c
+++ b/sheep/simple_store.c
@@ -79,11 +79,12 @@ static int simple_store_init(char *path)
return SD_RES_SUCCESS;
}
-static int store_write_last_sector(uint64_t oid, struct siocb *iocb)
+static int write_last_sector(int fd)
{
const int size = SECTOR_SIZE;
- char *buf = NULL;
+ char *buf;
int ret;
+ off_t off = SD_DATA_OBJ_SIZE - size;
buf = valloc(size);
if (!buf) {
@@ -92,19 +93,56 @@ static int store_write_last_sector(uint64_t oid, struct siocb *iocb)
}
memset(buf, 0, size);
- iocb->buf = buf;
- iocb->length = size;
- iocb->offset = SD_DATA_OBJ_SIZE - size;
- ret = store.write(oid, iocb);
+ ret = xpwrite(fd, buf, size, off);
+ if (ret != size)
+ ret = SD_RES_EIO;
+ else
+ ret = SD_RES_SUCCESS;
free(buf);
return ret;
}
-static int simple_store_open(uint64_t oid, struct siocb *iocb, int create)
+static int err_to_sderr(uint64_t oid, int err)
{
- struct strbuf path = STRBUF_INIT;
int ret;
+ if (err == ENOENT) {
+ struct stat s;
+
+ if (stat(obj_path, &s) < 0) {
+ eprintf("corrupted\n");
+ ret = SD_RES_EIO;
+ } else {
+ dprintf("object %016" PRIx64 " not found locally\n", oid);
+ ret = SD_RES_NO_OBJ;
+ }
+ } else {
+ eprintf("%m\n");
+ ret = SD_RES_UNKNOWN;
+ }
+ return ret;
+}
+
+/*
+ * Preallocate the whole object to get a better filesystem layout.
+ */
+static int prealloc(int fd)
+{
+ int ret = fallocate(fd, 0, 0, SD_DATA_OBJ_SIZE);
+ if (ret < 0) {
+ if (errno != ENOSYS && errno != EOPNOTSUPP)
+ ret = SD_RES_SYSTEM_ERROR;
+ else
+ ret = write_last_sector(fd);
+ } else
+ ret = SD_RES_SUCCESS;
+ return ret;
+}
+
+static int simple_store_open(uint64_t oid, struct siocb *iocb, int create)
+{
+ struct strbuf buf = STRBUF_INIT;
+ int ret = SD_RES_SUCCESS, fd;
int flags = def_store_flags;
if (sys->use_directio && is_data_obj(oid))
@@ -113,51 +151,22 @@ static int simple_store_open(uint64_t oid, struct siocb *iocb, int create)
if (create)
flags |= O_CREAT | O_TRUNC;
- strbuf_addf(&path, "%s%08u/%016" PRIx64, obj_path, iocb->epoch, oid);
-
- ret = open(path.buf, flags, def_fmode);
- if (ret < 0) {
- if (errno == ENOENT) {
- struct stat s;
-
- if (stat(obj_path, &s) < 0) {
- eprintf("store directory corrupted: %m\n");
- ret = SD_RES_EIO;
- } else {
- dprintf("object %08u/%016" PRIx64 " not found locally\n", iocb->epoch, oid);
- ret = SD_RES_NO_OBJ;
- }
- } else {
- eprintf("failed to open %s: %m\n", path.buf);
- ret = SD_RES_UNKNOWN;
- }
+ strbuf_addstr(&buf, obj_path);
+ strbuf_addf(&buf, "%08u/%016" PRIx64, iocb->epoch, oid);
+ fd = open(buf.buf, flags, def_fmode);
+ if (fd < 0) {
+ ret = err_to_sderr(oid, errno);
goto out;
}
-
- iocb->fd = ret;
+ iocb->fd = fd;
+ ret = SD_RES_SUCCESS;
if (!(iocb->flags & SD_FLAG_CMD_COW) && create) {
- /*
- * Preallocate the whole object to get a better filesystem layout.
- */
- ret = fallocate(iocb->fd, 0, 0, SD_DATA_OBJ_SIZE);
- if (ret < 0) {
- if (errno != ENOSYS && errno != EOPNOTSUPP) {
- ret = SD_RES_EIO;
- close(iocb->fd);
- goto out;
- }
-
- ret = store_write_last_sector(oid, iocb);
- if (ret) {
- close(iocb->fd);
- goto out;
- }
- }
+ ret = prealloc(fd);
+ if (ret != SD_RES_SUCCESS)
+ close(fd);
}
-
- ret = SD_RES_SUCCESS;
out:
- strbuf_release(&path);
+ strbuf_release(&buf);
return ret;
}
--
1.7.2.5
More information about the sheepdog
mailing list