From 3f7ff1a0343045c737fcca3ffbdc380be8a1f065 Mon Sep 17 00:00:00 2001 From: N Balachandran Date: Mon, 11 Mar 2019 11:30:05 +0530 Subject: [PATCH 537/538] cluster/dht: Do not use gfid-req in fresh lookup Fuse sets a random gfid-req value for a fresh lookup. Posix lookup will set this gfid on entries with missing gfids causing a GFID mismatch for directories. DHT will now ignore the Fuse provided gfid-req and use the GFID returned from other subvols to heal the missing gfid. upstream: https://review.gluster.org/#/c/22112/ > Change-Id: I5f541978808f246ba4542564251e341ec490db14 > fixes: bz#1670259 > Signed-off-by: N Balachandran Change-Id: I50e5a9cb4db8164989082daab30a0d5cac70920c BUG: 1661258 Signed-off-by: N Balachandran Reviewed-on: https://code.engineering.redhat.com/gerrit/164947 Tested-by: RHGS Build Bot Reviewed-by: Mohit Agrawal Reviewed-by: Sunil Kumar Heggodu Gopala Acharya --- xlators/cluster/dht/src/dht-common.c | 63 ++++++++++++++++++++++++++++++++++-- xlators/cluster/dht/src/dht-common.h | 2 ++ 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index 1311a8d..12a17e6 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -1347,7 +1347,7 @@ dht_lookup_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (!op_ret && gf_uuid_is_null (local->gfid)) { memcpy (local->gfid, stbuf->ia_gfid, 16); } - if (local->gfid) + if (!gf_uuid_is_null (local->gfid)) gf_uuid_unparse(local->gfid, gfid_local); /* Check if the gfid is different for file from other node */ @@ -1376,9 +1376,13 @@ dht_lookup_dir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (op_ret == -1) { local->op_errno = op_errno; gf_msg_debug (this->name, op_errno, - "lookup of %s on %s returned error", + "%s: lookup on %s returned error", local->loc.path, prev->name); + /* The GFID is missing on this subvol. Force a heal. */ + if (op_errno == ENODATA) { + local->need_selfheal = 1; + } goto unlock; } @@ -1485,6 +1489,17 @@ unlock: if (local->need_selfheal) { local->need_selfheal = 0; + /* Set the gfid-req so posix will set the GFID*/ + if (!gf_uuid_is_null(local->gfid)) { + ret = dict_set_static_bin(local->xattr_req, + "gfid-req", + local->gfid, 16); + } else { + if (!gf_uuid_is_null(local->gfid_req)) + ret = dict_set_static_bin(local->xattr_req, + "gfid-req", + local->gfid_req, 16); + } dht_lookup_everywhere (frame, this, &local->loc); return 0; } @@ -1686,6 +1701,12 @@ dht_revalidate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, local->need_lookup_everywhere = 1; } } + /* The GFID is missing on this subvol*/ + if ((op_errno == ENODATA) && + (IA_ISDIR(local->loc.inode->ia_type))) { + local->need_lookup_everywhere = 1; + } + goto unlock; } @@ -1931,6 +1952,13 @@ cont: /* We know that current cached subvol is no more valid, get the new one */ local->cached_subvol = NULL; + if (local->xattr_req) { + if (!gf_uuid_is_null(local->gfid)) { + ret = dict_set_static_bin(local->xattr_req, + "gfid-req", + local->gfid, 16); + } + } dht_lookup_everywhere (frame, this, &local->loc); return 0; } @@ -2391,6 +2419,17 @@ dht_lookup_everywhere_done (call_frame_t *frame, xlator_t *this) return 0; } + if (local->op_ret && local->gfid_missing) { + if (gf_uuid_is_null(local->gfid_req)) { + DHT_STACK_UNWIND(lookup, frame, -1, ENODATA, NULL, + NULL, NULL, NULL); + return 0; + } + /* A hack */ + dht_lookup_directory(frame, this, &local->loc); + return 0; + } + if (local->dir_count) { dht_lookup_directory (frame, this, &local->loc); return 0; @@ -2751,6 +2790,8 @@ dht_lookup_everywhere_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (op_ret == -1) { if (op_errno != ENOENT) local->op_errno = op_errno; + if (op_errno == ENODATA) + local->gfid_missing = _gf_true; goto unlock; } @@ -3292,7 +3333,8 @@ dht_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } } - if (is_dir || (op_ret == -1 && op_errno == ENOTCONN)) { + if (is_dir || (op_ret == -1 && + ((op_errno == ENOTCONN) || (op_errno == ENODATA)))) { dht_lookup_directory (frame, this, &local->loc); return 0; } @@ -3421,6 +3463,7 @@ dht_lookup (call_frame_t *frame, xlator_t *this, int call_cnt = 0; int gen = 0; loc_t new_loc = {0,}; + void *gfid_req_ptr = NULL; VALIDATE_OR_GOTO (frame, err); VALIDATE_OR_GOTO (this, err); @@ -3630,6 +3673,20 @@ dht_lookup (call_frame_t *frame, xlator_t *this, /* need it for dir self-heal */ dht_check_and_set_acl_xattr_req (loc->inode, local->xattr_req); + /* Fuse sets a random value in gfid-req. If the gfid is missing + * on one or more subvols, posix will set the gfid to this + * value, causing GFID mismatches for directories. + */ + ret = dict_get_ptr(local->xattr_req, "gfid-req", + &gfid_req_ptr); + if (ret) { + gf_msg_debug(this->name, 0, + "%s: No gfid-req available", loc->path); + } else { + memcpy(local->gfid_req, gfid_req_ptr, sizeof(uuid_t)); + dict_del(local->xattr_req, "gfid-req"); + } + if (!hashed_subvol) { gf_msg_debug (this->name, 0, diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h index b40815c..94a0869 100644 --- a/xlators/cluster/dht/src/dht-common.h +++ b/xlators/cluster/dht/src/dht-common.h @@ -346,6 +346,7 @@ struct dht_local { /* gfid related */ uuid_t gfid; + uuid_t gfid_req; /* flag used to make sure we need to return estale in {lookup,revalidate}_cbk */ @@ -394,6 +395,7 @@ struct dht_local { loc_t loc2_copy; gf_boolean_t locked; gf_boolean_t dont_create_linkto; + gf_boolean_t gfid_missing; }; typedef struct dht_local dht_local_t; -- 1.8.3.1