diff options
author | Pranith Kumar K <pkarampu@redhat.com> | 2014-06-12 20:38:34 +0530 |
---|---|---|
committer | Vijay Bellur <vbellur@redhat.com> | 2014-06-14 04:10:06 -0700 |
commit | 12b7797bfb143890ad4ca085332ec2f5e1ed08b8 (patch) | |
tree | 36fc239722c1df779e7a4efc43f64063bcd39ffd /xlators/protocol | |
parent | 7aa3630b1f5e07227e9cd167cbd717bd7932ae78 (diff) |
Fix resolution issues across fuse/server/afr
Problems with fuse/server:
Fuse loc touch up sets loc->name even when pargfid
is not known. Server lookup does (pargfid, name) based
lookup when name is set ignoring the gfid. Because of this server
resolver finds that the lookup came on (null-pargfid, name) and
fails the lookup with EINVAL.
Fix:
Don't set loc->name in loc_touchup if the pargfid is not known.
Did the same even for server-resolver
Problem with afr:
Lets say there is a directory hierarchy a/b/c/d on the mount and the
user is cd'ed into the directory. Bring down one of the bricks of replica and
remove all directories/files to simulate disk replacement on that brick. Now
this brick is brought back up. Creates on the cd'ed directory fail with ESTALE.
Basically before sending a create of 'f' inside 'd', fuse sends a lookup to
make sure the file is not present. On one of the bricks 'd' is present and
'f' is not so it sends ENOENT as response. On the new brick 'd' itself is not
present. So it sends ESTALE. In afr ESTALE is considered to be special errno on
witnessing which lookup has to fail. And ESTALE is given more priority than
ENOENT. Due to these reasons lookup fails with ESTALE rather than ENOENT. Since
lookup didn't fail with ENOENT, 'create' can't be issued so the command is
failed with ESTALE.
Solution:
Afr needs to consider ESTALE errno normally and ENOENT needs to
be given more priority so that operations like create can proceed even when
only one of the brick is up and running. Whenever client xlator identifies
that gfid-changed, it sets that information in lookup xdata. Afr uses this
information to fail the lookup with ESTALE so that top xlator can send
fresh lookup.
Change-Id: Ica6ce01baef08620154050a635e6f97d51029ef6
BUG: 1106408
Signed-off-by: Pranith Kumar K <pkarampu@redhat.com>
Reviewed-on: http://review.gluster.org/8015
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Diffstat (limited to 'xlators/protocol')
-rw-r--r-- | xlators/protocol/client/src/client-rpc-fops.c | 4 | ||||
-rw-r--r-- | xlators/protocol/server/src/server-resolve.c | 5 |
2 files changed, 4 insertions, 5 deletions
diff --git a/xlators/protocol/client/src/client-rpc-fops.c b/xlators/protocol/client/src/client-rpc-fops.c index dd6f48afb57..64d30f2a99f 100644 --- a/xlators/protocol/client/src/client-rpc-fops.c +++ b/xlators/protocol/client/src/client-rpc-fops.c @@ -2737,8 +2737,12 @@ client3_3_lookup_cbk (struct rpc_req *req, struct iovec *iov, int count, && (uuid_compare (stbuf.ia_gfid, inode->gfid) != 0)) { gf_log (frame->this->name, GF_LOG_DEBUG, "gfid changed for %s", local->loc.path); + rsp.op_ret = -1; op_errno = ESTALE; + if (xdata) + ret = dict_set_int32 (xdata, "gfid-changed", 1); + goto out; } diff --git a/xlators/protocol/server/src/server-resolve.c b/xlators/protocol/server/src/server-resolve.c index 9384e765cca..3b787c61734 100644 --- a/xlators/protocol/server/src/server-resolve.c +++ b/xlators/protocol/server/src/server-resolve.c @@ -48,11 +48,6 @@ resolve_loc_touchup (call_frame_t *frame) loc->name = resolve->bname; } else if (loc->inode) { ret = inode_path (loc->inode, NULL, &path); - if (path) { - loc->name = strrchr (path, '/'); - if (loc->name) - loc->name++; - } } if (ret) gf_log (frame->this->name, GF_LOG_TRACE, |