diff options
author | Anand Avati <avati@redhat.com> | 2013-11-21 06:48:17 -0800 |
---|---|---|
committer | Vijay Bellur <vbellur@redhat.com> | 2013-11-26 10:29:23 -0800 |
commit | d1879d04e39258ea25a49eed3244b395d4af2c1d (patch) | |
tree | 5f919b61f9eb05a5bd5cd760b83603be1c0a4257 | |
parent | ec8c678c4d8b948c1b471e497db5adc0221c154b (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/6318
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Amar Tumballi <amarts@gmail.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
-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 | 8 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht-inode-write.c | 12 | ||||
-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, 25 insertions, 15 deletions
diff --git a/xlators/cluster/afr/src/afr-self-heald.c b/xlators/cluster/afr/src/afr-self-heald.c index 1b48a1bcaae..8dbb9c69e71 100644 --- a/xlators/cluster/afr/src/afr-self-heald.c +++ b/xlators/cluster/afr/src/afr-self-heald.c @@ -335,7 +335,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 81e4cc17556..0497352e9a8 100644 --- a/xlators/cluster/dht/src/dht-common.h +++ b/xlators/cluster/dht/src/dht-common.h @@ -351,6 +351,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 311a481126d..00a98f1cfa5 100644 --- a/xlators/cluster/dht/src/dht-helper.c +++ b/xlators/cluster/dht/src/dht-helper.c @@ -769,7 +769,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 ece84151adb..12a5515051c 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)); @@ -144,7 +144,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)", @@ -398,7 +398,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; local->op_errno = op_errno; @@ -722,7 +722,7 @@ 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 && (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-inode-write.c b/xlators/cluster/dht/src/dht-inode-write.c index 1ba98473eee..363bff3bfa8 100644 --- a/xlators/cluster/dht/src/dht-inode-write.c +++ b/xlators/cluster/dht/src/dht-inode-write.c @@ -32,7 +32,7 @@ dht_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int ret = -1; xlator_t *subvol = NULL; - if (op_ret == -1 && (op_errno != ENOENT)) { + if (op_ret == -1 && !dht_inode_missing(op_errno)) { goto out; } @@ -181,7 +181,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, @@ -367,7 +367,7 @@ dht_fallocate_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, @@ -501,7 +501,7 @@ dht_discard_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, @@ -631,7 +631,7 @@ dht_zerofill_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, @@ -763,7 +763,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 38e9970a7a8..2bd9e5ff660 100644 --- a/xlators/cluster/dht/src/dht-layout.c +++ b/xlators/cluster/dht/src/dht-layout.c @@ -540,6 +540,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++; continue; case ENOTCONN: diff --git a/xlators/protocol/client/src/client-rpc-fops.c b/xlators/protocol/client/src/client-rpc-fops.c index 6901d8e2c3b..01590d73afc 100644 --- a/xlators/protocol/client/src/client-rpc-fops.c +++ b/xlators/protocol/client/src/client-rpc-fops.c @@ -2763,7 +2763,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), local->loc.path, diff --git a/xlators/protocol/server/src/server-resolve.c b/xlators/protocol/server/src/server-resolve.c index cc4686a0399..b2bff5c531a 100644 --- a/xlators/protocol/server/src/server-resolve.c +++ b/xlators/protocol/server/src/server-resolve.c @@ -246,7 +246,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; } @@ -343,7 +343,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 65b52a07cd5..2616885eebe 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -165,6 +165,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; } } |