From 7317a250caa96b00072a8a7cb2b2c18016e8a8d2 Mon Sep 17 00:00:00 2001 From: Pavan Sondur Date: Mon, 11 Jan 2010 01:20:21 +0000 Subject: features/locks: Fix broken interface grant_blocked_inode_locks Signed-off-by: Pavan Vilas Sondur Signed-off-by: Anand V. Avati BUG: 496 (deadlock in pl_inode_setlk) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=496 --- xlators/features/locks/src/common.h | 2 +- xlators/features/locks/src/inodelk.c | 55 ++++++++++++++++++++++-------------- 2 files changed, 35 insertions(+), 22 deletions(-) (limited to 'xlators/features') diff --git a/xlators/features/locks/src/common.h b/xlators/features/locks/src/common.h index 46da9e78cb1..00532ea6f92 100644 --- a/xlators/features/locks/src/common.h +++ b/xlators/features/locks/src/common.h @@ -54,7 +54,7 @@ pl_dom_list_t * get_domain (pl_inode_t *pl_inode, const char *volume); void -grant_blocked_inode_locks (xlator_t *this, pl_inode_t *pl_inode, pl_inode_lock_t *lock, pl_dom_list_t *dom); +grant_blocked_inode_locks (xlator_t *this, pl_inode_t *pl_inode, pl_dom_list_t *dom); void __delete_inode_lock (pl_inode_lock_t *lock); diff --git a/xlators/features/locks/src/inodelk.c b/xlators/features/locks/src/inodelk.c index 9e9d6d17389..50a5996d74a 100644 --- a/xlators/features/locks/src/inodelk.c +++ b/xlators/features/locks/src/inodelk.c @@ -304,7 +304,8 @@ out: } static void -__grant_blocked_inode_locks (xlator_t *this, pl_inode_t *pl_inode, pl_dom_list_t *dom) +__grant_blocked_inode_locks (xlator_t *this, pl_inode_t *pl_inode, + struct list_head *granted, pl_dom_list_t *dom) { int bl_ret = 0; pl_inode_lock_t *bl = NULL; @@ -322,19 +323,7 @@ __grant_blocked_inode_locks (xlator_t *this, pl_inode_t *pl_inode, pl_dom_list_t bl_ret = __lock_inodelk (this, pl_inode, bl, 1, dom); if (bl_ret == 0) { - gf_log (this->name, GF_LOG_TRACE, - "%s (pid=%d) (lk-owner=%"PRIu64") %"PRId64" - %"PRId64" => Granted", - bl->fl_type == F_UNLCK ? "Unlock" : "Lock", - bl->client_pid, - bl->owner, - bl->user_flock.l_start, - bl->user_flock.l_len); - - pl_trace_out (this, bl->frame, NULL, NULL, F_SETLKW, - &bl->user_flock, 0, 0, bl->volume); - - - STACK_UNWIND_STRICT (inodelk, bl->frame, 0, 0); + list_add (&bl->blocked_locks, granted); } } return; @@ -342,18 +331,39 @@ __grant_blocked_inode_locks (xlator_t *this, pl_inode_t *pl_inode, pl_dom_list_t /* Grant all inodelks blocked on a lock */ void -grant_blocked_inode_locks (xlator_t *this, pl_inode_t *pl_inode, pl_inode_lock_t *lock, pl_dom_list_t *dom) +grant_blocked_inode_locks (xlator_t *this, pl_inode_t *pl_inode, pl_dom_list_t *dom) { + struct list_head granted; + pl_inode_lock_t *lock; + pl_inode_lock_t *tmp; + + INIT_LIST_HEAD (&granted); if (list_empty (&dom->blocked_inodelks)) { gf_log (this->name, GF_LOG_TRACE, "No blocked locks to be granted for domain: %s", dom->domain); - goto out; } - __grant_blocked_inode_locks (this, pl_inode, dom); -out: - __destroy_inode_lock (lock); + pthread_mutex_lock (&pl_inode->mutex); + { + __grant_blocked_inode_locks (this, pl_inode, &granted, dom); + } + pthread_mutex_unlock (&pl_inode->mutex); + + list_for_each_entry_safe (lock, tmp, &granted, blocked_locks) { + gf_log (this->name, GF_LOG_TRACE, + "%s (pid=%d) (lk-owner=%"PRIu64") %"PRId64" - %"PRId64" => Granted", + lock->fl_type == F_UNLCK ? "Unlock" : "Lock", + lock->client_pid, + lock->owner, + lock->user_flock.l_start, + lock->user_flock.l_len); + + pl_trace_out (this, lock->frame, NULL, NULL, F_SETLKW, + &lock->user_flock, 0, 0, lock->volume); + + STACK_UNWIND_STRICT (inodelk, lock->frame, 0, 0); + } } @@ -408,8 +418,8 @@ release_inode_locks_of_transport (xlator_t *this, pl_dom_list_t *dom, continue; __delete_inode_lock (l); + __destroy_inode_lock (l); - grant_blocked_inode_locks (this, pinode, l, dom); if (inode_path (inode, NULL, &path) < 0) { gf_log (this->name, GF_LOG_TRACE, @@ -440,6 +450,7 @@ unlock: FREE (l); } + grant_blocked_inode_locks (this, pinode, dom); return 0; } @@ -484,13 +495,15 @@ pl_inode_setlk (xlator_t *this, pl_inode_t *pl_inode, pl_inode_lock_t *lock, ret = -EINVAL; goto out; } + __destroy_inode_lock (retlock); ret = 0; - grant_blocked_inode_locks (this, pl_inode, retlock, dom); + } out: pthread_mutex_unlock (&pl_inode->mutex); + grant_blocked_inode_locks (this, pl_inode, dom); return ret; } -- cgit