Пример #1
0
/*
 *  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);
}
Пример #2
0
/*
 * 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);
}
Пример #3
0
/*
 * 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);
}