NFS recover from destination server reboot for copies
Mark the destination state to indicate a server-side copy is happening. On detecting a reboot and recovering open state check if any state is engaged in a server-side copy, if so, find the copy and mark it and then signal the waiting thread. Upon wakeup, if copy was marked then propage EAGAIN to the nfsd_copy_file_range and restart the copy from scratch. Signed-off-by: Olga Kornievskaia <kolga@netapp.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
这个提交包含在:
@@ -140,6 +140,7 @@ static int handle_async_copy(struct nfs42_copy_res *res,
|
||||
struct nfs4_copy_state *copy;
|
||||
int status = NFS4_OK;
|
||||
bool found_pending = false;
|
||||
struct nfs_open_context *ctx = nfs_file_open_context(dst);
|
||||
|
||||
spin_lock(&server->nfs_client->cl_lock);
|
||||
list_for_each_entry(copy, &server->nfs_client->pending_cb_stateids,
|
||||
@@ -163,6 +164,7 @@ static int handle_async_copy(struct nfs42_copy_res *res,
|
||||
}
|
||||
memcpy(©->stateid, &res->write_res.stateid, NFS4_STATEID_SIZE);
|
||||
init_completion(©->completion);
|
||||
copy->parent_state = ctx->state;
|
||||
|
||||
list_add_tail(©->copies, &server->ss_copies);
|
||||
spin_unlock(&server->nfs_client->cl_lock);
|
||||
@@ -172,15 +174,20 @@ static int handle_async_copy(struct nfs42_copy_res *res,
|
||||
list_del_init(©->copies);
|
||||
spin_unlock(&server->nfs_client->cl_lock);
|
||||
if (status == -ERESTARTSYS) {
|
||||
nfs42_do_offload_cancel_async(dst, ©->stateid);
|
||||
kfree(copy);
|
||||
return status;
|
||||
goto out_cancel;
|
||||
} else if (copy->flags) {
|
||||
status = -EAGAIN;
|
||||
goto out_cancel;
|
||||
}
|
||||
out:
|
||||
res->write_res.count = copy->count;
|
||||
memcpy(&res->write_res.verifier, ©->verf, sizeof(copy->verf));
|
||||
status = -copy->error;
|
||||
|
||||
kfree(copy);
|
||||
return status;
|
||||
out_cancel:
|
||||
nfs42_do_offload_cancel_async(dst, ©->stateid);
|
||||
kfree(copy);
|
||||
return status;
|
||||
}
|
||||
@@ -254,6 +261,9 @@ static ssize_t _nfs42_proc_copy(struct file *src,
|
||||
if (!res->commit_res.verf)
|
||||
return -ENOMEM;
|
||||
}
|
||||
set_bit(NFS_CLNT_DST_SSC_COPY_STATE,
|
||||
&dst_lock->open_context->state->flags);
|
||||
|
||||
status = nfs4_call_sync(server->client, server, &msg,
|
||||
&args->seq_args, &res->seq_res, 0);
|
||||
if (status == -ENOTSUPP)
|
||||
|
在新工单中引用
屏蔽一个用户