[Sheepdog] [PATCH 2/2] collie: update object list file atomically
MORITA Kazutaka
morita.kazutaka at lab.ntt.co.jp
Wed Apr 14 07:17:45 CEST 2010
This is a temporary hack to update the object list file atomically.
FNV hash value is added to the file as an extend attribute.
Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
collie/store.c | 49 ++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 44 insertions(+), 5 deletions(-)
diff --git a/collie/store.c b/collie/store.c
index 1f17df4..72c079c 100644
--- a/collie/store.c
+++ b/collie/store.c
@@ -24,6 +24,7 @@
#define ANAME_CTIME "user.sheepdog.ctime"
#define ANAME_COPIES "user.sheepdog.copies"
#define ANAME_NODEID "user.sheepdog.nodeid"
+#define ANAME_CHECKSUM "user.sheepdog.checksum"
static char *obj_path;
static char *epoch_path;
@@ -105,6 +106,8 @@ static int get_obj_list(struct request *req, char *buf, int buf_len)
int e_nr;
int idx;
int res = SD_RES_SUCCESS;
+ uint64_t checksum = 0;
+ int ret;
if (epoch == 1)
goto local;
@@ -114,10 +117,26 @@ static int get_obj_list(struct request *req, char *buf, int buf_len)
fd = open(path, O_RDONLY);
if (fd < 0) {
eprintf("failed to open %s, %s\n", path, strerror(errno));
- close(fd);
- return SD_RES_EIO;
+ res = SD_RES_EIO;
+ goto out;
}
obj_nr = read(fd, buf, buf_len);
+
+ ret = fgetxattr(fd, ANAME_CHECKSUM, &checksum, sizeof(checksum));
+ if (ret != sizeof(checksum)) {
+ eprintf("failed to read checksum %s, %m\n", path);
+ close(fd);
+ res = SD_RES_EIO;
+ goto out;
+ }
+ if (checksum != fnv_64a_buf(buf, obj_nr, FNV1A_64_INIT)) {
+ eprintf("invalid checksum %s, %m\n", path);
+ close(fd);
+ res = SD_RES_EIO;
+ goto out;
+ }
+ dprintf("read objct list from %s, %d, %lx\n", path, obj_nr, checksum);
+
obj_nr /= sizeof(uint64_t);
objlist = (uint64_t *)buf;
for (i = 0; i < obj_nr; i++) {
@@ -140,7 +159,8 @@ local:
dir = opendir(path);
if (!dir) {
eprintf("%s\n", path);
- return SD_RES_EIO;
+ res = SD_RES_EIO;
+ goto out;
}
while ((d = readdir(dir))) {
@@ -168,7 +188,6 @@ local:
}
eprintf("nr = %d\n", nr);
- rsp->data_length = nr * sizeof(uint64_t);
e_nr = epoch_log_read(epoch, buf, buf_len);
e_nr /= sizeof(*e);
@@ -176,6 +195,7 @@ local:
if (e_nr <= sys->nr_sobjs) {
rsp->next = end_hash;
+ closedir(dir);
goto out;
}
@@ -200,9 +220,13 @@ local:
} else
res = SD_RES_SYSTEM_ERROR;
-out:
closedir(dir);
+out:
+ rsp->data_length = nr * sizeof(uint64_t);
+ for (i = 0; i < nr; i++) {
+ eprintf("oid %lx, %lx\n", *(p + i), p[i]);
+ }
return res;
}
@@ -1209,6 +1233,8 @@ static void __start_recovery(struct work *work, int idx)
int i, fd;
uint64_t start_hash, end_hash;
char path[PATH_MAX];
+ uint64_t checksum;
+ int ret;
dprintf("%u\n", epoch);
@@ -1245,6 +1271,9 @@ static void __start_recovery(struct work *work, int idx)
goto fail;
}
+ if (rw->retry)
+ goto fail;
+
snprintf(path, sizeof(path), "%s%08u/list", obj_path, epoch);
dprintf("write object list file to %s\n", path);
@@ -1254,6 +1283,16 @@ static void __start_recovery(struct work *work, int idx)
goto fail;
}
write(fd, rw->buf, sizeof(uint64_t) * rw->count);
+ fsync(fd);
+
+ checksum = fnv_64a_buf(rw->buf, sizeof(uint64_t) * rw->count, FNV1A_64_INIT);
+ ret = fsetxattr(fd, ANAME_CHECKSUM, &checksum, sizeof(checksum), 0);
+ if (ret) {
+ eprintf("couldn't set xattr to %s, %m\n", path);
+ close(fd);
+ goto fail;
+ }
+
close(fd);
return;
--
1.5.6.5
More information about the sheepdog
mailing list