From b8106d1127f034ffa88b5dd322c23a10e023b9b6 Mon Sep 17 00:00:00 2001 From: Krutika Dhananjay Date: Mon, 1 Feb 2016 11:46:08 +0530 Subject: cluster/afr: Fix heal-info slow response while IO is in progress Now heal-info does an open() on the file being examined so that the client at some point sees open-fd count being > 1 and releases the eager-lock so that heal-info doesn't remain blocked forever until IO completes. Change-Id: Icc478098e2bc7234408728b54d8185102b3540dc BUG: 1297695 Signed-off-by: Krutika Dhananjay Reviewed-on: http://review.gluster.org/13326 Reviewed-by: Ravishankar N Smoke: Gluster Build System Reviewed-by: Pranith Kumar Karampuri Tested-by: Pranith Kumar Karampuri NetBSD-regression: NetBSD Build System CentOS-regression: Gluster Build System --- xlators/cluster/afr/src/afr-common.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'xlators/cluster/afr/src/afr-common.c') diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index f33e00a76a0..457f7865cec 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -4513,12 +4513,13 @@ afr_selfheal_locked_data_inspect (call_frame_t *frame, xlator_t *this, gf_boolean_t *pflag) { int ret = -1; - afr_private_t *priv = NULL; unsigned char *locked_on = NULL; unsigned char *data_lock = NULL; unsigned char *sources = NULL; unsigned char *sinks = NULL; unsigned char *healed_sinks = NULL; + afr_private_t *priv = NULL; + fd_t *fd = NULL; struct afr_reply *locked_replies = NULL; priv = this->private; @@ -4528,6 +4529,18 @@ afr_selfheal_locked_data_inspect (call_frame_t *frame, xlator_t *this, sinks = alloca0 (priv->child_count); healed_sinks = alloca0 (priv->child_count); + /* Heal-info does an open() on the file being examined so that the + * current eager-lock holding client, if present, at some point sees + * open-fd count being > 1 and releases the eager-lock so that heal-info + * doesn't remain blocked forever until IO completes. + */ + ret = afr_selfheal_data_open (this, inode, &fd); + if (ret < 0) { + gf_msg_debug (this->name, -ret, "%s: Failed to open", + uuid_utoa (inode->gfid)); + goto out; + } + locked_replies = alloca0 (sizeof (*locked_replies) * priv->child_count); ret = afr_selfheal_tryinodelk (frame, this, inode, priv->sh_domain, @@ -4565,6 +4578,8 @@ unlock: out: if (locked_replies) afr_replies_wipe (locked_replies, priv->child_count); + if (fd) + fd_unref (fd); return ret; } -- cgit