void nfs_client_impl::local_write_callback(error_code err, size_t sz, dsn::ref_ptr<copy_request_ex> reqc) { //dassert(reqc->local_write_task == task::get_current_task(), ""); --_concurrent_local_write_count; // clear all content to release memory quickly reqc->response.file_content = blob(); continue_write(); bool completed = false; if (err != ERR_OK) { completed = true; } else { zauto_lock l(reqc->file_ctx->user_req->user_req_lock); if (++reqc->file_ctx->finished_segments == (int)reqc->file_ctx->copy_requests.size()) { auto err = dsn_file_close(reqc->file_ctx->file); dassert(err == ERR_OK, "dsn_file_close failed, err = %s", dsn_error_to_string(err)); reqc->file_ctx->file = static_cast<dsn_handle_t>(0); reqc->file_ctx->copy_requests.clear(); if (++reqc->file_ctx->user_req->finished_files == (int)reqc->file_ctx->user_req->file_context_map.size()) { completed = true; } } } if (completed) { handle_completion(reqc->file_ctx->user_req, err); } }
void nfs_client_impl::handle_completion(user_request *req, error_code err) { { zauto_lock l(req->user_req_lock); if (req->is_finished) return; req->is_finished = true; } for (auto& f : req->file_context_map) { for (auto& rc : f.second->copy_requests) { ::dsn::task_ptr ctask, wtask; { zauto_lock l(rc->lock); rc->is_valid = false; ctask = rc->remote_copy_task; wtask = rc->local_write_task; rc->remote_copy_task = nullptr; rc->local_write_task = nullptr; } if (err != ERR_OK) { if (ctask != nullptr) { if (ctask->cancel(true)) { _concurrent_copy_request_count--; rc->release_ref(); } } if (wtask != nullptr) { if (wtask->cancel(true)) { _concurrent_local_write_count--; } } } } if (f.second->file) { auto err2 = dsn_file_close(f.second->file); dassert(err2 == ERR_OK, "dsn_file_close failed, err = %s", dsn_error_to_string(err2)); f.second->file = nullptr; if (f.second->finished_segments != (int)f.second->copy_requests.size()) { ::remove((f.second->user_req->file_size_req.dst_dir + f.second->file_name).c_str()); } f.second->copy_requests.clear(); } delete f.second; } req->file_context_map.clear(); req->nfs_task->enqueue(err, 0); delete req; // clear out all canceled requests if (err != ERR_OK) { continue_copy(0); continue_write(); } }