Blob Blame History Raw
From 1b683e5e26f91cb55c23e07cf6e33ce3ef62283b Mon Sep 17 00:00:00 2001
From: Jiffin Tony Thottan <jthottan@redhat.com>
Date: Mon, 6 Jun 2016 18:10:09 +0530
Subject: [PATCH 191/192] nfs : store sattr properly in nfs3_setattr() call

nfs3_setattr stores the input arguments in cs->stbuf.
However, inode/entry resolution code overwrites cs->stbuf
after a successful resolution, thereby overwriting the
input arguments with iatt values stored on backend.
Hence operations like chmod/chown turns out to be a NOP.
Specifically following are the functions that overwrite
cs->stbuf:

    nfs3_fh_resolve_inode_lookup_cbk
    nfs3_fh_resolve_entry_lookup_cbk

Since we resort to inode resolution only when inode is not
found in inode table and lru limit guards the number of
inodes in itable, we run into this issue only when the data
set is bigger than lru limit of itable.

Fix is to store input arguments in a member other than
cs->stbuf.

Thanks Du for suggesting the fix

        Backport of http://review.gluster.org/#/c/14657/

> Change-Id: I7caef48839d4f177c3557d7823fc1d35c8294939
> BUG: 1318204
> Signed-off-by: Jiffin Tony Thottan <jthottan@redhat.com>
> Signed-off-by: Manikandan Selvaganesh <mselvaga@redhat.com>

Change-Id: I7caef48839d4f177c3557d7823fc1d35c8294939
BUG: 1336753
Signed-off-by: Manikandan Selvaganesh <mselvaga@redhat.com>
Signed-off-by: Jiffin Tony Thottan <jthottan@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/76053
Reviewed-by: Kaleb Keithley <kkeithle@redhat.com>
Tested-by: Kaleb Keithley <kkeithle@redhat.com>
Reviewed-by: Raghavendra Gowdappa <rgowdapp@redhat.com>
---
 xlators/nfs/server/src/nfs3.c |    9 +++++----
 xlators/nfs/server/src/nfs3.h |    1 +
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/xlators/nfs/server/src/nfs3.c b/xlators/nfs/server/src/nfs3.c
index aa7af31..2bcf85b 100644
--- a/xlators/nfs/server/src/nfs3.c
+++ b/xlators/nfs/server/src/nfs3.c
@@ -1024,10 +1024,11 @@ nfs3svc_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
          */
         if ((gf_attr_size_set (cs->setattr_valid)) &&
             (!IA_ISDIR (postop->ia_type)) &&
-            (preop->ia_size != cs->stbuf.ia_size)) {
+            (preop->ia_size != cs->attr_in.ia_size)) {
                 nfs_request_user_init (&nfu, cs->req);
                 ret = nfs_truncate (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
-                                    cs->stbuf.ia_size, nfs3svc_truncate_cbk,cs);
+                                    cs->attr_in.ia_size, nfs3svc_truncate_cbk,
+                                    cs);
 
                 if (ret < 0)
                         stat = nfs3_errno_to_nfsstat3 (-ret);
@@ -1110,7 +1111,7 @@ nfs3_setattr_resume (void *carg)
         nfs3_check_fh_resolve_status (cs, stat, nfs3err);
         nfs_request_user_init (&nfu, cs->req);
         ret = nfs_setattr (cs->nfsx, cs->vol, &nfu, &cs->resolvedloc,
-                           &cs->stbuf, cs->setattr_valid,
+                           &cs->attr_in, cs->setattr_valid,
                            nfs3svc_setattr_cbk, cs);
 
         if (ret < 0)
@@ -1152,7 +1153,7 @@ nfs3_setattr (rpcsvc_request_t *req, struct nfs3_fh *fh, sattr3 *sattr,
         nfs3_check_rw_volaccess (nfs3, fh->exportid, stat, nfs3err);
         nfs3_handle_call_state_init (nfs3, cs, req, vol, stat, nfs3err);
 
-        cs->setattr_valid = nfs3_sattr3_to_setattr_valid (sattr, &cs->stbuf,
+        cs->setattr_valid = nfs3_sattr3_to_setattr_valid (sattr, &cs->attr_in,
                                                           NULL);
         if (guard->check) {
                 gf_msg_trace (GF_NFS3, 0, "Guard check required");
diff --git a/xlators/nfs/server/src/nfs3.h b/xlators/nfs/server/src/nfs3.h
index f1b89fe..fd7cc0d 100644
--- a/xlators/nfs/server/src/nfs3.h
+++ b/xlators/nfs/server/src/nfs3.h
@@ -230,6 +230,7 @@ struct nfs3_local {
         cookie3                 cookie;
         struct iovec            datavec;
         mode_t                  mode;
+        struct iatt             attr_in;
 
         /* NFSv3 FH resolver state */
         int                     hardresolved;
-- 
1.7.1