path: root/xlators
diff options
authorJiffin Tony Thottan <>2016-06-06 18:10:09 +0530
committerKaushal M <>2016-06-24 03:19:49 -0700
commitc04ee47d1e9847b50c459734a42681450005ee60 (patch)
tree0bfa3ba17714eb92b0b31e8bfba542acdadbe360 /xlators
parent568c74b6571bdd6272ed932f5d15285d8a18ed14 (diff)
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 > Change-Id: I7caef48839d4f177c3557d7823fc1d35c8294939 > BUG: 1318204 > Signed-off-by: Jiffin Tony Thottan <> > Signed-off-by: Manikandan Selvaganesh <> Change-Id: I7caef48839d4f177c3557d7823fc1d35c8294939 BUG: 1343362 Signed-off-by: Manikandan Selvaganesh <> Reviewed-on: Reviewed-by: jiffin tony Thottan <> Reviewed-by: Niels de Vos <> CentOS-regression: Gluster Build System <> NetBSD-regression: NetBSD Build System <> Reviewed-by: Raghavendra G <> Smoke: Gluster Build System <>
Diffstat (limited to 'xlators')
2 files changed, 6 insertions, 4 deletions
diff --git a/xlators/nfs/server/src/nfs3.c b/xlators/nfs/server/src/nfs3.c
index aa7af312b89..2bcf85b0ce4 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,
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 f1b89fe17a8..fd7cc0d3a47 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;