NFSv4: Add support for the NFSv4.2 "change_attr_type" attribute
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Fri, 26 Mar 2021 13:50:19 +0000 (09:50 -0400)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Tue, 13 Apr 2021 14:04:05 +0000 (10:04 -0400)
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: Trond Myklebust <trond.myklebust@hammerspace.com>
fs/nfs/client.c
fs/nfs/nfs3xdr.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4xdr.c
fs/nfs/proc.c
include/linux/nfs4.h
include/linux/nfs_fs_sb.h
include/linux/nfs_xdr.h

index 399a8eb..2aeb4e5 100644 (file)
@@ -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);
index ed1c837..83ad62c 100644 (file)
@@ -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;
 }
 
index bc90f2a..6992c88 100644 (file)
@@ -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
 };
 
index d8a1911..edac471 100644 (file)
@@ -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)
index 73ab7c5..ea19dbf 100644 (file)
@@ -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;
 }
 
index 5b4c67c..15004c4 100644 (file)
@@ -452,6 +452,7 @@ enum lock_type4 {
 #define FATTR4_WORD2_LAYOUT_BLKSIZE     (1UL << 1)
 #define FATTR4_WORD2_MDSTHRESHOLD       (1UL << 4)
 #define FATTR4_WORD2_CLONE_BLKSIZE     (1UL << 13)
+#define FATTR4_WORD2_CHANGE_ATTR_TYPE  (1UL << 15)
 #define FATTR4_WORD2_SECURITY_LABEL     (1UL << 16)
 #define FATTR4_WORD2_MODE_UMASK                (1UL << 17)
 #define FATTR4_WORD2_XATTR_SUPPORT     (1UL << 18)
@@ -709,6 +710,14 @@ struct nl4_server {
        } u;
 };
 
+enum nfs4_change_attr_type {
+       NFS4_CHANGE_TYPE_IS_MONOTONIC_INCR = 0,
+       NFS4_CHANGE_TYPE_IS_VERSION_COUNTER = 1,
+       NFS4_CHANGE_TYPE_IS_VERSION_COUNTER_NOPNFS = 2,
+       NFS4_CHANGE_TYPE_IS_TIME_METADATA = 3,
+       NFS4_CHANGE_TYPE_IS_UNDEFINED = 4,
+};
+
 /*
  * Options for setxattr. These match the flags for setxattr(2).
  */
index 6f76b32..fbcdfd9 100644 (file)
@@ -180,6 +180,9 @@ struct nfs_server {
 #define NFS_OPTION_FSCACHE     0x00000001      /* - local caching enabled */
 #define NFS_OPTION_MIGRATION   0x00000002      /* - NFSv4 migration enabled */
 
+       enum nfs4_change_attr_type
+                               change_attr_type;/* Description of change attribute */
+
        struct nfs_fsid         fsid;
        __u64                   maxfilesize;    /* maximum file size */
        struct timespec64       time_delta;     /* smallest time granularity */
index cc29dee..717ecc8 100644 (file)
@@ -152,6 +152,8 @@ struct nfs_fsinfo {
        __u32                   layouttype[NFS_MAX_LAYOUT_TYPES]; /* supported pnfs layout driver */
        __u32                   blksize; /* preferred pnfs io block size */
        __u32                   clone_blksize; /* granularity of a CLONE operation */
+       enum nfs4_change_attr_type
+                               change_attr_type; /* Info about change attr */
        __u32                   xattr_support; /* User xattrs supported */
 };