Blob Blame History Raw
From 2b7ab9febff2100f6ae6f3d25d3f916e17109fd7 Mon Sep 17 00:00:00 2001
From: Pranith Kumar K <pkarampu@redhat.com>
Date: Wed, 9 Nov 2016 13:07:25 +0530
Subject: [PATCH 159/162] performance/open-behind: Avoid deadlock in statedump

Problem:
open-behind is taking fd->lock then inode->lock where as statedump is taking
inode->lock then fd->lock, so it is leading to deadlock

In open-behind, following code exists:
void
ob_fd_free (ob_fd_t *ob_fd)
{
        loc_wipe (&ob_fd->loc); <<--- this takes (inode->lock)
.......
}

int
ob_wake_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
             int op_ret, int op_errno, fd_t *fd_ret, dict_t *xdata)
{
	.......
        LOCK (&fd->lock); <<---- fd->lock
        {
	.......
                __fd_ctx_del (fd, this, NULL);
                ob_fd_free (ob_fd); <<<---------------
        }
        UNLOCK (&fd->lock);
.......
}
=================================================================
In statedump this code exists:
inode_dump (inode_t *inode, char *prefix)
{
.......
	ret = TRY_LOCK(&inode->lock); <<---- inode->lock
.......
	fd_ctx_dump (fd, prefix); <<<-----
.......
}
fd_ctx_dump (fd_t *fd, char *prefix)
{
.......
        LOCK (&fd->lock); <<<------------------ this takes fd-lock
        {
.......
}

Fix:
Make sure open-behind doesn't call ob_fd_free() inside fd->lock

 >BUG: 1393259
 >Change-Id: I4abdcfc5216270fa1e2b43f7b73445f49e6d6e6e
 >Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
 >Reviewed-on: http://review.gluster.org/15808
 >Smoke: Gluster Build System <jenkins@build.gluster.org>
 >NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
 >CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
 >Reviewed-by: Poornima G <pgurusid@redhat.com>
 >Reviewed-by: Raghavendra G <rgowdapp@redhat.com>

BUG: 1392899
Change-Id: I45a0fbed683ef6acb7900df87534927f332fdaaa
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/89794
---
 xlators/performance/open-behind/src/open-behind.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/xlators/performance/open-behind/src/open-behind.c b/xlators/performance/open-behind/src/open-behind.c
index 00e8906..d6dcf6f 100644
--- a/xlators/performance/open-behind/src/open-behind.c
+++ b/xlators/performance/open-behind/src/open-behind.c
@@ -154,13 +154,16 @@ ob_wake_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
 		if (op_ret < 0) {
 			/* mark fd BAD for ever */
 			ob_fd->op_errno = op_errno;
+                        ob_fd = NULL; /*shouldn't be freed*/
 		} else {
 			__fd_ctx_del (fd, this, NULL);
-			ob_fd_free (ob_fd);
 		}
 	}
 	UNLOCK (&fd->lock);
 
+        if (ob_fd)
+                ob_fd_free (ob_fd);
+
 	list_for_each_entry_safe (stub, tmp, &list, list) {
 		list_del_init (&stub->list);
 
-- 
1.7.1