NFS: add COPY_NOTIFY operation

Try using the delegation stateid, then the open stateid.

Only NL4_NETATTR, No support for NL4_NAME and NL4_URL.
Allow only one source server address to be returned for now.

To distinguish between same server copy offload ("intra") and
a copy between different server ("inter"), do a check of server
owner identity and also make sure server is capable of doing
a copy offload.

Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
This commit is contained in:
Olga Kornievskaia
2019-06-04 16:14:30 -04:00
committed by Olga Kornievskaia
parent f9bdad8ca8
commit 0491567b51
11 changed files with 323 additions and 2 deletions

View File

@@ -133,6 +133,9 @@ static ssize_t __nfs4_copy_file_range(struct file *file_in, loff_t pos_in,
struct file *file_out, loff_t pos_out,
size_t count, unsigned int flags)
{
struct nfs42_copy_notify_res *cn_resp = NULL;
ssize_t ret;
/* Only offload copy if superblock is the same */
if (file_inode(file_in)->i_sb != file_inode(file_out)->i_sb)
return -EXDEV;
@@ -140,7 +143,22 @@ static ssize_t __nfs4_copy_file_range(struct file *file_in, loff_t pos_in,
return -EOPNOTSUPP;
if (file_inode(file_in) == file_inode(file_out))
return -EOPNOTSUPP;
return nfs42_proc_copy(file_in, pos_in, file_out, pos_out, count);
if (!nfs42_files_from_same_server(file_in, file_out)) {
cn_resp = kzalloc(sizeof(struct nfs42_copy_notify_res),
GFP_NOFS);
if (unlikely(cn_resp == NULL))
return -ENOMEM;
ret = nfs42_proc_copy_notify(file_in, file_out, cn_resp);
if (ret) {
ret = -EOPNOTSUPP;
goto out;
}
}
ret = nfs42_proc_copy(file_in, pos_in, file_out, pos_out, count);
out:
kfree(cn_resp);
return ret;
}
static ssize_t nfs4_copy_file_range(struct file *file_in, loff_t pos_in,