NFSv4.2: query the server for extended attribute support
authorFrank van der Linden <fllinden@amazon.com>
Tue, 23 Jun 2020 22:38:55 +0000 (22:38 +0000)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Mon, 13 Jul 2020 21:52:45 +0000 (17:52 -0400)
Query the server for extended attribute support, and record it
as the NFS_CAP_XATTR flag in the server capabilities.

Signed-off-by: Frank van der Linden <fllinden@amazon.com>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
fs/nfs/client.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4xdr.c
include/linux/nfs_fs_sb.h
include/linux/nfs_xdr.h

index 055040b..4b8cc93 100644 (file)
@@ -809,6 +809,9 @@ static void nfs_server_set_fsinfo(struct nfs_server *server,
                                XATTR_SIZE_MAX);
        server->lxasize = min_t(unsigned int, raw_max_rpc_payload,
                                nfs42_listxattr_xdrsize(XATTR_LIST_MAX));
+
+       if (fsinfo->xattr_support)
+               server->caps |= NFS_CAP_XATTR;
 #endif
 }
 
index e32717f..64e0814 100644 (file)
@@ -256,6 +256,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_XATTR_SUPPORT
 };
 
 const u32 nfs4_fs_locations_bitmap[3] = {
@@ -3740,7 +3741,7 @@ static void nfs4_close_context(struct nfs_open_context *ctx, int is_sync)
 
 #define FATTR4_WORD1_NFS40_MASK (2*FATTR4_WORD1_MOUNTED_ON_FILEID - 1UL)
 #define FATTR4_WORD2_NFS41_MASK (2*FATTR4_WORD2_SUPPATTR_EXCLCREAT - 1UL)
-#define FATTR4_WORD2_NFS42_MASK (2*FATTR4_WORD2_MODE_UMASK - 1UL)
+#define FATTR4_WORD2_NFS42_MASK (2*FATTR4_WORD2_XATTR_SUPPORT - 1UL)
 
 static int _nfs4_server_capabilities(struct nfs_server *server, struct nfs_fh *fhandle)
 {
index 47817ef..9e1b076 100644 (file)
@@ -4201,6 +4201,26 @@ static int decode_attr_time_modify(struct xdr_stream *xdr, uint32_t *bitmap, str
        return status;
 }
 
+static int decode_attr_xattrsupport(struct xdr_stream *xdr, uint32_t *bitmap,
+                                   uint32_t *res)
+{
+       __be32 *p;
+
+       *res = 0;
+       if (unlikely(bitmap[2] & (FATTR4_WORD2_XATTR_SUPPORT - 1U)))
+               return -EIO;
+       if (likely(bitmap[2] & FATTR4_WORD2_XATTR_SUPPORT)) {
+               p = xdr_inline_decode(xdr, 4);
+               if (unlikely(!p))
+                       return -EIO;
+               *res = be32_to_cpup(p);
+               bitmap[2] &= ~FATTR4_WORD2_XATTR_SUPPORT;
+       }
+       dprintk("%s: XATTR support=%s\n", __func__,
+               *res == 0 ? "false" : "true");
+       return 0;
+}
+
 static int verify_attr_len(struct xdr_stream *xdr, unsigned int savep, uint32_t attrlen)
 {
        unsigned int attrwords = XDR_QUADLEN(attrlen);
@@ -4855,6 +4875,11 @@ static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo)
        if (status)
                goto xdr_error;
 
+       status = decode_attr_xattrsupport(xdr, bitmap,
+                                         &fsinfo->xattr_support);
+       if (status)
+               goto xdr_error;
+
        status = verify_attr_len(xdr, savep, attrlen);
 xdr_error:
        dprintk("%s: xdr returned %d!\n", __func__, -status);
index 128e01a..7eae72a 100644 (file)
@@ -286,5 +286,6 @@ struct nfs_server {
 #define NFS_CAP_OFFLOAD_CANCEL (1U << 25)
 #define NFS_CAP_LAYOUTERROR    (1U << 26)
 #define NFS_CAP_COPY_NOTIFY    (1U << 27)
+#define NFS_CAP_XATTR          (1U << 28)
 
 #endif
index 5fd0a9e..dee9b1c 100644 (file)
@@ -150,6 +150,7 @@ 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 */
+       __u32                   xattr_support; /* User xattrs supported */
 };
 
 struct nfs_fsstat {