From 50998ae08c5a767468ee85cb5c53bb5554ff734a Mon Sep 17 00:00:00 2001 From: Pranith Kumar K Date: Mon, 17 Nov 2014 14:27:47 +0530 Subject: cluster/afr: Make entry-self-heal in afr-v2 compatible with afr-v1 Backport of http://review.gluster.org/9227 Problem: entry self-heal in 3.6 and above, takes full lock on the directory only for the duration of figuring out the xattrs of the directories where as 3.5 takes locks through out the entry-self-heal. If the cluster is heterogeneous then there is a chance that 3.6 self-heal is triggered and then 3.5 self-heal will also triggered and both the self-heal daemons of 3.5 and 3.6 do self-heal. Fix: In 3.6.x and above get an entry lock on a very long name before entry self-heal begins so that 3.5 entry self-heal will not get locks until 3.6.x entry self-heal completes. BUG: 1177418 Change-Id: Iecf49d794c6b480e38563e39599a40067b3a21cb Signed-off-by: Pranith Kumar K Reviewed-on: http://review.gluster.org/9355 Reviewed-by: Krutika Dhananjay Tested-by: Gluster Build System Reviewed-by: Raghavendra Bhat --- xlators/cluster/afr/src/afr-self-heal-entry.c | 29 ++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'xlators/cluster') diff --git a/xlators/cluster/afr/src/afr-self-heal-entry.c b/xlators/cluster/afr/src/afr-self-heal-entry.c index 3f753251e7c..4b513ffc73d 100644 --- a/xlators/cluster/afr/src/afr-self-heal-entry.c +++ b/xlators/cluster/afr/src/afr-self-heal-entry.c @@ -19,6 +19,15 @@ #include "byte-order.h" #include "afr-transaction.h" +/* Max file name length is 255 this filename is of length 256. No file with + * this name can ever come, entry-lock with this name is going to prevent + * self-heals from older versions while the granular entry-self-heal is going + * on in newer version.*/ +#define LONG_FILENAME "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"\ + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"\ + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"\ + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"\ + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" static int afr_selfheal_entry_delete (xlator_t *this, inode_t *dir, const char *name, @@ -679,6 +688,7 @@ afr_selfheal_entry (call_frame_t *frame, xlator_t *this, inode_t *inode) { afr_private_t *priv = NULL; unsigned char *locked_on = NULL; + unsigned char *long_name_locked = NULL; fd_t *fd = NULL; int ret = 0; @@ -689,6 +699,7 @@ afr_selfheal_entry (call_frame_t *frame, xlator_t *this, inode_t *inode) return -EIO; locked_on = alloca0 (priv->child_count); + long_name_locked = alloca0 (priv->child_count); ret = afr_selfheal_tryentrylk (frame, this, inode, priv->sh_domain, NULL, locked_on); @@ -707,7 +718,23 @@ afr_selfheal_entry (call_frame_t *frame, xlator_t *this, inode_t *inode) goto unlock; } - ret = __afr_selfheal_entry (frame, this, fd, locked_on); + ret = afr_selfheal_tryentrylk (frame, this, inode, this->name, + LONG_FILENAME, long_name_locked); + { + if (ret < 1) { + gf_log (this->name, GF_LOG_DEBUG, "%s: Skipping" + " entry self-heal as only %d " + "sub-volumes could be locked in " + "special-filename domain", + uuid_utoa (fd->inode->gfid), + ret); + ret = -ENOTCONN; + goto unlock; + } + ret = __afr_selfheal_entry (frame, this, fd, locked_on); + } + afr_selfheal_unentrylk (frame, this, inode, this->name, + LONG_FILENAME, long_name_locked); } unlock: afr_selfheal_unentrylk (frame, this, inode, priv->sh_domain, NULL, locked_on); -- cgit