summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVikas Gorur <vikas@gluster.com>2009-11-24 04:46:35 +0000
committerAnand V. Avati <avati@dev.gluster.com>2009-11-24 04:36:41 -0800
commit1cd2e389020b8713d45dce44df9f473622109b0d (patch)
tree925aeee240b8b0be08af76d8092a84b21fde15ee
parent5b483cb62f00faa66e8795e24856600b961c8d4a (diff)
cluster/afr: Fix handling of revalidate lookups.
This patch does two things related to revalidate: 1) If a revalidate fails on any subvolume, the entire lookup call is failed. 2) Self-heal is not triggered on a revalidate if revalidate has failed on any subvolume. Signed-off-by: Vikas Gorur <vikas@gluster.com> Signed-off-by: Anand V. Avati <avati@dev.gluster.com> BUG: 389 (auto-heal fails randomly and causes "Stale NFS file handle" errors) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=389
-rw-r--r--xlators/cluster/afr/src/afr.c61
-rw-r--r--xlators/cluster/afr/src/afr.h1
2 files changed, 38 insertions, 24 deletions
diff --git a/xlators/cluster/afr/src/afr.c b/xlators/cluster/afr/src/afr.c
index a0441bfb0bd..3f1928157a9 100644
--- a/xlators/cluster/afr/src/afr.c
+++ b/xlators/cluster/afr/src/afr.c
@@ -521,18 +521,14 @@ afr_lookup_cbk (call_frame_t *frame, void *cookie,
if (op_ret == -1) {
if (op_errno == ENOENT)
local->enoent_count++;
-
- if (op_errno != ENOTCONN) {
- if (local->op_errno != ESTALE)
- local->op_errno = op_errno;
- }
- if (op_errno == ESTALE) {
+ local->op_errno = op_errno;
+
+ if (local->cont.lookup.is_revalidate) {
/* no matter what other subvolumes return for
- * this call, ESTALE _must_ be sent to parent
+ * this call, errno _must_ be sent to parent
*/
- local->op_ret = -1;
- local->op_errno = ESTALE;
+ local->op_ret = -1;
}
goto unlock;
}
@@ -576,15 +572,15 @@ afr_lookup_cbk (call_frame_t *frame, void *cookie,
/* inode number should be preserved across revalidates */
if (local->success_count == 0) {
- if (local->op_errno != ESTALE)
- local->op_ret = op_ret;
-
+ if (!local->cont.lookup.is_revalidate)
+ local->op_ret = op_ret;
+
local->cont.lookup.inode = inode;
local->cont.lookup.xattr = dict_ref (xattr);
local->cont.lookup.postparent = *postparent;
*lookup_buf = *buf;
-
+
lookup_buf->st_ino = afr_itransform (buf->st_ino,
priv->child_count,
child_index);
@@ -628,9 +624,6 @@ afr_lookup_cbk (call_frame_t *frame, void *cookie,
lookup has succeeded on the read child.
So use its inode number
*/
- if (local->op_errno != ESTALE)
- local->op_ret = op_ret;
-
if (local->cont.lookup.xattr)
dict_unref (local->cont.lookup.xattr);
@@ -693,7 +686,9 @@ unlock:
|| local->need_entry_self_heal)
&& (!local->open_fd_count &&
!local->inodelk_count &&
- !local->entrylk_count)) {
+ !local->entrylk_count)
+ && ((!local->cont.lookup.is_revalidate)
+ || (local->op_ret != -1))) {
if (!local->cont.lookup.inode->st_mode) {
/* fix for RT #602 */
@@ -725,6 +720,8 @@ afr_lookup (call_frame_t *frame, xlator_t *this,
int ret = -1;
int i = 0;
+ int call_count = 0;
+
uint64_t ctx;
int32_t op_errno = 0;
@@ -748,7 +745,10 @@ afr_lookup (call_frame_t *frame, xlator_t *this,
if (ret == 0) {
/* lookup is a revalidate */
- local->read_child_index = afr_read_child (this, loc->inode);
+ local->op_ret = 0;
+ local->cont.lookup.is_revalidate = _gf_true;
+ local->read_child_index = afr_read_child (this,
+ loc->inode);
} else {
LOCK (&priv->read_child_lock);
{
@@ -758,12 +758,21 @@ afr_lookup (call_frame_t *frame, xlator_t *this,
UNLOCK (&priv->read_child_lock);
}
- local->call_count = priv->child_count;
-
local->child_up = memdup (priv->child_up, priv->child_count);
+
+ local->call_count = afr_up_children_count (priv->child_count,
+ local->child_up);
+ call_count = local->call_count;
+
local->child_count = afr_up_children_count (priv->child_count,
local->child_up);
+ if (local->call_count == 0) {
+ ret = -1;
+ op_errno = ENOTCONN;
+ goto out;
+ }
+
/* By default assume ENOTCONN. On success it will be set to 0. */
local->op_errno = ENOTCONN;
@@ -784,10 +793,14 @@ afr_lookup (call_frame_t *frame, xlator_t *this,
ret = dict_set_uint64 (local->xattr_req, GLUSTERFS_ENTRYLK_COUNT, 0);
for (i = 0; i < priv->child_count; i++) {
- STACK_WIND_COOKIE (frame, afr_lookup_cbk, (void *) (long) i,
- priv->children[i],
- priv->children[i]->fops->lookup,
- loc, local->xattr_req);
+ if (local->child_up[i]) {
+ STACK_WIND_COOKIE (frame, afr_lookup_cbk, (void *) (long) i,
+ priv->children[i],
+ priv->children[i]->fops->lookup,
+ loc, local->xattr_req);
+ if (!--call_count)
+ break;
+ }
}
ret = 0;
diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h
index bde151866bf..2d497afe1d8 100644
--- a/xlators/cluster/afr/src/afr.h
+++ b/xlators/cluster/afr/src/afr.h
@@ -219,6 +219,7 @@ typedef struct _afr_local {
ino_t ino;
ino_t parent_ino;
dict_t *xattr;
+ gf_boolean_t is_revalidate;
} lookup;
struct {