NFS: add ca_source_server<> to COPY
authorOlga Kornievskaia <kolga@netapp.com>
Tue, 4 Jun 2019 15:54:18 +0000 (11:54 -0400)
committerOlga Kornievskaia <olga.kornievskaia@gmail.com>
Wed, 9 Oct 2019 16:05:49 +0000 (12:05 -0400)
Support only one source server address: the same address that
the client and source server use.

Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
fs/nfs/nfs42.h
fs/nfs/nfs42proc.c
fs/nfs/nfs42xdr.c
fs/nfs/nfs4file.c
include/linux/nfs_xdr.h

index 4995731..02e3810 100644 (file)
@@ -15,7 +15,8 @@
 /* nfs4.2proc.c */
 #ifdef CONFIG_NFS_V4_2
 int nfs42_proc_allocate(struct file *, loff_t, loff_t);
-ssize_t nfs42_proc_copy(struct file *, loff_t, struct file *, loff_t, size_t);
+ssize_t nfs42_proc_copy(struct file *, loff_t, struct file *, loff_t, size_t,
+                       struct nl4_server *, nfs4_stateid *);
 int nfs42_proc_deallocate(struct file *, loff_t, loff_t);
 loff_t nfs42_proc_llseek(struct file *, loff_t, int);
 int nfs42_proc_layoutstats_generic(struct nfs_server *,
index 6317dd8..e34ade8 100644 (file)
@@ -243,7 +243,9 @@ static ssize_t _nfs42_proc_copy(struct file *src,
                                struct file *dst,
                                struct nfs_lock_context *dst_lock,
                                struct nfs42_copy_args *args,
-                               struct nfs42_copy_res *res)
+                               struct nfs42_copy_res *res,
+                               struct nl4_server *nss,
+                               nfs4_stateid *cnr_stateid)
 {
        struct rpc_message msg = {
                .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COPY],
@@ -257,11 +259,15 @@ static ssize_t _nfs42_proc_copy(struct file *src,
        size_t count = args->count;
        ssize_t status;
 
-       status = nfs4_set_rw_stateid(&args->src_stateid, src_lock->open_context,
-                                    src_lock, FMODE_READ);
-       if (status)
-               return status;
-
+       if (nss) {
+               args->cp_src = nss;
+               nfs4_stateid_copy(&args->src_stateid, cnr_stateid);
+       } else {
+               status = nfs4_set_rw_stateid(&args->src_stateid,
+                               src_lock->open_context, src_lock, FMODE_READ);
+               if (status)
+                       return status;
+       }
        status = nfs_filemap_write_and_wait_range(file_inode(src)->i_mapping,
                        pos_src, pos_src + (loff_t)count - 1);
        if (status)
@@ -325,8 +331,9 @@ out:
 }
 
 ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,
-                       struct file *dst, loff_t pos_dst,
-                       size_t count)
+                       struct file *dst, loff_t pos_dst, size_t count,
+                       struct nl4_server *nss,
+                       nfs4_stateid *cnr_stateid)
 {
        struct nfs_server *server = NFS_SERVER(file_inode(dst));
        struct nfs_lock_context *src_lock;
@@ -368,7 +375,8 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,
                inode_lock(file_inode(dst));
                err = _nfs42_proc_copy(src, src_lock,
                                dst, dst_lock,
-                               &args, &res);
+                               &args, &res,
+                               nss, cnr_stateid);
                inode_unlock(file_inode(dst));
 
                if (err >= 0)
index ccabc0c..c03f324 100644 (file)
 #define encode_copy_maxsz              (op_encode_hdr_maxsz +          \
                                         XDR_QUADLEN(NFS4_STATEID_SIZE) + \
                                         XDR_QUADLEN(NFS4_STATEID_SIZE) + \
-                                        2 + 2 + 2 + 1 + 1 + 1)
+                                        2 + 2 + 2 + 1 + 1 + 1 +\
+                                        1 + /* One cnr_source_server */\
+                                        1 + /* nl4_type */ \
+                                        1 + XDR_QUADLEN(NFS4_OPAQUE_LIMIT))
 #define decode_copy_maxsz              (op_decode_hdr_maxsz + \
                                         NFS42_WRITE_RES_SIZE + \
                                         1 /* cr_consecutive */ + \
@@ -216,7 +219,12 @@ static void encode_copy(struct xdr_stream *xdr,
 
        encode_uint32(xdr, 1); /* consecutive = true */
        encode_uint32(xdr, args->sync);
-       encode_uint32(xdr, 0); /* src server list */
+       if (args->cp_src == NULL) { /* intra-ssc */
+               encode_uint32(xdr, 0); /* no src server list */
+               return;
+       }
+       encode_uint32(xdr, 1); /* supporting 1 server */
+       encode_nl4_server(xdr, args->cp_src);
 }
 
 static void encode_offload_cancel(struct xdr_stream *xdr,
index 686a6c4..b68b41b 100644 (file)
@@ -134,6 +134,8 @@ static ssize_t __nfs4_copy_file_range(struct file *file_in, loff_t pos_in,
                                      size_t count, unsigned int flags)
 {
        struct nfs42_copy_notify_res *cn_resp = NULL;
+       struct nl4_server *nss = NULL;
+       nfs4_stateid *cnrs = NULL;
        ssize_t ret;
 
        /* Only offload copy if superblock is the same */
@@ -154,8 +156,11 @@ static ssize_t __nfs4_copy_file_range(struct file *file_in, loff_t pos_in,
                        ret = -EOPNOTSUPP;
                        goto out;
                }
+               nss = &cn_resp->cnr_src;
+               cnrs = &cn_resp->cnr_stateid;
        }
-       ret = nfs42_proc_copy(file_in, pos_in, file_out, pos_out, count);
+       ret = nfs42_proc_copy(file_in, pos_in, file_out, pos_out, count,
+                               nss, cnrs);
 out:
        kfree(cn_resp);
        return ret;
index 0a7af40..008faca 100644 (file)
@@ -1435,6 +1435,7 @@ struct nfs42_copy_args {
 
        u64                             count;
        bool                            sync;
+       struct nl4_server               *cp_src;
 };
 
 struct nfs42_write_res {