summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnand Avati <avati@redhat.com>2013-11-21 06:48:17 -0800
committerAnand Avati <avati@redhat.com>2013-11-26 11:49:05 -0800
commit837422858c2e4ab447879a4141361fd382645406 (patch)
treefcde4c24a7ad906a8cd3081e59668064d9fad150
parent28ae39e94092ce853a114ee9186fbf8f0f1e6adb (diff)
core: fix errno for non-existent GFID
When clients refer to a GFID which does not exist, the errno to be returned in ESTALE (and not ENOENT). Even though ENOENT might look "proper" most of the time, as the application eventually expects ENOENT even if a parent directory does not exist, not returning ESTALE results in resolvers (FUSE and GFAPI) to not retry resolution in uncached mode. This can result in spurious ENOENTs during concurrent path modification operations. Change-Id: I7a06ea6d6a191739f2e9c6e333a1969615e05936 BUG: 1032894 Signed-off-by: Anand Avati <avati@redhat.com> Reviewed-on: http://review.gluster.org/6322 Tested-by: Gluster Build System <jenkins@build.gluster.com>
-rw-r--r--xlators/cluster/afr/src/afr-self-heald.c2
-rw-r--r--xlators/cluster/dht/src/dht-common.h2
-rw-r--r--xlators/cluster/dht/src/dht-helper.c2
-rw-r--r--xlators/cluster/dht/src/dht-inode-read.c9
-rw-r--r--xlators/cluster/dht/src/dht-inode-write.c6
-rw-r--r--xlators/cluster/dht/src/dht-layout.c1
-rw-r--r--xlators/protocol/client/src/client-rpc-fops.c3
-rw-r--r--xlators/protocol/server/src/server-resolve.c4
-rw-r--r--xlators/storage/posix/src/posix.c6
9 files changed, 23 insertions, 12 deletions
diff --git a/xlators/cluster/afr/src/afr-self-heald.c b/xlators/cluster/afr/src/afr-self-heald.c
index 37bc224f58a..4ce6e86c8f3 100644
--- a/xlators/cluster/afr/src/afr-self-heald.c
+++ b/xlators/cluster/afr/src/afr-self-heald.c
@@ -190,7 +190,7 @@ _get_path_from_gfid_loc (xlator_t *this, xlator_t *readdir_xl, loc_t *child,
ret = syncop_getxattr (readdir_xl, child, &xattr, GFID_TO_PATH_KEY);
if (ret < 0) {
- if ((errno == ENOENT) && missing)
+ if ((errno == ENOENT || errno == ESTALE) && missing)
*missing = _gf_true;
goto out;
}
diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h
index e220f554c00..d1d6032540d 100644
--- a/xlators/cluster/dht/src/dht-common.h
+++ b/xlators/cluster/dht/src/dht-common.h
@@ -331,6 +331,8 @@ typedef enum {
} \
} while (0)
+#define dht_inode_missing(op_errno) (op_errno == ENOENT || op_errno == ESTALE)
+
#define check_is_dir(i,s,x) (IA_ISDIR(s->ia_type))
#define layout_is_sane(layout) ((layout) && (layout->cnt > 0))
diff --git a/xlators/cluster/dht/src/dht-helper.c b/xlators/cluster/dht/src/dht-helper.c
index ef29e3f3a8c..552b1597884 100644
--- a/xlators/cluster/dht/src/dht-helper.c
+++ b/xlators/cluster/dht/src/dht-helper.c
@@ -719,7 +719,7 @@ dht_migration_complete_check_task (void *data)
dst_node = dht_linkfile_subvol (this, NULL, NULL, dict);
if (ret) {
- if ((errno != ENOENT) || (!local->loc.inode)) {
+ if (!dht_inode_missing(errno) || (!local->loc.inode)) {
gf_log (this->name, GF_LOG_ERROR,
"%s: failed to get the 'linkto' xattr %s",
local->loc.path, strerror (errno));
diff --git a/xlators/cluster/dht/src/dht-inode-read.c b/xlators/cluster/dht/src/dht-inode-read.c
index f17cb73b97c..1b05f18a4af 100644
--- a/xlators/cluster/dht/src/dht-inode-read.c
+++ b/xlators/cluster/dht/src/dht-inode-read.c
@@ -35,7 +35,7 @@ dht_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
prev = cookie;
local->op_errno = op_errno;
- if ((op_ret == -1) && (op_errno != ENOENT)) {
+ if ((op_ret == -1) && !dht_inode_missing(op_errno)) {
gf_log (this->name, GF_LOG_DEBUG,
"subvolume %s returned -1 (%s)",
prev->this->name, strerror (op_errno));
@@ -143,7 +143,7 @@ dht_file_attr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local = frame->local;
prev = cookie;
- if ((op_ret == -1) && (op_errno != ENOENT)) {
+ if ((op_ret == -1) && !dht_inode_missing(op_errno)) {
local->op_errno = op_errno;
gf_log (this->name, GF_LOG_DEBUG,
"subvolume %s returned -1 (%s)",
@@ -393,7 +393,7 @@ dht_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
if (local->call_cnt != 1)
goto out;
- if ((op_ret == -1) && (op_errno != ENOENT))
+ if ((op_ret == -1) && !dht_inode_missing(op_errno))
goto out;
if ((op_ret == -1) || IS_DHT_MIGRATION_PHASE2 (stbuf)) {
@@ -706,7 +706,8 @@ dht_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret,
prev = cookie;
local->op_errno = op_errno;
- if (op_ret == -1) {
+
+ if (op_ret == -1 && !dht_inode_missing(op_errno)) {
gf_log (this->name, GF_LOG_DEBUG,
"subvolume %s returned -1 (%s)",
prev->this->name, strerror (op_errno));
diff --git a/xlators/cluster/dht/src/dht-inode-write.c b/xlators/cluster/dht/src/dht-inode-write.c
index 5e85ca536af..a0271842841 100644
--- a/xlators/cluster/dht/src/dht-inode-write.c
+++ b/xlators/cluster/dht/src/dht-inode-write.c
@@ -28,7 +28,7 @@ dht_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
dht_local_t *local = NULL;
int ret = -1;
- if (op_ret == -1) {
+ if (op_ret == -1 && !dht_inode_missing(op_errno)) {
goto out;
}
@@ -178,7 +178,7 @@ dht_truncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
local = frame->local;
prev = cookie;
- if ((op_ret == -1) && (op_errno != ENOENT)) {
+ if ((op_ret == -1) && !dht_inode_missing(op_errno)) {
local->op_errno = op_errno;
local->op_ret = -1;
gf_log (this->name, GF_LOG_DEBUG,
@@ -360,7 +360,7 @@ dht_file_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
prev = cookie;
local->op_errno = op_errno;
- if ((op_ret == -1) && (op_errno != ENOENT)) {
+ if ((op_ret == -1) && !dht_inode_missing(op_errno)) {
gf_log (this->name, GF_LOG_DEBUG,
"subvolume %s returned -1 (%s)",
prev->this->name, strerror (op_errno));
diff --git a/xlators/cluster/dht/src/dht-layout.c b/xlators/cluster/dht/src/dht-layout.c
index 3331db5c518..ca6f10d7a92 100644
--- a/xlators/cluster/dht/src/dht-layout.c
+++ b/xlators/cluster/dht/src/dht-layout.c
@@ -532,6 +532,7 @@ dht_layout_anomalies (xlator_t *this, loc_t *loc, dht_layout_t *layout,
switch (layout->list[i].err) {
case -1:
case ENOENT:
+ case ESTALE:
missing++;
break;
case ENOTCONN:
diff --git a/xlators/protocol/client/src/client-rpc-fops.c b/xlators/protocol/client/src/client-rpc-fops.c
index f524c1a373a..12fef8db5a9 100644
--- a/xlators/protocol/client/src/client-rpc-fops.c
+++ b/xlators/protocol/client/src/client-rpc-fops.c
@@ -2615,7 +2615,8 @@ out:
rsp.op_errno = op_errno;
if (rsp.op_ret == -1) {
/* any error other than ENOENT */
- if (rsp.op_errno != ENOENT)
+ if (!(local->loc.name && rsp.op_errno == ENOENT) &&
+ !(rsp.op_errno == ESTALE))
gf_log (this->name, GF_LOG_WARNING,
"remote operation failed: %s. Path: %s (%s)",
strerror (rsp.op_errno),
diff --git a/xlators/protocol/server/src/server-resolve.c b/xlators/protocol/server/src/server-resolve.c
index 4a91a41043c..4c6e819c3f8 100644
--- a/xlators/protocol/server/src/server-resolve.c
+++ b/xlators/protocol/server/src/server-resolve.c
@@ -244,7 +244,7 @@ resolve_entry_simple (call_frame_t *frame)
/* simple resolution is indecisive. need to perform
deep resolution */
resolve->op_ret = -1;
- resolve->op_errno = ENOENT;
+ resolve->op_errno = ESTALE;
ret = 1;
goto out;
}
@@ -341,7 +341,7 @@ resolve_inode_simple (call_frame_t *frame)
if (!inode) {
resolve->op_ret = -1;
- resolve->op_errno = ENOENT;
+ resolve->op_errno = ESTALE;
ret = 1;
goto out;
}
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index 4c9827f1e1b..fb78bc86d07 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -160,6 +160,12 @@ parent:
gf_log (this->name, GF_LOG_ERROR,
"post-operation lstat on parent %s failed: %s",
par_path, strerror (op_errno));
+ if (op_errno == ENOENT)
+ /* If parent directory is missing in a lookup,
+ errno should be ESTALE (bad handle) and not
+ ENOENT (missing entry)
+ */
+ op_errno = ESTALE;
goto out;
}
}