diff options
| author | Pranith Kumar K <pkarampu@redhat.com> | 2018-07-06 12:28:53 +0530 | 
|---|---|---|
| committer | Pranith Kumar Karampuri <pkarampu@redhat.com> | 2018-07-10 04:13:01 +0000 | 
| commit | 03f1f5bdc46076178f1afdf8e2a76c5b973fe11f (patch) | |
| tree | 27e321fa747032ee81bc4eca01d40c124f29e683 | |
| parent | 886ee4dfacdbdff68f7cf5d4938fdf1c81b98e03 (diff) | |
cluster/afr: Prevent execution of code after call_count decrementing
Problem:
When call_count is decremented by one thread, another thread can
go ahead with the operation leading to undefined behavior for the
thread executing statements after decrementing call count.
Fix:
Do the operations necessary before decrementing call count.
fixes bz#1598663
Change-Id: Icc90cd92ac16e5fbdfe534d9f0a61312943393fe
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
| -rw-r--r-- | xlators/cluster/afr/src/afr-lk-common.c | 15 | 
1 files changed, 8 insertions, 7 deletions
diff --git a/xlators/cluster/afr/src/afr-lk-common.c b/xlators/cluster/afr/src/afr-lk-common.c index be3de01924d..dff6644eb96 100644 --- a/xlators/cluster/afr/src/afr-lk-common.c +++ b/xlators/cluster/afr/src/afr-lk-common.c @@ -970,6 +970,14 @@ afr_nonblocking_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          local    = frame->local;          int_lock = &local->internal_lock; +        if (op_ret == 0 && local->transaction.type == AFR_DATA_TRANSACTION) { +                LOCK (&local->inode->lock); +                { +                        local->inode_ctx->lock_count++; +                } +                UNLOCK (&local->inode->lock); +        } +          LOCK (&frame->lock);          {  		if (op_ret < 0) { @@ -994,13 +1002,6 @@ afr_nonblocking_inodelk_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          }          UNLOCK (&frame->lock); -        if (op_ret == 0 && local->transaction.type == AFR_DATA_TRANSACTION) { -                LOCK (&local->inode->lock); -                { -                        local->inode_ctx->lock_count++; -                } -                UNLOCK (&local->inode->lock); -        }          if (call_count == 0) {                  gf_msg_trace (this->name, 0,                                "Last inode locking reply received");  | 
