|
@@ -129,30 +129,26 @@ out_unlock:
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
|
|
|
|
-static ssize_t _nfs42_proc_copy(struct file *src, loff_t pos_src,
|
|
|
|
|
|
+static ssize_t _nfs42_proc_copy(struct file *src,
|
|
struct nfs_lock_context *src_lock,
|
|
struct nfs_lock_context *src_lock,
|
|
- struct file *dst, loff_t pos_dst,
|
|
|
|
|
|
+ struct file *dst,
|
|
struct nfs_lock_context *dst_lock,
|
|
struct nfs_lock_context *dst_lock,
|
|
- size_t count)
|
|
|
|
|
|
+ struct nfs42_copy_args *args,
|
|
|
|
+ struct nfs42_copy_res *res)
|
|
{
|
|
{
|
|
- struct nfs42_copy_args args = {
|
|
|
|
- .src_fh = NFS_FH(file_inode(src)),
|
|
|
|
- .src_pos = pos_src,
|
|
|
|
- .dst_fh = NFS_FH(file_inode(dst)),
|
|
|
|
- .dst_pos = pos_dst,
|
|
|
|
- .count = count,
|
|
|
|
- };
|
|
|
|
- struct nfs42_copy_res res;
|
|
|
|
struct rpc_message msg = {
|
|
struct rpc_message msg = {
|
|
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COPY],
|
|
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_COPY],
|
|
- .rpc_argp = &args,
|
|
|
|
- .rpc_resp = &res,
|
|
|
|
|
|
+ .rpc_argp = args,
|
|
|
|
+ .rpc_resp = res,
|
|
};
|
|
};
|
|
struct inode *dst_inode = file_inode(dst);
|
|
struct inode *dst_inode = file_inode(dst);
|
|
struct nfs_server *server = NFS_SERVER(dst_inode);
|
|
struct nfs_server *server = NFS_SERVER(dst_inode);
|
|
|
|
+ loff_t pos_src = args->src_pos;
|
|
|
|
+ loff_t pos_dst = args->dst_pos;
|
|
|
|
+ size_t count = args->count;
|
|
int status;
|
|
int status;
|
|
|
|
|
|
- status = nfs4_set_rw_stateid(&args.src_stateid, src_lock->open_context,
|
|
|
|
|
|
+ status = nfs4_set_rw_stateid(&args->src_stateid, src_lock->open_context,
|
|
src_lock, FMODE_READ);
|
|
src_lock, FMODE_READ);
|
|
if (status)
|
|
if (status)
|
|
return status;
|
|
return status;
|
|
@@ -162,7 +158,7 @@ static ssize_t _nfs42_proc_copy(struct file *src, loff_t pos_src,
|
|
if (status)
|
|
if (status)
|
|
return status;
|
|
return status;
|
|
|
|
|
|
- status = nfs4_set_rw_stateid(&args.dst_stateid, dst_lock->open_context,
|
|
|
|
|
|
+ status = nfs4_set_rw_stateid(&args->dst_stateid, dst_lock->open_context,
|
|
dst_lock, FMODE_WRITE);
|
|
dst_lock, FMODE_WRITE);
|
|
if (status)
|
|
if (status)
|
|
return status;
|
|
return status;
|
|
@@ -172,22 +168,22 @@ static ssize_t _nfs42_proc_copy(struct file *src, loff_t pos_src,
|
|
return status;
|
|
return status;
|
|
|
|
|
|
status = nfs4_call_sync(server->client, server, &msg,
|
|
status = nfs4_call_sync(server->client, server, &msg,
|
|
- &args.seq_args, &res.seq_res, 0);
|
|
|
|
|
|
+ &args->seq_args, &res->seq_res, 0);
|
|
if (status == -ENOTSUPP)
|
|
if (status == -ENOTSUPP)
|
|
server->caps &= ~NFS_CAP_COPY;
|
|
server->caps &= ~NFS_CAP_COPY;
|
|
if (status)
|
|
if (status)
|
|
return status;
|
|
return status;
|
|
|
|
|
|
- if (res.write_res.verifier.committed != NFS_FILE_SYNC) {
|
|
|
|
- status = nfs_commit_file(dst, &res.write_res.verifier.verifier);
|
|
|
|
|
|
+ if (res->write_res.verifier.committed != NFS_FILE_SYNC) {
|
|
|
|
+ status = nfs_commit_file(dst, &res->write_res.verifier.verifier);
|
|
if (status)
|
|
if (status)
|
|
return status;
|
|
return status;
|
|
}
|
|
}
|
|
|
|
|
|
truncate_pagecache_range(dst_inode, pos_dst,
|
|
truncate_pagecache_range(dst_inode, pos_dst,
|
|
- pos_dst + res.write_res.count);
|
|
|
|
|
|
+ pos_dst + res->write_res.count);
|
|
|
|
|
|
- return res.write_res.count;
|
|
|
|
|
|
+ return res->write_res.count;
|
|
}
|
|
}
|
|
|
|
|
|
ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,
|
|
ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,
|
|
@@ -197,8 +193,22 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,
|
|
struct nfs_server *server = NFS_SERVER(file_inode(dst));
|
|
struct nfs_server *server = NFS_SERVER(file_inode(dst));
|
|
struct nfs_lock_context *src_lock;
|
|
struct nfs_lock_context *src_lock;
|
|
struct nfs_lock_context *dst_lock;
|
|
struct nfs_lock_context *dst_lock;
|
|
- struct nfs4_exception src_exception = { };
|
|
|
|
- struct nfs4_exception dst_exception = { };
|
|
|
|
|
|
+ struct nfs42_copy_args args = {
|
|
|
|
+ .src_fh = NFS_FH(file_inode(src)),
|
|
|
|
+ .src_pos = pos_src,
|
|
|
|
+ .dst_fh = NFS_FH(file_inode(dst)),
|
|
|
|
+ .dst_pos = pos_dst,
|
|
|
|
+ .count = count,
|
|
|
|
+ };
|
|
|
|
+ struct nfs42_copy_res res;
|
|
|
|
+ struct nfs4_exception src_exception = {
|
|
|
|
+ .inode = file_inode(src),
|
|
|
|
+ .stateid = &args.src_stateid,
|
|
|
|
+ };
|
|
|
|
+ struct nfs4_exception dst_exception = {
|
|
|
|
+ .inode = file_inode(dst),
|
|
|
|
+ .stateid = &args.dst_stateid,
|
|
|
|
+ };
|
|
ssize_t err, err2;
|
|
ssize_t err, err2;
|
|
|
|
|
|
if (!nfs_server_capable(file_inode(dst), NFS_CAP_COPY))
|
|
if (!nfs_server_capable(file_inode(dst), NFS_CAP_COPY))
|
|
@@ -208,7 +218,6 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,
|
|
if (IS_ERR(src_lock))
|
|
if (IS_ERR(src_lock))
|
|
return PTR_ERR(src_lock);
|
|
return PTR_ERR(src_lock);
|
|
|
|
|
|
- src_exception.inode = file_inode(src);
|
|
|
|
src_exception.state = src_lock->open_context->state;
|
|
src_exception.state = src_lock->open_context->state;
|
|
|
|
|
|
dst_lock = nfs_get_lock_context(nfs_file_open_context(dst));
|
|
dst_lock = nfs_get_lock_context(nfs_file_open_context(dst));
|
|
@@ -217,15 +226,17 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,
|
|
goto out_put_src_lock;
|
|
goto out_put_src_lock;
|
|
}
|
|
}
|
|
|
|
|
|
- dst_exception.inode = file_inode(dst);
|
|
|
|
dst_exception.state = dst_lock->open_context->state;
|
|
dst_exception.state = dst_lock->open_context->state;
|
|
|
|
|
|
do {
|
|
do {
|
|
inode_lock(file_inode(dst));
|
|
inode_lock(file_inode(dst));
|
|
- err = _nfs42_proc_copy(src, pos_src, src_lock,
|
|
|
|
- dst, pos_dst, dst_lock, count);
|
|
|
|
|
|
+ err = _nfs42_proc_copy(src, src_lock,
|
|
|
|
+ dst, dst_lock,
|
|
|
|
+ &args, &res);
|
|
inode_unlock(file_inode(dst));
|
|
inode_unlock(file_inode(dst));
|
|
|
|
|
|
|
|
+ if (err >= 0)
|
|
|
|
+ break;
|
|
if (err == -ENOTSUPP) {
|
|
if (err == -ENOTSUPP) {
|
|
err = -EOPNOTSUPP;
|
|
err = -EOPNOTSUPP;
|
|
break;
|
|
break;
|