|
@@ -138,14 +138,31 @@ static int handle_async_copy(struct nfs42_copy_res *res,
|
|
{
|
|
{
|
|
struct nfs4_copy_state *copy;
|
|
struct nfs4_copy_state *copy;
|
|
int status = NFS4_OK;
|
|
int status = NFS4_OK;
|
|
|
|
+ bool found_pending = false;
|
|
|
|
+
|
|
|
|
+ spin_lock(&server->nfs_client->cl_lock);
|
|
|
|
+ list_for_each_entry(copy, &server->nfs_client->pending_cb_stateids,
|
|
|
|
+ copies) {
|
|
|
|
+ if (memcmp(&res->write_res.stateid, ©->stateid,
|
|
|
|
+ NFS4_STATEID_SIZE))
|
|
|
|
+ continue;
|
|
|
|
+ found_pending = true;
|
|
|
|
+ list_del(©->copies);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ if (found_pending) {
|
|
|
|
+ spin_unlock(&server->nfs_client->cl_lock);
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
|
|
copy = kzalloc(sizeof(struct nfs4_copy_state), GFP_NOFS);
|
|
copy = kzalloc(sizeof(struct nfs4_copy_state), GFP_NOFS);
|
|
- if (!copy)
|
|
|
|
|
|
+ if (!copy) {
|
|
|
|
+ spin_unlock(&server->nfs_client->cl_lock);
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
|
|
+ }
|
|
memcpy(©->stateid, &res->write_res.stateid, NFS4_STATEID_SIZE);
|
|
memcpy(©->stateid, &res->write_res.stateid, NFS4_STATEID_SIZE);
|
|
init_completion(©->completion);
|
|
init_completion(©->completion);
|
|
|
|
|
|
- spin_lock(&server->nfs_client->cl_lock);
|
|
|
|
list_add_tail(©->copies, &server->ss_copies);
|
|
list_add_tail(©->copies, &server->ss_copies);
|
|
spin_unlock(&server->nfs_client->cl_lock);
|
|
spin_unlock(&server->nfs_client->cl_lock);
|
|
|
|
|
|
@@ -153,6 +170,7 @@ static int handle_async_copy(struct nfs42_copy_res *res,
|
|
spin_lock(&server->nfs_client->cl_lock);
|
|
spin_lock(&server->nfs_client->cl_lock);
|
|
list_del_init(©->copies);
|
|
list_del_init(©->copies);
|
|
spin_unlock(&server->nfs_client->cl_lock);
|
|
spin_unlock(&server->nfs_client->cl_lock);
|
|
|
|
+out:
|
|
res->write_res.count = copy->count;
|
|
res->write_res.count = copy->count;
|
|
memcpy(&res->write_res.verifier, ©->verf, sizeof(copy->verf));
|
|
memcpy(&res->write_res.verifier, ©->verf, sizeof(copy->verf));
|
|
status = -copy->error;
|
|
status = -copy->error;
|