nfs: get clone_blksize when probing fsinfo
authorPeng Tao <tao.peng@primarydata.com>
Fri, 25 Sep 2015 18:24:37 +0000 (02:24 +0800)
committerTrond Myklebust <trond.myklebust@primarydata.com>
Thu, 15 Oct 2015 20:08:18 +0000 (16:08 -0400)
NFSv42 CLONE operation is supposed to respect it.

Signed-off-by: Peng Tao <tao.peng@primarydata.com>
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
fs/nfs/client.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4xdr.c
include/linux/nfs4.h
include/linux/nfs_fs_sb.h
include/linux/nfs_xdr.h

index 57c5a02f6213e421cb3cfcdf2ba3a67b7141c6c6..d6d5d2a48e838f9b65b5fa71809afc3562c30e27 100644 (file)
@@ -764,6 +764,7 @@ static void nfs_server_set_fsinfo(struct nfs_server *server,
 
        server->time_delta = fsinfo->time_delta;
 
+       server->clone_blksize = fsinfo->clone_blksize;
        /* We're airborne Set socket buffersize */
        rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100);
 }
index 9688b1a9787f09cfe3a26d9279936736e64e6f3b..8814fbe626236fdfc21fb35de1d74e5757a82204 100644 (file)
@@ -239,6 +239,7 @@ const u32 nfs4_fsinfo_bitmap[3] = { FATTR4_WORD0_MAXFILESIZE
                        FATTR4_WORD1_TIME_DELTA
                        | FATTR4_WORD1_FS_LAYOUT_TYPES,
                        FATTR4_WORD2_LAYOUT_BLKSIZE
+                       | FATTR4_WORD2_CLONE_BLKSIZE
 };
 
 const u32 nfs4_fs_locations_bitmap[3] = {
index 868472b6b303b280bee69100077949d3bd6db698..9f656791a3389ed86695a3859d6f6424d67e16b9 100644 (file)
@@ -4764,6 +4764,28 @@ static int decode_attr_layout_blksize(struct xdr_stream *xdr, uint32_t *bitmap,
        return 0;
 }
 
+/*
+ * The granularity of a CLONE operation.
+ */
+static int decode_attr_clone_blksize(struct xdr_stream *xdr, uint32_t *bitmap,
+                                    uint32_t *res)
+{
+       __be32 *p;
+
+       dprintk("%s: bitmap is %x\n", __func__, bitmap[2]);
+       *res = 0;
+       if (bitmap[2] & FATTR4_WORD2_CLONE_BLKSIZE) {
+               p = xdr_inline_decode(xdr, 4);
+               if (unlikely(!p)) {
+                       print_overflow_msg(__func__, xdr);
+                       return -EIO;
+               }
+               *res = be32_to_cpup(p);
+               bitmap[2] &= ~FATTR4_WORD2_CLONE_BLKSIZE;
+       }
+       return 0;
+}
+
 static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo)
 {
        unsigned int savep;
@@ -4796,6 +4818,9 @@ static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo)
        if (status != 0)
                goto xdr_error;
        status = decode_attr_layout_blksize(xdr, bitmap, &fsinfo->blksize);
+       if (status)
+               goto xdr_error;
+       status = decode_attr_clone_blksize(xdr, bitmap, &fsinfo->clone_blksize);
        if (status)
                goto xdr_error;
 
index c0c695b634d0aac8030414fc650422b5edeb5353..e7e78537aea2cbeba658bc8591350961b089fa58 100644 (file)
@@ -422,6 +422,7 @@ enum lock_type4 {
 #define FATTR4_WORD2_LAYOUT_TYPES       (1UL << 0)
 #define FATTR4_WORD2_LAYOUT_BLKSIZE     (1UL << 1)
 #define FATTR4_WORD2_MDSTHRESHOLD       (1UL << 4)
+#define FATTR4_WORD2_CLONE_BLKSIZE     (1UL << 13)
 #define FATTR4_WORD2_SECURITY_LABEL     (1UL << 16)
 
 /* MDS threshold bitmap bits */
index a50de1002b2089960808676587f580d058604433..2469ab0bb3a1f0cf6aa2c947b3fc3dc614b93152 100644 (file)
@@ -147,6 +147,7 @@ struct nfs_server {
        unsigned int            acdirmax;
        unsigned int            namelen;
        unsigned int            options;        /* extra options enabled by mount */
+       unsigned int            clone_blksize;  /* granularity of a CLONE operation */
 #define NFS_OPTION_FSCACHE     0x00000001      /* - local caching enabled */
 #define NFS_OPTION_MIGRATION   0x00000002      /* - NFSv4 migration enabled */
 
index ac678b7a65ed8b5a04e1b7e29fa62fcefbe382e2..92ff445e60a06e27372ce62acd8e37179c1143cf 100644 (file)
@@ -141,6 +141,7 @@ struct nfs_fsinfo {
        __u32                   lease_time; /* in seconds */
        __u32                   layouttype; /* supported pnfs layout driver */
        __u32                   blksize; /* preferred pnfs io block size */
+       __u32                   clone_blksize; /* granularity of a CLONE operation */
 };
 
 struct nfs_fsstat {