Commit 7f08a335 authored by Trond Myklebust's avatar Trond Myklebust
Browse files

NFSv4: Add support for the NFSv4.2 "change_attr_type" attribute



The change_attr_type allows the server to provide a description of how
the change attribute will behave. This again will allow the client to
optimise its behaviour w.r.t. attribute revalidation.

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
parent 993e2d4b
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -792,6 +792,7 @@ static void nfs_server_set_fsinfo(struct nfs_server *server,
	server->maxfilesize = fsinfo->maxfilesize;

	server->time_delta = fsinfo->time_delta;
	server->change_attr_type = fsinfo->change_attr_type;

	server->clone_blksize = fsinfo->clone_blksize;
	/* We're airborne Set socket buffersize */
@@ -933,6 +934,8 @@ struct nfs_server *nfs_alloc_server(void)
		return NULL;
	}

	server->change_attr_type = NFS4_CHANGE_TYPE_IS_UNDEFINED;

	ida_init(&server->openowner_id);
	ida_init(&server->lockowner_id);
	pnfs_init_server(server);
+1 −0
Original line number Diff line number Diff line
@@ -2227,6 +2227,7 @@ static int decode_fsinfo3resok(struct xdr_stream *xdr,

	/* ignore properties */
	result->lease_time = 0;
	result->change_attr_type = NFS4_CHANGE_TYPE_IS_TIME_METADATA;
	return 0;
}

+1 −0
Original line number Diff line number Diff line
@@ -264,6 +264,7 @@ const u32 nfs4_fsinfo_bitmap[3] = { FATTR4_WORD0_MAXFILESIZE
			| FATTR4_WORD1_FS_LAYOUT_TYPES,
			FATTR4_WORD2_LAYOUT_BLKSIZE
			| FATTR4_WORD2_CLONE_BLKSIZE
			| FATTR4_WORD2_CHANGE_ATTR_TYPE
			| FATTR4_WORD2_XATTR_SUPPORT
};

+32 −0
Original line number Diff line number Diff line
@@ -153,6 +153,7 @@ static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req,
				 5 /* fs layout types */ + \
				 1 /* layout blksize */ + \
				 1 /* clone blksize */ + \
				 1 /* change attr type */ + \
				 1 /* xattr support */)
#define encode_renew_maxsz	(op_encode_hdr_maxsz + 3)
#define decode_renew_maxsz	(op_decode_hdr_maxsz)
@@ -4846,6 +4847,32 @@ static int decode_attr_clone_blksize(struct xdr_stream *xdr, uint32_t *bitmap,
	return 0;
}

static int decode_attr_change_attr_type(struct xdr_stream *xdr,
					uint32_t *bitmap,
					enum nfs4_change_attr_type *res)
{
	u32 tmp = NFS4_CHANGE_TYPE_IS_UNDEFINED;

	dprintk("%s: bitmap is %x\n", __func__, bitmap[2]);
	if (bitmap[2] & FATTR4_WORD2_CHANGE_ATTR_TYPE) {
		if (xdr_stream_decode_u32(xdr, &tmp))
			return -EIO;
		bitmap[2] &= ~FATTR4_WORD2_CHANGE_ATTR_TYPE;
	}

	switch(tmp) {
	case NFS4_CHANGE_TYPE_IS_MONOTONIC_INCR:
	case NFS4_CHANGE_TYPE_IS_VERSION_COUNTER:
	case NFS4_CHANGE_TYPE_IS_VERSION_COUNTER_NOPNFS:
	case NFS4_CHANGE_TYPE_IS_TIME_METADATA:
		*res = tmp;
		break;
	default:
		*res = NFS4_CHANGE_TYPE_IS_UNDEFINED;
	}
	return 0;
}

static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo)
{
	unsigned int savep;
@@ -4894,6 +4921,11 @@ static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo)
	if (status)
		goto xdr_error;

	status = decode_attr_change_attr_type(xdr, bitmap,
					      &fsinfo->change_attr_type);
	if (status)
		goto xdr_error;

	status = decode_attr_xattrsupport(xdr, bitmap,
					  &fsinfo->xattr_support);
	if (status)
+1 −0
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ nfs_proc_get_root(struct nfs_server *server, struct nfs_fh *fhandle,
	info->dtpref = fsinfo.tsize;
	info->maxfilesize = 0x7FFFFFFF;
	info->lease_time = 0;
	info->change_attr_type = NFS4_CHANGE_TYPE_IS_TIME_METADATA;
	return 0;
}

Loading