When object is updated at the first time from epoch is updated, collies set the extended attribute to the epoch file. This is needed to detect that cluster is broken. Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp> --- collie/collie.h | 3 ++ collie/group.c | 2 + collie/store.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 76 insertions(+), 4 deletions(-) diff --git a/collie/collie.h b/collie/collie.h index 37e9dd1..88bc8be 100644 --- a/collie/collie.h +++ b/collie/collie.h @@ -62,6 +62,7 @@ struct cluster_info { struct sheepdog_node_list_entry this_node; uint32_t epoch; + uint32_t is_object_updated; struct list_head cpg_node_list; struct list_head sd_node_list; @@ -110,6 +111,8 @@ extern struct work_queue *dobj_queue; int epoch_log_write(uint32_t epoch, char *buf, int len); int epoch_log_read(uint32_t epoch, char *buf, int len); +int set_epoch_updated(uint32_t epoch, uint32_t val); +uint32_t is_epoch_updated(uint32_t epoch); int set_cluster_ctime(uint64_t ctime); uint64_t get_cluster_ctime(void); diff --git a/collie/group.c b/collie/group.c index 9b0fde3..0de23e6 100644 --- a/collie/group.c +++ b/collie/group.c @@ -369,6 +369,7 @@ out: eprintf("can't write epoch %u\n", sys->epoch + 1); sys->epoch++; + sys->is_object_updated = 0; update_epoch_store(sys->epoch); @@ -630,6 +631,7 @@ static void __sd_confch(struct work *work, int idx) nr * sizeof(struct sheepdog_node_list_entry)); sys->epoch++; + sys->is_object_updated = 0; update_epoch_store(sys->epoch); } diff --git a/collie/store.c b/collie/store.c index 280fc4a..6bc3229 100644 --- a/collie/store.c +++ b/collie/store.c @@ -24,6 +24,7 @@ #define ANAME_LAST_OID "user.sheepdog.last_oid" #define ANAME_CTIME "user.sheepdog.ctime" #define ANAME_COPIES "user.sheepdog.copies" +#define ANAME_OBJECT_UPDATED "user.sheepdog.object_updated" static char *vdi_path; static char *obj_path; @@ -504,8 +505,17 @@ static int store_queue_request_local(struct request *req, char *buf, uint32_t ep if (ret != hdr->data_length) { ret = SD_RES_EIO; goto out; - } else - ret = SD_RES_SUCCESS; + } + + if (!sys->is_object_updated) { + ret = set_epoch_updated(epoch, 1); + if (ret) { + ret = SD_RES_EIO; + goto out; + } + } + + ret = SD_RES_SUCCESS; break; case SD_OP_SYNC_OBJ: ret = fsync(fd); @@ -843,8 +853,18 @@ void so_queue_request(struct work *work, int idx) ret = fsetxattr(fd, ANAME_COPIES, &hdr->copies, sizeof(hdr->copies), 0); - if (ret) + if (ret) { result = SD_RES_EIO; + goto out; + } + + if (!sys->is_object_updated) { + ret = set_epoch_updated(sys->epoch, 1); + if (ret) { + ret = SD_RES_EIO; + goto out; + } + } break; case SD_OP_SO_NEW_VDI: fd = open(path, O_RDONLY); @@ -956,8 +976,15 @@ void so_queue_request(struct work *work, int idx) eprintf("%lx\n", last_oid); rsp->oid = last_oid; - break; + if (!sys->is_object_updated) { + ret = set_epoch_updated(sys->epoch, 1); + if (ret) { + ret = SD_RES_EIO; + goto out; + } + } + break; case SD_OP_SO_LOOKUP_VDI: result = so_lookup_vdi(req); break; @@ -1041,6 +1068,46 @@ int epoch_log_read(uint32_t epoch, char *buf, int len) return len; } +int set_epoch_updated(uint32_t epoch, uint32_t val) +{ + int fd, ret; + char path[PATH_MAX]; + + snprintf(path, sizeof(path), "%s%08u", epoch_path, epoch); + fd = open(path, O_RDONLY); + eprintf("%s is updated\n", path); + if (fd < 0) + return -1; + + ret = fsetxattr(fd, ANAME_OBJECT_UPDATED, &val, sizeof(val), 0); + + close(fd); + + if (ret) + return -1; + return 0; +} + +uint32_t is_epoch_updated(uint32_t epoch) +{ + uint32_t val; + int fd, ret; + char path[PATH_MAX]; + + snprintf(path, sizeof(path), "%s%08u", epoch_path, epoch); + fd = open(path, O_RDONLY); + if (fd < 0) + return -1; + + ret = fgetxattr(fd, ANAME_OBJECT_UPDATED, &val, sizeof(val)); + + close(fd); + + if (ret != sizeof(val)) + return 0; + return val; +} + int set_cluster_ctime(uint64_t ctime) { int fd, ret; -- 1.5.6.5 |