[sheepdog] [PATCH] fix a race in get_obj_list()
levin li
levin108 at gmail.com
Fri May 25 09:55:57 CEST 2012
From: levin li <xingke.lwp at taobao.com>
Reseting the object list buffer should not be locked by the
reader lock, but should be locked by a writer lock, or else
it's a race.
Signed-off-by: levin li <xingke.lwp at taobao.com>
---
sheep/object_list_cache.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/sheep/object_list_cache.c b/sheep/object_list_cache.c
index 0eb5223..110f810 100644
--- a/sheep/object_list_cache.c
+++ b/sheep/object_list_cache.c
@@ -143,22 +143,27 @@ int get_obj_list(const struct sd_list_req *hdr, struct sd_list_rsp *rsp, void *d
struct objlist_cache_entry *entry;
struct rb_node *p;
- rsp->data_length = obj_list_cache.cache_size * sizeof(uint64_t);
-
pthread_rwlock_rdlock(&obj_list_cache.lock);
- if (obj_list_cache.tree_version == obj_list_cache.buf_version)
+ rsp->data_length = obj_list_cache.cache_size * sizeof(uint64_t);
+ if (obj_list_cache.tree_version == obj_list_cache.buf_version) {
memcpy(list, obj_list_cache.buffer.buf, rsp->data_length);
- else {
+ pthread_rwlock_unlock(&obj_list_cache.lock);
+ } else {
for (p = rb_first(&obj_list_cache.root); p; p = rb_next(p)) {
entry = rb_entry(p, struct objlist_cache_entry, node);
list[nr++] = entry->oid;
}
+ pthread_rwlock_unlock(&obj_list_cache.lock);
+ pthread_rwlock_wrlock(&obj_list_cache.lock);
+ if (obj_list_cache.tree_version == obj_list_cache.buf_version)
+ goto unlock;
strbuf_reset(&obj_list_cache.buffer);
strbuf_add(&obj_list_cache.buffer, list, nr * sizeof(uint64_t));
obj_list_cache.buf_version = obj_list_cache.tree_version;
+unlock:
+ pthread_rwlock_unlock(&obj_list_cache.lock);
}
- pthread_rwlock_unlock(&obj_list_cache.lock);
return SD_RES_SUCCESS;
}
--
1.7.10
More information about the sheepdog
mailing list