Commit 86e2e1f6 authored by Anna Schumaker's avatar Anna Schumaker Committed by Trond Myklebust
Browse files

NFSv4.2: SETXATTR should update ctime



Otherwise, `stat` will report a stale value to users.

Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
parent 64edd55d
Loading
Loading
Loading
Loading
+21 −4
Original line number Diff line number Diff line
@@ -1190,15 +1190,19 @@ static int _nfs42_proc_setxattr(struct inode *inode, const char *name,
				const void *buf, size_t buflen, int flags)
{
	struct nfs_server *server = NFS_SERVER(inode);
	__u32 bitmask[NFS_BITMASK_SZ];
	struct page *pages[NFS4XATTR_MAXPAGES];
	struct nfs42_setxattrargs arg = {
		.fh		= NFS_FH(inode),
		.bitmask	= bitmask,
		.xattr_pages	= pages,
		.xattr_len	= buflen,
		.xattr_name	= name,
		.xattr_flags	= flags,
	};
	struct nfs42_setxattrres res;
	struct nfs42_setxattrres res = {
		.server		= server,
	};
	struct rpc_message msg = {
		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_SETXATTR],
		.rpc_argp	= &arg,
@@ -1210,13 +1214,22 @@ static int _nfs42_proc_setxattr(struct inode *inode, const char *name,
	if (buflen > server->sxasize)
		return -ERANGE;

	res.fattr = nfs_alloc_fattr();
	if (!res.fattr)
		return -ENOMEM;

	if (buflen > 0) {
		np = nfs4_buf_to_pages_noslab(buf, buflen, arg.xattr_pages);
		if (np < 0)
			return np;
		if (np < 0) {
			ret = np;
			goto out;
		}
	} else
		np = 0;

	nfs4_bitmask_set(bitmask, server->cache_consistency_bitmask,
			 inode, NFS_INO_INVALID_CHANGE);

	ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args,
	    &res.seq_res, 1);
	trace_nfs4_setxattr(inode, name, ret);
@@ -1224,9 +1237,13 @@ static int _nfs42_proc_setxattr(struct inode *inode, const char *name,
	for (; np > 0; np--)
		put_page(pages[np - 1]);

	if (!ret)
	if (!ret) {
		nfs4_update_changeattr(inode, &res.cinfo, timestamp, 0);
		ret = nfs_post_op_update_inode(inode, res.fattr);
	}

out:
	kfree(res.fattr);
	return ret;
}

+8 −3
Original line number Diff line number Diff line
@@ -212,11 +212,13 @@
#define NFS4_enc_setxattr_sz		(compound_encode_hdr_maxsz + \
					 encode_sequence_maxsz + \
					 encode_putfh_maxsz + \
					 encode_setxattr_maxsz)
					 encode_setxattr_maxsz + \
					 encode_getattr_maxsz)
#define NFS4_dec_setxattr_sz		(compound_decode_hdr_maxsz + \
					 decode_sequence_maxsz + \
					 decode_putfh_maxsz + \
					 decode_setxattr_maxsz)
					 decode_setxattr_maxsz + \
					 decode_getattr_maxsz)
#define NFS4_enc_listxattrs_sz		(compound_encode_hdr_maxsz + \
					 encode_sequence_maxsz + \
					 encode_putfh_maxsz + \
@@ -720,6 +722,7 @@ static void nfs4_xdr_enc_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
	encode_sequence(xdr, &args->seq_args, &hdr);
	encode_putfh(xdr, args->fh, &hdr);
	encode_setxattr(xdr, args, &hdr);
	encode_getfattr(xdr, args->bitmask, &hdr);
	encode_nops(&hdr);
}

@@ -1579,8 +1582,10 @@ static int nfs4_xdr_dec_setxattr(struct rpc_rqst *req, struct xdr_stream *xdr,
	status = decode_putfh(xdr);
	if (status)
		goto out;

	status = decode_setxattr(xdr, &res->cinfo);
	if (status)
		goto out;
	status = decode_getfattr(xdr, res->fattr, res->server);
out:
	return status;
}
+3 −0
Original line number Diff line number Diff line
@@ -1528,6 +1528,7 @@ struct nfs42_seek_res {
struct nfs42_setxattrargs {
	struct nfs4_sequence_args	seq_args;
	struct nfs_fh			*fh;
	const u32			*bitmask;
	const char			*xattr_name;
	u32				xattr_flags;
	size_t				xattr_len;
@@ -1537,6 +1538,8 @@ struct nfs42_setxattrargs {
struct nfs42_setxattrres {
	struct nfs4_sequence_res	seq_res;
	struct nfs4_change_info		cinfo;
	struct nfs_fattr		*fattr;
	const struct nfs_server		*server;
};

struct nfs42_getxattrargs {