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