|
|
21ab4e |
From b3b78fa20f8e186d9bba8082814247ebee902f96 Mon Sep 17 00:00:00 2001
|
|
|
21ab4e |
From: Susant Palai <spalai@redhat.com>
|
|
|
21ab4e |
Date: Wed, 11 Jan 2017 16:04:47 +0530
|
|
|
21ab4e |
Subject: [PATCH 419/426] dht: send lookup on old name inside rename with bname
|
|
|
21ab4e |
and pargfid
|
|
|
21ab4e |
|
|
|
21ab4e |
Inside rename, a lookup is done on the source name to make sure that
|
|
|
21ab4e |
the file is there. But we used to do a gfid based lookup and hence,
|
|
|
21ab4e |
even if the source name was renamed to a new name from some other client,
|
|
|
21ab4e |
lookup will be successful as server3_3_lookup will fetch the new path
|
|
|
21ab4e |
based on the gfid.
|
|
|
21ab4e |
|
|
|
21ab4e |
So even if the source file does not exist any more rename will carry on,
|
|
|
21ab4e |
and as server3_3_link(destination is hashed to a different brick other
|
|
|
21ab4e |
than source cached scenario) also does gfid based resolve, it wont
|
|
|
21ab4e |
detect that the source name does not exist and hardlink creation will be
|
|
|
21ab4e |
successful (since gfid based resolve will get the new dentry).
|
|
|
21ab4e |
|
|
|
21ab4e |
To solve this problem, do a name based lookup inside rename. So that
|
|
|
21ab4e |
rename will fail right away if the source does not exist.
|
|
|
21ab4e |
|
|
|
21ab4e |
>Reviewed-on: https://review.gluster.org/16375
|
|
|
21ab4e |
>Smoke: Gluster Build System <jenkins@build.gluster.org>
|
|
|
21ab4e |
>NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
|
|
|
21ab4e |
>Reviewed-by: N Balachandran <nbalacha@redhat.com>
|
|
|
21ab4e |
>CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
|
|
|
21ab4e |
|
|
|
21ab4e |
Change-Id: Ieba8bdd6675088dbf18de90ed4622df043d163bd
|
|
|
21ab4e |
BUG: 1411352
|
|
|
21ab4e |
Signed-off-by: Susant Palai <spalai@redhat.com>
|
|
|
21ab4e |
Reviewed-on: https://code.engineering.redhat.com/gerrit/104688
|
|
|
21ab4e |
Tested-by: Atin Mukherjee <amukherj@redhat.com>
|
|
|
21ab4e |
Reviewed-by: Nithya Balachandran <nbalacha@redhat.com>
|
|
|
21ab4e |
---
|
|
|
21ab4e |
libglusterfs/src/xlator.c | 6 +++-
|
|
|
21ab4e |
xlators/cluster/dht/src/dht-rename.c | 64 +++++++++++++++++++++++++++++++-----
|
|
|
21ab4e |
2 files changed, 61 insertions(+), 9 deletions(-)
|
|
|
21ab4e |
|
|
|
21ab4e |
diff --git a/libglusterfs/src/xlator.c b/libglusterfs/src/xlator.c
|
|
|
21ab4e |
index 6775efc..6e3ff51 100644
|
|
|
21ab4e |
--- a/libglusterfs/src/xlator.c
|
|
|
21ab4e |
+++ b/libglusterfs/src/xlator.c
|
|
|
21ab4e |
@@ -922,7 +922,11 @@ loc_copy (loc_t *dst, loc_t *src)
|
|
|
21ab4e |
GF_VALIDATE_OR_GOTO ("xlator", dst, err);
|
|
|
21ab4e |
GF_VALIDATE_OR_GOTO ("xlator", src, err);
|
|
|
21ab4e |
|
|
|
21ab4e |
- gf_uuid_copy (dst->gfid, src->gfid);
|
|
|
21ab4e |
+ if (!gf_uuid_is_null (src->gfid))
|
|
|
21ab4e |
+ gf_uuid_copy (dst->gfid, src->gfid);
|
|
|
21ab4e |
+ else if (src->inode && !gf_uuid_is_null (src->inode->gfid))
|
|
|
21ab4e |
+ gf_uuid_copy (dst->gfid, src->inode->gfid);
|
|
|
21ab4e |
+
|
|
|
21ab4e |
gf_uuid_copy (dst->pargfid, src->pargfid);
|
|
|
21ab4e |
|
|
|
21ab4e |
if (src->inode)
|
|
|
21ab4e |
diff --git a/xlators/cluster/dht/src/dht-rename.c b/xlators/cluster/dht/src/dht-rename.c
|
|
|
21ab4e |
index 7e7e715..3cd400f 100644
|
|
|
21ab4e |
--- a/xlators/cluster/dht/src/dht-rename.c
|
|
|
21ab4e |
+++ b/xlators/cluster/dht/src/dht-rename.c
|
|
|
21ab4e |
@@ -1307,9 +1307,15 @@ dht_rename_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
21ab4e |
inode_t *inode, struct iatt *stbuf, dict_t *xattr,
|
|
|
21ab4e |
struct iatt *postparent)
|
|
|
21ab4e |
{
|
|
|
21ab4e |
- dht_local_t *local = NULL;
|
|
|
21ab4e |
- int call_cnt = 0;
|
|
|
21ab4e |
- dht_conf_t *conf = NULL;
|
|
|
21ab4e |
+ dht_local_t *local = NULL;
|
|
|
21ab4e |
+ int call_cnt = 0;
|
|
|
21ab4e |
+ dht_conf_t *conf = NULL;
|
|
|
21ab4e |
+ char gfid_local[GF_UUID_BUF_SIZE] = {0};
|
|
|
21ab4e |
+ char gfid_server[GF_UUID_BUF_SIZE] = {0};
|
|
|
21ab4e |
+ int child_index = -1;
|
|
|
21ab4e |
+
|
|
|
21ab4e |
+
|
|
|
21ab4e |
+ child_index = (long)cookie;
|
|
|
21ab4e |
|
|
|
21ab4e |
local = frame->local;
|
|
|
21ab4e |
conf = this->private;
|
|
|
21ab4e |
@@ -1328,16 +1334,39 @@ dht_rename_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
21ab4e |
* that this is a linkfile and fail the rename operation.
|
|
|
21ab4e |
*/
|
|
|
21ab4e |
local->is_linkfile = _gf_true;
|
|
|
21ab4e |
+ local->op_errno = op_errno;
|
|
|
21ab4e |
} else if (xattr && check_is_linkfile (inode, stbuf, xattr,
|
|
|
21ab4e |
conf->link_xattr_name)) {
|
|
|
21ab4e |
local->is_linkfile = _gf_true;
|
|
|
21ab4e |
+ /* Found linkto file instead of data file, passdown ENOENT
|
|
|
21ab4e |
+ * based on the above comment */
|
|
|
21ab4e |
+ local->op_errno = ENOENT;
|
|
|
21ab4e |
+ }
|
|
|
21ab4e |
+
|
|
|
21ab4e |
+ if (!local->is_linkfile &&
|
|
|
21ab4e |
+ gf_uuid_compare (local->lock.locks[child_index]->loc.gfid,
|
|
|
21ab4e |
+ stbuf->ia_gfid)) {
|
|
|
21ab4e |
+ gf_uuid_unparse (local->lock.locks[child_index]->loc.gfid, gfid_local);
|
|
|
21ab4e |
+ gf_uuid_unparse (stbuf->ia_gfid, gfid_server);
|
|
|
21ab4e |
+
|
|
|
21ab4e |
+ gf_msg (this->name, GF_LOG_WARNING, 0,
|
|
|
21ab4e |
+ DHT_MSG_GFID_MISMATCH,
|
|
|
21ab4e |
+ "path:%s, received a different gfid, local_gfid= %s"
|
|
|
21ab4e |
+ " server_gfid: %s",
|
|
|
21ab4e |
+ local->loc.path, gfid_local, gfid_server);
|
|
|
21ab4e |
+
|
|
|
21ab4e |
+ /* Will passdown ENOENT anyway since the file we sent on
|
|
|
21ab4e |
+ * rename is replaced with a different file */
|
|
|
21ab4e |
+ local->op_errno = ENOENT;
|
|
|
21ab4e |
+ /* Since local->is_linkfile is used here to detect failure,
|
|
|
21ab4e |
+ * marking this to true */
|
|
|
21ab4e |
+ local->is_linkfile = _gf_true;
|
|
|
21ab4e |
}
|
|
|
21ab4e |
|
|
|
21ab4e |
call_cnt = dht_frame_return (frame);
|
|
|
21ab4e |
if (is_last_call (call_cnt)) {
|
|
|
21ab4e |
if (local->is_linkfile) {
|
|
|
21ab4e |
local->op_ret = -1;
|
|
|
21ab4e |
- local->op_errno = op_errno;
|
|
|
21ab4e |
goto fail;
|
|
|
21ab4e |
}
|
|
|
21ab4e |
|
|
|
21ab4e |
@@ -1401,11 +1430,30 @@ dht_rename_lock_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
|
|
|
21ab4e |
|
|
|
21ab4e |
local->call_cnt = local->lock.lk_count;
|
|
|
21ab4e |
|
|
|
21ab4e |
+ /* Why not use local->lock.locks[?].loc for lookup post lock phase
|
|
|
21ab4e |
+ * ---------------------------------------------------------------
|
|
|
21ab4e |
+ * "locks[?].loc" does not have the name and pargfid populated.
|
|
|
21ab4e |
+ * Reason: If we had populated the name and pargfid, server might
|
|
|
21ab4e |
+ * resolve to a successful lookup even if there is a file with same name
|
|
|
21ab4e |
+ * with a different gfid(unlink & create) as server does name based
|
|
|
21ab4e |
+ * resolution on first priority. And this can result in operating on a
|
|
|
21ab4e |
+ * different inode entirely.
|
|
|
21ab4e |
+ *
|
|
|
21ab4e |
+ * Now consider a scenario where source file was renamed by some other
|
|
|
21ab4e |
+ * client to a new name just before this lock was granted. So if a
|
|
|
21ab4e |
+ * lookup would be done on local->lock.locks[?].loc, server will send
|
|
|
21ab4e |
+ * success even if the entry was renamed (since server willl do a gfid
|
|
|
21ab4e |
+ * based resolution). So once a lock is granted, make sure the file
|
|
|
21ab4e |
+ * exists with the name that the client requested with.
|
|
|
21ab4e |
+ * */
|
|
|
21ab4e |
+
|
|
|
21ab4e |
for (i = 0; i < local->lock.lk_count; i++) {
|
|
|
21ab4e |
- STACK_WIND (frame, dht_rename_lookup_cbk,
|
|
|
21ab4e |
- local->lock.locks[i]->xl,
|
|
|
21ab4e |
- local->lock.locks[i]->xl->fops->lookup,
|
|
|
21ab4e |
- &local->lock.locks[i]->loc, xattr_req);
|
|
|
21ab4e |
+ STACK_WIND_COOKIE (frame, dht_rename_lookup_cbk, (void *)(long)i
|
|
|
21ab4e |
+ , local->lock.locks[i]->xl,
|
|
|
21ab4e |
+ local->lock.locks[i]->xl->fops->lookup,
|
|
|
21ab4e |
+ ((gf_uuid_compare (local->loc.gfid, \
|
|
|
21ab4e |
+ local->lock.locks[i]->loc.gfid) == 0) ?
|
|
|
21ab4e |
+ &local->loc : &local->loc2), xattr_req);
|
|
|
21ab4e |
}
|
|
|
21ab4e |
|
|
|
21ab4e |
dict_unref (xattr_req);
|
|
|
21ab4e |
--
|
|
|
21ab4e |
1.8.3.1
|
|
|
21ab4e |
|