@@ -1275,6 +1275,23 @@ static int nfsd4_do_async_copy(void *data)
goto out;
}
+struct nfsd4_copy *
+find_async_copy(struct nfs4_client *clp, stateid_t *stateid)
+{
+ struct nfsd4_copy *copy;
+
+ spin_lock(&clp->async_lock);
+ list_for_each_entry(copy, &clp->async_copies, copies) {
+ if (memcmp(©->cp_stateid, stateid, NFS4_STATEID_SIZE))
+ continue;
+ refcount_inc(©->refcount);
+ spin_unlock(&clp->async_lock);
+ return copy;
+ }
+ spin_unlock(&clp->async_lock);
+ return NULL;
+}
+
static __be32
nfsd4_offload_cancel(struct svc_rqst *rqstp,
struct nfsd4_compound_state *cstate,
@@ -1283,20 +1300,10 @@ static int nfsd4_do_async_copy(void *data)
struct nfsd4_offload_status *os = &u->offload_status;
__be32 status = 0;
struct nfsd4_copy *copy;
- bool found = false;
struct nfs4_client *clp = cstate->clp;
- spin_lock(&clp->async_lock);
- list_for_each_entry(copy, &clp->async_copies, copies) {
- if (memcmp(©->cp_stateid, &os->stateid,
- NFS4_STATEID_SIZE))
- continue;
- found = true;
- refcount_inc(©->refcount);
- break;
- }
- spin_unlock(&clp->async_lock);
- if (found) {
+ copy = find_async_copy(clp, &os->stateid);
+ if (copy) {
set_tsk_thread_flag(copy->copy_task, TIF_SIGPENDING);
kthread_stop(copy->copy_task);
nfs4_put_copy(copy);
@@ -1333,7 +1340,19 @@ static int nfsd4_do_async_copy(void *data)
struct nfsd4_compound_state *cstate,
union nfsd4_op_u *u)
{
- return nfserr_notsupp;
+ struct nfsd4_offload_status *os = &u->offload_status;
+ __be32 status = 0;
+ struct nfsd4_copy *copy;
+ struct nfs4_client *clp = cstate->clp;
+
+ copy = find_async_copy(clp, &os->stateid);
+ if (copy) {
+ os->count = copy->cp_res.wr_bytes_written;
+ nfs4_put_copy(copy);
+ } else
+ status = nfserr_bad_stateid;
+
+ return status;
}
static __be32
@@ -642,6 +642,8 @@ extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(const char *name,
struct nfs4_file *find_file(struct knfsd_fh *fh);
void put_nfs4_file(struct nfs4_file *fi);
extern void nfs4_put_copy(struct nfsd4_copy *copy);
+extern struct nfsd4_copy *
+find_async_copy(struct nfs4_client *clp, stateid_t *staetid);
static inline void get_nfs4_file(struct nfs4_file *fi)
{
refcount_inc(&fi->fi_ref);
Search the list for the asynchronous copy based on the stateid, then lookup the number of bytes copied so far. Signed-off-by: Olga Kornievskaia <kolga@netapp.com> --- fs/nfsd/nfs4proc.c | 45 ++++++++++++++++++++++++++++++++------------- fs/nfsd/state.h | 2 ++ 2 files changed, 34 insertions(+), 13 deletions(-)