summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMohammed Rafi KC <rkavunga@redhat.com>2016-09-27 19:01:48 +0530
committerNiels de Vos <ndevos@redhat.com>2017-02-16 13:53:43 -0500
commitcce1e4c2b96bac9c496565546045a6cebec52afe (patch)
tree1bb2760d9523e9c6636e725bdb87d1159bf304d5
parent61a5de50ae6c58c587e9cd808d395d2689051894 (diff)
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> Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com> Change-Id: I44c3770fb07e84183f8bc6eceb533efbc67fb67f BUG: 1394634 Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com> Reviewed-on: https://review.gluster.org/15839 Smoke: Gluster Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: Niels de Vos <ndevos@redhat.com> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org>
-rw-r--r--xlators/nfs/server/src/mount3.c4
-rw-r--r--xlators/nfs/server/src/nfs-common.c7
-rw-r--r--xlators/nfs/server/src/nfs-common.h3
-rw-r--r--xlators/nfs/server/src/nfs3-helpers.c11
4 files changed, 15 insertions, 10 deletions
diff --git a/xlators/nfs/server/src/mount3.c b/xlators/nfs/server/src/mount3.c
index 5b1da41ef1d..4fb4b757423 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 d9ea1e1ac47..af37f6b264c 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 77bdfb0bbf0..8c9a1e33457 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 5ed57bde0e2..0b977092fbb 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;