summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnand Avati <avati@gluster.com>2011-12-08 11:08:48 +0530
committerAnand Avati <avati@gluster.com>2012-01-11 00:18:22 -0800
commit1020a3dfe9834468be96040633369d69dc9aeef3 (patch)
treefdfbbeb7e647061f68ec537c5227a1c32b91fe55
parent50d6112ed3aecdcb003c72f68daf105b10d5a153 (diff)
core/stack: perform locked windsv3.2.6qa1
In configurations like pump, where there is a cluster translator on top of io-threads, there are situations where two concurrent stack-winds can be performed on the same call stack in multiple threads. This patch holds locks during the call frame list manipulation Change-Id: I51539210dc8101f7a80cf9bc103b5eff0c86dc9f BUG: 765522 Reviewed-on: http://review.gluster.com/2629 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Anand Avati <avati@gluster.com>
-rw-r--r--libglusterfs/src/stack.h51
1 files changed, 35 insertions, 16 deletions
diff --git a/libglusterfs/src/stack.h b/libglusterfs/src/stack.h
index d867a4d..d6ba707 100644
--- a/libglusterfs/src/stack.h
+++ b/libglusterfs/src/stack.h
@@ -99,6 +99,7 @@ struct _call_stack_t {
};
};
call_pool_t *pool;
+ gf_lock_t stack_lock;
void *trans;
uint64_t unique;
void *state; /* pointer to request state */
@@ -218,20 +219,24 @@ STACK_DESTROY (call_stack_t *stack)
} \
typeof(fn##_cbk) tmp_cbk = rfn; \
_new->root = frame->root; \
- _new->next = frame->root->frames.next; \
- _new->prev = &frame->root->frames; \
- if (frame->root->frames.next) \
- frame->root->frames.next->prev = _new; \
- frame->root->frames.next = _new; \
_new->this = obj; \
_new->ret = (ret_fn_t) tmp_cbk; \
_new->parent = frame; \
_new->cookie = _new; \
- LOCK_INIT (&_new->lock); \
_new->wind_from = __FUNCTION__; \
_new->wind_to = #fn; \
_new->unwind_to = #rfn; \
- frame->ref_count++; \
+ LOCK_INIT (&_new->lock); \
+ LOCK(&frame->root->stack_lock); \
+ { \
+ _new->next = frame->root->frames.next; \
+ _new->prev = &frame->root->frames; \
+ if (frame->root->frames.next) \
+ frame->root->frames.next->prev = _new; \
+ frame->root->frames.next = _new; \
+ frame->ref_count++; \
+ } \
+ UNLOCK(&frame->root->stack_lock); \
old_THIS = THIS; \
THIS = obj; \
fn (_new, obj, params); \
@@ -252,20 +257,24 @@ STACK_DESTROY (call_stack_t *stack)
} \
typeof(fn##_cbk) tmp_cbk = rfn; \
_new->root = frame->root; \
- _new->next = frame->root->frames.next; \
- _new->prev = &frame->root->frames; \
- if (frame->root->frames.next) \
- frame->root->frames.next->prev = _new; \
- frame->root->frames.next = _new; \
_new->this = obj; \
_new->ret = (ret_fn_t) tmp_cbk; \
_new->parent = frame; \
_new->cookie = cky; \
- LOCK_INIT (&_new->lock); \
_new->wind_from = __FUNCTION__; \
_new->wind_to = #fn; \
_new->unwind_to = #rfn; \
- frame->ref_count++; \
+ LOCK_INIT (&_new->lock); \
+ LOCK(&frame->root->stack_lock); \
+ { \
+ frame->ref_count++; \
+ _new->next = frame->root->frames.next; \
+ _new->prev = &frame->root->frames; \
+ if (frame->root->frames.next) \
+ frame->root->frames.next->prev = _new; \
+ frame->root->frames.next = _new; \
+ } \
+ UNLOCK(&frame->root->stack_lock); \
fn##_cbk = rfn; \
old_THIS = THIS; \
THIS = obj; \
@@ -286,7 +295,11 @@ STACK_DESTROY (call_stack_t *stack)
} \
fn = frame->ret; \
_parent = frame->parent; \
- _parent->ref_count--; \
+ LOCK(&frame->root->stack_lock); \
+ { \
+ _parent->ref_count--; \
+ } \
+ UNLOCK(&frame->root->stack_lock); \
old_THIS = THIS; \
THIS = _parent->this; \
frame->complete = _gf_true; \
@@ -309,7 +322,11 @@ STACK_DESTROY (call_stack_t *stack)
} \
fn = (fop_##op##_cbk_t )frame->ret; \
_parent = frame->parent; \
- _parent->ref_count--; \
+ LOCK(&frame->root->stack_lock); \
+ { \
+ _parent->ref_count--; \
+ } \
+ UNLOCK(&frame->root->stack_lock); \
old_THIS = THIS; \
THIS = _parent->this; \
frame->complete = _gf_true; \
@@ -352,6 +369,7 @@ copy_frame (call_frame_t *frame)
newstack->lk_owner = oldstack->lk_owner;
LOCK_INIT (&newstack->frames.lock);
+ LOCK_INIT (&newstack->stack_lock);
LOCK (&oldstack->pool->lock);
{
@@ -389,6 +407,7 @@ create_frame (xlator_t *xl, call_pool_t *pool)
UNLOCK (&pool->lock);
LOCK_INIT (&stack->frames.lock);
+ LOCK_INIT (&stack->stack_lock);
return &stack->frames;
}