Skip to content

Commit 86e2e1f

Browse files
amschuma-ntapTrond Myklebust
authored andcommitted
NFSv4.2: SETXATTR should update ctime
Otherwise, `stat` will report a stale value to users. Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
1 parent 64edd55 commit 86e2e1f

3 files changed

Lines changed: 32 additions & 7 deletions

File tree

fs/nfs/nfs42proc.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,15 +1190,19 @@ static int _nfs42_proc_setxattr(struct inode *inode, const char *name,
11901190
const void *buf, size_t buflen, int flags)
11911191
{
11921192
struct nfs_server *server = NFS_SERVER(inode);
1193+
__u32 bitmask[NFS_BITMASK_SZ];
11931194
struct page *pages[NFS4XATTR_MAXPAGES];
11941195
struct nfs42_setxattrargs arg = {
11951196
.fh = NFS_FH(inode),
1197+
.bitmask = bitmask,
11961198
.xattr_pages = pages,
11971199
.xattr_len = buflen,
11981200
.xattr_name = name,
11991201
.xattr_flags = flags,
12001202
};
1201-
struct nfs42_setxattrres res;
1203+
struct nfs42_setxattrres res = {
1204+
.server = server,
1205+
};
12021206
struct rpc_message msg = {
12031207
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETXATTR],
12041208
.rpc_argp = &arg,
@@ -1210,23 +1214,36 @@ static int _nfs42_proc_setxattr(struct inode *inode, const char *name,
12101214
if (buflen > server->sxasize)
12111215
return -ERANGE;
12121216

1217+
res.fattr = nfs_alloc_fattr();
1218+
if (!res.fattr)
1219+
return -ENOMEM;
1220+
12131221
if (buflen > 0) {
12141222
np = nfs4_buf_to_pages_noslab(buf, buflen, arg.xattr_pages);
1215-
if (np < 0)
1216-
return np;
1223+
if (np < 0) {
1224+
ret = np;
1225+
goto out;
1226+
}
12171227
} else
12181228
np = 0;
12191229

1230+
nfs4_bitmask_set(bitmask, server->cache_consistency_bitmask,
1231+
inode, NFS_INO_INVALID_CHANGE);
1232+
12201233
ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args,
12211234
&res.seq_res, 1);
12221235
trace_nfs4_setxattr(inode, name, ret);
12231236

12241237
for (; np > 0; np--)
12251238
put_page(pages[np - 1]);
12261239

1227-
if (!ret)
1240+
if (!ret) {
12281241
nfs4_update_changeattr(inode, &res.cinfo, timestamp, 0);
1242+
ret = nfs_post_op_update_inode(inode, res.fattr);
1243+
}
12291244

1245+
out:
1246+
kfree(res.fattr);
12301247
return ret;
12311248
}
12321249

fs/nfs/nfs42xdr.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,13 @@
212212
#define NFS4_enc_setxattr_sz (compound_encode_hdr_maxsz + \
213213
encode_sequence_maxsz + \
214214
encode_putfh_maxsz + \
215-
encode_setxattr_maxsz)
215+
encode_setxattr_maxsz + \
216+
encode_getattr_maxsz)
216217
#define NFS4_dec_setxattr_sz (compound_decode_hdr_maxsz + \
217218
decode_sequence_maxsz + \
218219
decode_putfh_maxsz + \
219-
decode_setxattr_maxsz)
220+
decode_setxattr_maxsz + \
221+
decode_getattr_maxsz)
220222
#define NFS4_enc_listxattrs_sz (compound_encode_hdr_maxsz + \
221223
encode_sequence_maxsz + \
222224
encode_putfh_maxsz + \
@@ -720,6 +722,7 @@ static void nfs4_xdr_enc_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
720722
encode_sequence(xdr, &args->seq_args, &hdr);
721723
encode_putfh(xdr, args->fh, &hdr);
722724
encode_setxattr(xdr, args, &hdr);
725+
encode_getfattr(xdr, args->bitmask, &hdr);
723726
encode_nops(&hdr);
724727
}
725728

@@ -1579,8 +1582,10 @@ static int nfs4_xdr_dec_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
15791582
status = decode_putfh(xdr);
15801583
if (status)
15811584
goto out;
1582-
15831585
status = decode_setxattr(xdr, &res->cinfo);
1586+
if (status)
1587+
goto out;
1588+
status = decode_getfattr(xdr, res->fattr, res->server);
15841589
out:
15851590
return status;
15861591
}

include/linux/nfs_xdr.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,6 +1528,7 @@ struct nfs42_seek_res {
15281528
struct nfs42_setxattrargs {
15291529
struct nfs4_sequence_args seq_args;
15301530
struct nfs_fh *fh;
1531+
const u32 *bitmask;
15311532
const char *xattr_name;
15321533
u32 xattr_flags;
15331534
size_t xattr_len;
@@ -1537,6 +1538,8 @@ struct nfs42_setxattrargs {
15371538
struct nfs42_setxattrres {
15381539
struct nfs4_sequence_res seq_res;
15391540
struct nfs4_change_info cinfo;
1541+
struct nfs_fattr *fattr;
1542+
const struct nfs_server *server;
15401543
};
15411544

15421545
struct nfs42_getxattrargs {

0 commit comments

Comments
 (0)