[sheepdog] [PATCH v2 4/6] fix sys->epoch race
Liu Yuan
namei.unix at gmail.com
Sat May 19 17:11:23 CEST 2012
From: Liu Yuan <tailai.ly at taobao.com>
We shouldn't use sys->epoch directly in worker threads. Add a atomic helper
for it.
Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
---
sheep/farm/farm.c | 8 +++++---
sheep/farm/snap.c | 2 +-
sheep/group.c | 4 ++--
sheep/object_cache.c | 6 +++---
sheep/sheep_priv.h | 7 +++++++
5 files changed, 18 insertions(+), 9 deletions(-)
diff --git a/sheep/farm/farm.c b/sheep/farm/farm.c
index b5bfa19..f89d5fe 100644
--- a/sheep/farm/farm.c
+++ b/sheep/farm/farm.c
@@ -416,8 +416,9 @@ out:
static int farm_read(uint64_t oid, struct siocb *iocb)
{
int flags = def_open_flags, fd, ret = SD_RES_SUCCESS;
+ uint32_t epoch = sys_epoch();
- if (iocb->epoch < sys->epoch) {
+ if (iocb->epoch < epoch) {
int i;
void *buffer;
@@ -431,7 +432,7 @@ static int farm_read(uint64_t oid, struct siocb *iocb)
* in this case, we should try to retrieve object upwards, since.
* when the object is to be removed, it will get written to the
* snapshot at later epoch. */
- for (i = iocb->epoch; i < sys->epoch; i++) {
+ for (i = iocb->epoch; i < epoch; i++) {
buffer = retrieve_object_from_snap(oid, i);
if (buffer)
break;
@@ -514,10 +515,11 @@ static int farm_link(uint64_t oid, struct siocb *iocb, uint32_t tgt_epoch)
void *buf = NULL;
struct siocb io = { 0 };
int i;
+ uint32_t epoch = sys_epoch();
dprintf("try link %"PRIx64" from snapshot with epoch %d\n", oid, tgt_epoch);
- for (i = tgt_epoch; i < sys->epoch; i++) {
+ for (i = tgt_epoch; i < epoch; i++) {
buf = retrieve_object_from_snap(oid, i);
if (buf)
break;
diff --git a/sheep/farm/snap.c b/sheep/farm/snap.c
index 957ea13..3134c28 100644
--- a/sheep/farm/snap.c
+++ b/sheep/farm/snap.c
@@ -160,7 +160,7 @@ int snap_file_write(uint32_t epoch, unsigned char *trunksha1, unsigned char *out
int ret = 0;
struct strbuf buf = STRBUF_INIT;
struct sd_node nodes[SD_MAX_NODES];
- int tgt_epoch = user ? sys->epoch : epoch;
+ int tgt_epoch = user ? sys_epoch() : epoch;
uint64_t epoch_size = epoch_log_read(tgt_epoch, (char *)nodes, sizeof(nodes));
struct sha1_file_hdr hdr = { .size = epoch_size + SHA1_LEN,
.priv = tgt_epoch };
diff --git a/sheep/group.c b/sheep/group.c
index 776fa58..520ba21 100644
--- a/sheep/group.c
+++ b/sheep/group.c
@@ -670,7 +670,7 @@ static void update_cluster_info(struct join_message *msg,
if (msg->cluster_status == SD_STATUS_OK ||
msg->cluster_status == SD_STATUS_HALT) {
if (msg->inc_epoch) {
- sys->epoch++;
+ uatomic_inc(&sys->epoch);
update_epoch_log(sys->epoch, sys->nodes, sys->nr_nodes);
update_epoch_store(sys->epoch);
}
@@ -1322,7 +1322,7 @@ void sd_leave_handler(struct sd_node *left, struct sd_node *members,
update_node_info(members, nr_members);
if (sys_can_recover()) {
- sys->epoch++;
+ uatomic_inc(&sys->epoch);
update_epoch_store(sys->epoch);
update_epoch_log(sys->epoch, sys->nodes, sys->nr_nodes);
}
diff --git a/sheep/object_cache.c b/sheep/object_cache.c
index 3ca31b5..efd815f 100644
--- a/sheep/object_cache.c
+++ b/sheep/object_cache.c
@@ -435,7 +435,7 @@ int object_cache_pull(struct vnode_info *vnode_info, struct object_cache *oc,
v = vnodes[i];
if (vnode_is_local(v)) {
struct siocb iocb = { 0 };
- iocb.epoch = sys->epoch;
+ iocb.epoch = sys_epoch();
iocb.buf = buf;
iocb.length = data_length;
iocb.offset = 0;
@@ -458,7 +458,7 @@ pull_remote:
continue;
hdr.opcode = SD_OP_READ_OBJ;
- hdr.epoch = sys->epoch;
+ hdr.epoch = sys_epoch();
hdr.data_length = rlen = data_length;
hdr.flags = SD_FLAG_CMD_IO_LOCAL;
hdr.obj.oid = oid;
@@ -546,7 +546,7 @@ static int push_cache_object(struct vnode_info *vnode_info, uint32_t vid,
hdr->opcode = create ? SD_OP_CREATE_AND_WRITE_OBJ : SD_OP_WRITE_OBJ;
hdr->flags = SD_FLAG_CMD_WRITE;
hdr->data_length = data_length;
- hdr->epoch = sys->epoch;
+ hdr->epoch = sys_epoch();
hdr->obj.oid = oid;
hdr->obj.offset = 0;
diff --git a/sheep/sheep_priv.h b/sheep/sheep_priv.h
index c09918a..3aade23 100644
--- a/sheep/sheep_priv.h
+++ b/sheep/sheep_priv.h
@@ -12,6 +12,7 @@
#define __SHEEP_PRIV_H__
#include <inttypes.h>
+#include <urcu/uatomic.h>
#include "sheepdog_proto.h"
#include "event.h"
@@ -217,6 +218,12 @@ extern mode_t def_fmode;
extern mode_t def_dmode;
extern struct objlist_cache obj_list_cache;
+/* One should call this function to get sys->epoch outside main thread */
+static inline uint32_t sys_epoch(void)
+{
+ return uatomic_read(&sys->epoch);
+}
+
int create_listen_port(int port, void *data);
int init_store(const char *dir, int enable_write_cache);
--
1.7.10.2
More information about the sheepdog
mailing list