From 56ae2cb68cd715a49f9a03f1ef13e22782ef6792 Mon Sep 17 00:00:00 2001
From: Mohammed Rafi KC <rkavunga@redhat.com>
Date: Tue, 27 Sep 2016 19:01:48 +0530
Subject: [PATCH 166/206] nfs: revalidate lookup converted to fresh lookup
Backport of http://review.gluster.org/15580
when an inode ctx is missing for a linked inode the revalidate
lookups are converted to fresh.
This could result in sending ESTALE when the gfid are recreated
We are not able to reproduce the issue with normal setup, most part of
RCA was done with code reading.
Possible scenario in which this bug can reproduce,
Delete a file and recreate a new file with same name, at the same time
from another client process try to list/or access the file.
In this case the second client may throw an ESTALE error for such files
Thanks to Soumya and Pranith for doing the complete RCA
>Change-Id: I73992a65844b09a169cefaaedc0dcfb129d66ea1
>BUG: 1379720
>Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com>
>Reviewed-on: http://review.gluster.org/15580
>NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
>CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
>Smoke: Gluster Build System <jenkins@build.gluster.org>
>Reviewed-by: soumya k <skoduri@redhat.com>
>Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com>
>Change-Id: Ifd0d92e29e409e5b23790b677034cfc8f3184d1a
>BUG: 1394635
Change-Id: I86e6a156e806a10baad01d7930c2a725e62b9cc9
BUG: 1380419
Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/90281
Reviewed-by: Soumya Koduri <skoduri@redhat.com>
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
Tested-by: Atin Mukherjee <amukherj@redhat.com>
---
xlators/nfs/server/src/mount3.c | 4 ++--
xlators/nfs/server/src/nfs-common.c | 7 +++++--
xlators/nfs/server/src/nfs-common.h | 3 ++-
xlators/nfs/server/src/nfs3-helpers.c | 11 ++++++-----
4 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/xlators/nfs/server/src/mount3.c b/xlators/nfs/server/src/mount3.c
index 2647e38..48b719d 100644
--- a/xlators/nfs/server/src/mount3.c
+++ b/xlators/nfs/server/src/mount3.c
@@ -1059,7 +1059,7 @@ __mnt3_resolve_export_subdir_comp (mnt3_resolve_t *mres)
nfs_loc_wipe (&mres->resolveloc);
ret = nfs_entry_loc_fill (mres->mstate->nfsx, mres->exp->vol->itable,
gfid, nextcomp, &mres->resolveloc,
- NFS_RESOLVE_CREATE);
+ NFS_RESOLVE_CREATE, NULL);
if ((ret < 0) && (ret != -2)) {
gf_msg (GF_MNT, GF_LOG_ERROR, EFAULT,
NFS_MSG_RESOLVE_INODE_FAIL, "Failed to resolve and "
@@ -1374,7 +1374,7 @@ __mnt3_resolve_subdir (mnt3_resolve_t *mres)
rootgfid[15] = 1;
ret = nfs_entry_loc_fill (mres->mstate->nfsx, mres->exp->vol->itable,
rootgfid, firstcomp, &mres->resolveloc,
- NFS_RESOLVE_CREATE);
+ NFS_RESOLVE_CREATE, NULL);
if ((ret < 0) && (ret != -2)) {
gf_msg (GF_MNT, GF_LOG_ERROR, EFAULT,
NFS_MSG_RESOLVE_INODE_FAIL, "Failed to resolve and "
diff --git a/xlators/nfs/server/src/nfs-common.c b/xlators/nfs/server/src/nfs-common.c
index d9ea1e1..af37f6b 100644
--- a/xlators/nfs/server/src/nfs-common.c
+++ b/xlators/nfs/server/src/nfs-common.c
@@ -308,7 +308,7 @@ err:
*/
int
nfs_entry_loc_fill (xlator_t *this, inode_table_t *itable, uuid_t pargfid,
- char *entry, loc_t *loc, int how)
+ char *entry, loc_t *loc, int how, gf_boolean_t *freshlookup)
{
inode_t *parent = NULL;
inode_t *entryinode = NULL;
@@ -337,8 +337,11 @@ nfs_entry_loc_fill (xlator_t *this, inode_table_t *itable, uuid_t pargfid,
* that the caller can use the filled loc to call
* lookup.
*/
- if (!entryinode)
+ if (!entryinode) {
entryinode = inode_new (itable);
+ if (freshlookup)
+ *freshlookup = _gf_true;
+ }
/* Cannot change ret because that must
* continue to have -2.
*/
diff --git a/xlators/nfs/server/src/nfs-common.h b/xlators/nfs/server/src/nfs-common.h
index 77bdfb0..8c9a1e3 100644
--- a/xlators/nfs/server/src/nfs-common.h
+++ b/xlators/nfs/server/src/nfs-common.h
@@ -57,7 +57,8 @@ nfs_ino_loc_fill (inode_table_t *itable, uuid_t gfid, loc_t *l);
extern int
nfs_entry_loc_fill (xlator_t *this, inode_table_t *itable, uuid_t pargfid,
- char *entry, loc_t *loc, int how);
+ char *entry, loc_t *loc, int how,
+ gf_boolean_t *freshlookup);
extern int
nfs_root_loc_fill (inode_table_t *itable, loc_t *loc);
diff --git a/xlators/nfs/server/src/nfs3-helpers.c b/xlators/nfs/server/src/nfs3-helpers.c
index 5ed57bd..0b97709 100644
--- a/xlators/nfs/server/src/nfs3-helpers.c
+++ b/xlators/nfs/server/src/nfs3-helpers.c
@@ -3757,8 +3757,9 @@ out:
int
nfs3_fh_resolve_entry_hard (nfs3_call_state_t *cs)
{
- int ret = -EFAULT;
- nfs_user_t nfu = {0, };
+ int ret = -EFAULT;
+ nfs_user_t nfu = {0, };
+ gf_boolean_t freshlookup = _gf_false;
if (!cs)
return ret;
@@ -3771,7 +3772,7 @@ nfs3_fh_resolve_entry_hard (nfs3_call_state_t *cs)
ret = nfs_entry_loc_fill (cs->nfsx, cs->vol->itable, cs->resolvefh.gfid,
cs->resolventry, &cs->resolvedloc,
- NFS_RESOLVE_CREATE);
+ NFS_RESOLVE_CREATE, &freshlookup);
if (ret == -2) {
gf_msg_trace (GF_NFS3, 0, "Entry needs lookup: %s",
@@ -3782,8 +3783,8 @@ nfs3_fh_resolve_entry_hard (nfs3_call_state_t *cs)
* go ahead in the resume callback so that an EEXIST gets
* handled at posix without an extra fop at this point.
*/
- if (nfs3_lookup_op (cs) ||
- (nfs3_create_op (cs) && !nfs3_create_exclusive_op (cs))) {
+ if (freshlookup && (nfs3_lookup_op (cs) ||
+ (nfs3_create_op (cs) && !nfs3_create_exclusive_op (cs)))) {
cs->lookuptype = GF_NFS3_FRESH;
cs->resolve_ret = 0;
cs->hardresolved = 0;
--
2.9.3