diff options
| author | Pavan Sondur <pavan@gluster.com> | 2010-01-11 01:19:05 +0000 | 
|---|---|---|
| committer | Anand V. Avati <avati@dev.gluster.com> | 2010-01-14 23:23:34 -0800 | 
| commit | 3647c9707f0124ae2fea21b4d501461e0e9b0169 (patch) | |
| tree | 5f4e7d81675c2329b55adf574dd76711737def4c | |
| parent | d0c355917839ac06463ea1d0852eb56835cb7b45 (diff) | |
features/locks: Do not call grant blocked locks in pl_forget
Signed-off-by: Pavan Vilas Sondur <pavan@gluster.com>
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
BUG: 496 (deadlock in pl_inode_setlk)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=496
| -rw-r--r-- | xlators/features/locks/src/posix.c | 129 | 
1 files changed, 85 insertions, 44 deletions
diff --git a/xlators/features/locks/src/posix.c b/xlators/features/locks/src/posix.c index d4e1b152f..60724d5c3 100644 --- a/xlators/features/locks/src/posix.c +++ b/xlators/features/locks/src/posix.c @@ -788,79 +788,120 @@ pl_forget (xlator_t *this,          posix_lock_t *ext_tmp = NULL;          posix_lock_t *ext_l   = NULL; +	struct list_head posixlks_released;          pl_inode_lock_t *ino_tmp = NULL;          pl_inode_lock_t *ino_l   = NULL; +	struct list_head inodelks_released;          pl_rw_req_t *rw_tmp = NULL;          pl_rw_req_t *rw_req = NULL;          pl_entry_lock_t *entry_tmp = NULL;          pl_entry_lock_t *entry_l   = NULL; +	struct list_head entrylks_released;          pl_dom_list_t *dom = NULL;          pl_dom_list_t *dom_tmp = NULL; +	INIT_LIST_HEAD (&posixlks_released); +	INIT_LIST_HEAD (&inodelks_released); +	INIT_LIST_HEAD (&entrylks_released); +          pl_inode = pl_inode_get (this, inode); -        if (!list_empty (&pl_inode->rw_list)) { -                gf_log (this->name, GF_LOG_DEBUG, -                        "Pending R/W requests found, releasing."); +	pthread_mutex_lock (&pl_inode->mutex); +	{ -                list_for_each_entry_safe (rw_req, rw_tmp, &pl_inode->rw_list, -                                          list) { +		if (!list_empty (&pl_inode->rw_list)) { +			gf_log (this->name, GF_LOG_WARNING, +				"Pending R/W requests found, releasing."); -                        list_del (&rw_req->list); -                        FREE (rw_req); -                } -        } +			list_for_each_entry_safe (rw_req, rw_tmp, &pl_inode->rw_list, +						  list) { -        if (!list_empty (&pl_inode->ext_list)) { -                gf_log (this->name, GF_LOG_DEBUG, -                        "Pending fcntl locks found, releasing."); +				list_del (&rw_req->list); +				FREE (rw_req); +			} +		} -                list_for_each_entry_safe (ext_l, ext_tmp, &pl_inode->ext_list, -                                          list) { +		if (!list_empty (&pl_inode->ext_list)) { +			gf_log (this->name, GF_LOG_WARNING, +				"Pending fcntl locks found, releasing."); -                        __delete_lock (pl_inode, ext_l); -                        __destroy_lock (ext_l); -                } -        } +			list_for_each_entry_safe (ext_l, ext_tmp, &pl_inode->ext_list, +						  list) { +				__delete_lock (pl_inode, ext_l); +				if (ext_l->blocked) { +					list_add_tail (&ext_l->list, &posixlks_released); +					continue; +				} +				__destroy_lock (ext_l); +			} +		} -        list_for_each_entry_safe (dom, dom_tmp, &pl_inode->dom_list, inode_list) { -                if (!list_empty (&dom->inodelk_list)) { -                        gf_log (this->name, GF_LOG_WARNING, -                                "Pending inode locks found, releasing."); +		list_for_each_entry_safe (dom, dom_tmp, &pl_inode->dom_list, inode_list) { -                        list_for_each_entry_safe (ino_l, ino_tmp, &dom->inodelk_list, list) { -                                __delete_inode_lock (ino_l); -                                grant_blocked_inode_locks (this, pl_inode, ino_l, dom); -                        } +			if (!list_empty (&dom->inodelk_list)) { +				gf_log (this->name, GF_LOG_WARNING, +					"Pending inode locks found, releasing."); -                } -                if (!list_empty (&dom->entrylk_list)) { -                        gf_log (this->name, GF_LOG_WARNING, -                                "Pending entry locks found, releasing."); +				list_for_each_entry_safe (ino_l, ino_tmp, &dom->inodelk_list, list) { +					__delete_inode_lock (ino_l); +					__destroy_inode_lock (ino_l); +				} -                        list_for_each_entry_safe (entry_l, entry_tmp, &dom->entrylk_list, domain_list) { -                                list_del_init (&entry_l->domain_list); -                                grant_blocked_entry_locks (this, pl_inode, entry_l, dom); +				list_splice_init (&dom->blocked_inodelks, &inodelks_released); +				 -                                if (entry_l->basename) -                                        FREE (entry_l->basename); -                                FREE (entry_l); -                        } +			} +			if (!list_empty (&dom->entrylk_list)) { +				gf_log (this->name, GF_LOG_WARNING, +					"Pending entry locks found, releasing."); -                } +				list_for_each_entry_safe (entry_l, entry_tmp, &dom->entrylk_list, domain_list) { +					list_del_init (&entry_l->domain_list); -                list_del (&dom->inode_list); -                gf_log ("posix-locks", GF_LOG_TRACE, -                        " Cleaning up domain: %s", dom->domain); -                FREE (dom->domain); -                FREE (dom); -        } +					if (entry_l->basename) +						FREE (entry_l->basename); +					FREE (entry_l); +				} + +				list_splice_init (&dom->blocked_entrylks, &entrylks_released); +			} + +			list_del (&dom->inode_list); +			gf_log ("posix-locks", GF_LOG_TRACE, +				" Cleaning up domain: %s", dom->domain); +			FREE (dom->domain); +			FREE (dom); +		} + +	} +	pthread_mutex_unlock (&pl_inode->mutex); + +	list_for_each_entry_safe (ext_l, ext_tmp, &posixlks_released, list) { + +		STACK_UNWIND_STRICT (lk, ext_l->frame, -1, 0, &ext_l->user_flock); +		__destroy_lock (ext_l); +	} + +	list_for_each_entry_safe (ino_l, ino_tmp, &inodelks_released, blocked_locks) { + +		STACK_UNWIND_STRICT (inodelk, ino_l->frame, -1, 0); +		__destroy_inode_lock (ino_l); +	} + +	list_for_each_entry_safe (entry_l, entry_tmp, &entrylks_released, blocked_locks) { + +		STACK_UNWIND_STRICT (entrylk, entry_l->frame, -1, 0); +		if (entry_l->basename) +			FREE (entry_l->basename); +		FREE (entry_l); + +	}          FREE (pl_inode);  | 
