From 0aa270282f0f0a7649d5e07f7d128cef5996cf70 Mon Sep 17 00:00:00 2001 From: Anand Avati Date: Sat, 22 Oct 2011 09:48:17 +0530 Subject: locks: perform inode_ref of pl_update_refkeeper outside locked region Performing inode_ref inside the critical section of pl_update_refkeeper (around pl_inode_t->mutex) causes a deadlock with inode_table_t->lock. The other thread (process state dump) holds the inode_table_t->lock first to loop over inodes and then while dumping an inode's lock context, tries to acquire pl_inode_t->mutex thereby completing the deadlock. The fix is to perform inode_ref outside the critical section in pl_update_refkeeper Change-Id: I689ab4a9b46b36287740279fdec6159182c86119 BUG: 3753 Reviewed-on: http://review.gluster.com/630 Tested-by: Gluster Build System Reviewed-by: Vijay Bellur --- xlators/features/locks/src/common.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'xlators') diff --git a/xlators/features/locks/src/common.c b/xlators/features/locks/src/common.c index c957b974c..bf22183ed 100644 --- a/xlators/features/locks/src/common.c +++ b/xlators/features/locks/src/common.c @@ -391,6 +391,7 @@ pl_update_refkeeper (xlator_t *this, inode_t *inode) pl_inode_t *pl_inode = NULL; int is_empty = 0; int need_unref = 0; + int need_ref = 0; pl_inode = pl_inode_get (this, inode); @@ -404,13 +405,17 @@ pl_update_refkeeper (xlator_t *this, inode_t *inode) } if (!is_empty && !pl_inode->refkeeper) { - pl_inode->refkeeper = inode_ref (inode); + need_ref = 1; + pl_inode->refkeeper = inode; } } pthread_mutex_unlock (&pl_inode->mutex); if (need_unref) inode_unref (inode); + + if (need_ref) + inode_ref (inode); } -- cgit