3604df
From 2b7ab9febff2100f6ae6f3d25d3f916e17109fd7 Mon Sep 17 00:00:00 2001
3604df
From: Pranith Kumar K <pkarampu@redhat.com>
3604df
Date: Wed, 9 Nov 2016 13:07:25 +0530
3604df
Subject: [PATCH 159/162] performance/open-behind: Avoid deadlock in statedump
3604df
3604df
Problem:
3604df
open-behind is taking fd->lock then inode->lock where as statedump is taking
3604df
inode->lock then fd->lock, so it is leading to deadlock
3604df
3604df
In open-behind, following code exists:
3604df
void
3604df
ob_fd_free (ob_fd_t *ob_fd)
3604df
{
3604df
        loc_wipe (&ob_fd->loc); <<--- this takes (inode->lock)
3604df
.......
3604df
}
3604df
3604df
int
3604df
ob_wake_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
3604df
             int op_ret, int op_errno, fd_t *fd_ret, dict_t *xdata)
3604df
{
3604df
	.......
3604df
        LOCK (&fd->lock); <<---- fd->lock
3604df
        {
3604df
	.......
3604df
                __fd_ctx_del (fd, this, NULL);
3604df
                ob_fd_free (ob_fd); <<<---------------
3604df
        }
3604df
        UNLOCK (&fd->lock);
3604df
.......
3604df
}
3604df
=================================================================
3604df
In statedump this code exists:
3604df
inode_dump (inode_t *inode, char *prefix)
3604df
{
3604df
.......
3604df
	ret = TRY_LOCK(&inode->lock); <<---- inode->lock
3604df
.......
3604df
	fd_ctx_dump (fd, prefix); <<<-----
3604df
.......
3604df
}
3604df
fd_ctx_dump (fd_t *fd, char *prefix)
3604df
{
3604df
.......
3604df
        LOCK (&fd->lock); <<<------------------ this takes fd-lock
3604df
        {
3604df
.......
3604df
}
3604df
3604df
Fix:
3604df
Make sure open-behind doesn't call ob_fd_free() inside fd->lock
3604df
3604df
 >BUG: 1393259
3604df
 >Change-Id: I4abdcfc5216270fa1e2b43f7b73445f49e6d6e6e
3604df
 >Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
3604df
 >Reviewed-on: http://review.gluster.org/15808
3604df
 >Smoke: Gluster Build System <jenkins@build.gluster.org>
3604df
 >NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
3604df
 >CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
3604df
 >Reviewed-by: Poornima G <pgurusid@redhat.com>
3604df
 >Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
3604df
3604df
BUG: 1392899
3604df
Change-Id: I45a0fbed683ef6acb7900df87534927f332fdaaa
3604df
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
3604df
Reviewed-on: https://code.engineering.redhat.com/gerrit/89794
3604df
---
3604df
 xlators/performance/open-behind/src/open-behind.c |    5 ++++-
3604df
 1 files changed, 4 insertions(+), 1 deletions(-)
3604df
3604df
diff --git a/xlators/performance/open-behind/src/open-behind.c b/xlators/performance/open-behind/src/open-behind.c
3604df
index 00e8906..d6dcf6f 100644
3604df
--- a/xlators/performance/open-behind/src/open-behind.c
3604df
+++ b/xlators/performance/open-behind/src/open-behind.c
3604df
@@ -154,13 +154,16 @@ ob_wake_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
3604df
 		if (op_ret < 0) {
3604df
 			/* mark fd BAD for ever */
3604df
 			ob_fd->op_errno = op_errno;
3604df
+                        ob_fd = NULL; /*shouldn't be freed*/
3604df
 		} else {
3604df
 			__fd_ctx_del (fd, this, NULL);
3604df
-			ob_fd_free (ob_fd);
3604df
 		}
3604df
 	}
3604df
 	UNLOCK (&fd->lock);
3604df
 
3604df
+        if (ob_fd)
3604df
+                ob_fd_free (ob_fd);
3604df
+
3604df
 	list_for_each_entry_safe (stub, tmp, &list, list) {
3604df
 		list_del_init (&stub->list);
3604df
 
3604df
-- 
3604df
1.7.1
3604df