diff options
author | Anand Avati <avati@redhat.com> | 2013-11-21 06:48:17 -0800 |
---|---|---|
committer | Anand Avati <avati@redhat.com> | 2013-11-26 11:49:05 -0800 |
commit | 837422858c2e4ab447879a4141361fd382645406 (patch) | |
tree | fcde4c24a7ad906a8cd3081e59668064d9fad150 /xlators | |
parent | 28ae39e94092ce853a114ee9186fbf8f0f1e6adb (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>
Diffstat (limited to 'xlators')
-rw-r--r-- | xlators/cluster/afr/src/afr-self-heald.c | 2 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht-common.h | 2 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht-helper.c | 2 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht-inode-read.c | 9 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht-inode-write.c | 6 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht-layout.c | 1 | ||||
-rw-r--r-- | xlators/protocol/client/src/client-rpc-fops.c | 3 | ||||
-rw-r--r-- | xlators/protocol/server/src/server-resolve.c | 4 | ||||
-rw-r--r-- | xlators/storage/posix/src/posix.c | 6 |
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 37bc224f5..4ce6e86c8 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 e220f554c..d1d603254 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 ef29e3f3a..552b15978 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 f17cb73b9..1b05f18a4 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 5e85ca536..a02718428 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 3331db5c5..ca6f10d7a 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 f524c1a37..12fef8db5 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 4a91a4104..4c6e819c3 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 4c9827f1e..fb78bc86d 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; } } |