/* * Handle a request for MDS from another MDS. */ int slm_rmm_handler(struct pscrpc_request *rq) { int rc; rq->rq_status = SL_EXP_REGISTER_RESM(rq->rq_export, slm_getmcsvcx(_resm, rq->rq_export)); if (rq->rq_status) return (pscrpc_error(rq)); switch (rq->rq_reqmsg->opc) { case SRMT_CONNECT: rc = slrpc_handle_connect(rq, SRMM_MAGIC, SRMM_VERSION, SLCONNT_MDS); break; case SRMT_BATCH_RP: rc = sl_handle_batchrp(rq); break; case SRMT_NAMESPACE_UPDATE: rc = slm_rmm_handle_namespace_update(rq); break; case SRMT_NAMESPACE_FORWARD: rc = slm_rmm_handle_namespace_forward(rq); break; default: psclog_errorx("unexpected opcode %d", rq->rq_reqmsg->opc); rq->rq_status = -PFLERR_NOSYS; return (pscrpc_error(rq)); } slrpc_rep_out(rq); pscrpc_target_send_reply_msg(rq, rc, 0); return (rc); }
/** * rsx_bulkserver - Setup a source or sink for a server. * @rq: RPC request associated with GET. * @type: GET_SINK receive from client or PUT_SOURCE to push to a client. * @ptl: portal to issue bulk xfer across. * @iov: iovec array of receive buffer. * @n: #iovecs. * Returns: 0 or negative errno on error. */ int rsx_bulkserver(struct pscrpc_request *rq, int type, int ptl, struct iovec *iov, int n) { int sum, i, rc, comms_error; struct pscrpc_bulk_desc *desc; struct l_wait_info lwi; uint64_t *v8; uint8_t *v1; psc_assert(type == BULK_GET_SINK || type == BULK_PUT_SOURCE); desc = pscrpc_prep_bulk_exp(rq, n, type, ptl); if (desc == NULL) { psclog_warnx("pscrpc_prep_bulk_exp returned a null desc"); return (-ENOMEM); // XXX errno } desc->bd_nob = 0; desc->bd_iov_count = n; memcpy(desc->bd_iov, iov, n * sizeof(*iov)); for (i = 0; i < n; i++) desc->bd_nob += iov[i].iov_len; /* Check for client eviction during previous I/O before proceeding. */ if (desc->bd_export->exp_failed) rc = -ENOTCONN; else rc = pscrpc_start_bulk_transfer(desc); if (rc == 0) { lwi = LWI_TIMEOUT_INTERVAL(OBD_TIMEOUT / 2, 100, pfl_rsx_timeout, desc); rc = pscrpc_svr_wait_event(&desc->bd_waitq, (!pscrpc_bulk_active(desc) || desc->bd_export->exp_failed), &lwi, NULL); LASSERT(rc == 0 || rc == -ETIMEDOUT); if (rc == -ETIMEDOUT) { DEBUG_REQ(PLL_ERROR, rq, "timeout on bulk GET"); pscrpc_abort_bulk(desc); } else if (desc->bd_export->exp_failed) { DEBUG_REQ(PLL_ERROR, rq, "eviction on bulk GET"); rc = -ENOTCONN; pscrpc_abort_bulk(desc); } else if (!desc->bd_success || desc->bd_nob_transferred != desc->bd_nob) { DEBUG_REQ(PLL_ERROR, rq, "%s bulk GET %d(%d)", desc->bd_success ? "truncated" : "network error on", desc->bd_nob_transferred, desc->bd_nob); rc = -ETIMEDOUT; } } else { DEBUG_REQ(PLL_ERROR, rq, "pscrpc I/O bulk get failed: " "rc=%d", rc); } comms_error = (rc != 0); /* count the number of bytes received, and hold for later... */ if (rc == 0) { v1 = desc->bd_iov[0].iov_base; v8 = desc->bd_iov[0].iov_base; if (v1 == NULL) { DEBUG_REQ(PLL_ERROR, rq, "desc->bd_iov[0].iov_base is NULL"); rc = -ENXIO; goto out; } DEBUG_REQ(PLL_DIAG, rq, "got %u bytes of bulk data across %d IOVs: " "first byte is %#x (%"PRIx64")", desc->bd_nob, desc->bd_iov_count, *v1, *v8); sum = 0; for (i = 0; i < desc->bd_iov_count; i++) sum += desc->bd_iov[i].iov_len; if (sum != desc->bd_nob) DEBUG_REQ(PLL_WARN, rq, "sum (%d) does not match bd_nob (%d)", sum, desc->bd_nob); //rc = pscrpc_reply(rq); } out: if (rc == 0) ; else if (!comms_error) { /* Only reply if there were no comm problems with bulk. */ rq->rq_status = rc; pscrpc_error(rq); } else { #if 0 // For now let's not free the reply state.. if (rq->rq_reply_state != NULL) { /* reply out callback would free */ pscrpc_rs_decref(rq->rq_reply_state); rq->rq_reply_state = NULL; rq->rq_repmsg = NULL; } #endif DEBUG_REQ(PLL_WARN, rq, "ignoring bulk I/O comm error; " "id %s - client will retry", libcfs_id2str(rq->rq_peer)); } pscrpc_free_bulk(desc); return (rc); }