/* * Client's outgoing request callback */ void request_out_callback(lnet_event_t *ev) { struct ptlrpc_cb_id *cbid = ev->md.user_ptr; struct ptlrpc_request *req = cbid->cbid_arg; LASSERT(ev->type == LNET_EVENT_SEND || ev->type == LNET_EVENT_UNLINK); LASSERT(ev->unlinked); DEBUG_REQ(D_NET, req, "type %d, status %d", ev->type, ev->status); sptlrpc_request_out_callback(req); req->rq_real_sent = cfs_time_current_sec(); if (ev->type == LNET_EVENT_UNLINK || ev->status != 0) { /* Failed send: make it seem like the reply timed out, just * like failing sends in client.c does currently... */ spin_lock(&req->rq_lock); req->rq_net_err = 1; spin_unlock(&req->rq_lock); ptlrpc_client_wake_req(req); } ptlrpc_req_finished(req); }
/* * Client's bulk has been written/read */ void client_bulk_callback(lnet_event_t *ev) { struct ptlrpc_cb_id *cbid = ev->md.user_ptr; struct ptlrpc_bulk_desc *desc = cbid->cbid_arg; struct ptlrpc_request *req; LASSERT((desc->bd_type == BULK_PUT_SINK && ev->type == LNET_EVENT_PUT) || (desc->bd_type == BULK_GET_SOURCE && ev->type == LNET_EVENT_GET) || ev->type == LNET_EVENT_UNLINK); LASSERT(ev->unlinked); if (CFS_FAIL_CHECK_ORSET(OBD_FAIL_PTLRPC_CLIENT_BULK_CB, CFS_FAIL_ONCE)) ev->status = -EIO; if (CFS_FAIL_CHECK_ORSET(OBD_FAIL_PTLRPC_CLIENT_BULK_CB2, CFS_FAIL_ONCE)) ev->status = -EIO; CDEBUG((ev->status == 0) ? D_NET : D_ERROR, "event type %d, status %d, desc %p\n", ev->type, ev->status, desc); spin_lock(&desc->bd_lock); req = desc->bd_req; LASSERT(desc->bd_md_count > 0); desc->bd_md_count--; if (ev->type != LNET_EVENT_UNLINK && ev->status == 0) { desc->bd_nob_transferred += ev->mlength; desc->bd_sender = ev->sender; } else { /* start reconnect and resend if network error hit */ spin_lock(&req->rq_lock); req->rq_net_err = 1; spin_unlock(&req->rq_lock); } if (ev->status != 0) desc->bd_failure = 1; /* NB don't unlock till after wakeup; desc can disappear under us * otherwise */ if (desc->bd_md_count == 0) ptlrpc_client_wake_req(desc->bd_req); spin_unlock(&desc->bd_lock); }
/* * Client's incoming reply callback */ void reply_in_callback(lnet_event_t *ev) { struct ptlrpc_cb_id *cbid = ev->md.user_ptr; struct ptlrpc_request *req = cbid->cbid_arg; DEBUG_REQ(D_NET, req, "type %d, status %d", ev->type, ev->status); LASSERT(ev->type == LNET_EVENT_PUT || ev->type == LNET_EVENT_UNLINK); LASSERT(ev->md.start == req->rq_repbuf); LASSERT(ev->offset + ev->mlength <= req->rq_repbuf_len); /* We've set LNET_MD_MANAGE_REMOTE for all outgoing requests for adaptive timeouts' early reply. */ LASSERT((ev->md.options & LNET_MD_MANAGE_REMOTE) != 0); spin_lock(&req->rq_lock); req->rq_receiving_reply = 0; req->rq_early = 0; if (ev->unlinked) req->rq_must_unlink = 0; if (ev->status) goto out_wake; if (ev->type == LNET_EVENT_UNLINK) { LASSERT(ev->unlinked); DEBUG_REQ(D_NET, req, "unlink"); goto out_wake; } if (ev->mlength < ev->rlength) { CDEBUG(D_RPCTRACE, "truncate req %p rpc %d - %d+%d\n", req, req->rq_replen, ev->rlength, ev->offset); req->rq_reply_truncate = 1; req->rq_replied = 1; req->rq_status = -EOVERFLOW; req->rq_nob_received = ev->rlength + ev->offset; goto out_wake; } if ((ev->offset == 0) && ((lustre_msghdr_get_flags(req->rq_reqmsg) & MSGHDR_AT_SUPPORT))) { /* Early reply */ DEBUG_REQ(D_ADAPTTO, req, "Early reply received: mlen=%u offset=%d replen=%d " "replied=%d unlinked=%d", ev->mlength, ev->offset, req->rq_replen, req->rq_replied, ev->unlinked); req->rq_early_count++; /* number received, client side */ if (req->rq_replied) /* already got the real reply */ goto out_wake; req->rq_early = 1; req->rq_reply_off = ev->offset; req->rq_nob_received = ev->mlength; /* And we're still receiving */ req->rq_receiving_reply = 1; } else { /* Real reply */ req->rq_rep_swab_mask = 0; req->rq_replied = 1; req->rq_reply_off = ev->offset; req->rq_nob_received = ev->mlength; /* LNetMDUnlink can't be called under the LNET_LOCK, so we must unlink in ptlrpc_unregister_reply */ DEBUG_REQ(D_INFO, req, "reply in flags=%x mlen=%u offset=%d replen=%d", lustre_msg_get_flags(req->rq_reqmsg), ev->mlength, ev->offset, req->rq_replen); } req->rq_import->imp_last_reply_time = cfs_time_current_sec(); out_wake: /* NB don't unlock till after wakeup; req can disappear under us * since we don't have our own ref */ ptlrpc_client_wake_req(req); spin_unlock(&req->rq_lock); }