int out_tx_end(const struct lu_env *env, struct thandle_exec_args *ta) { struct tgt_session_info *tsi = tgt_ses_info(env); int i = 0, rc; LASSERT(ta->ta_dev); LASSERT(ta->ta_handle); if (ta->ta_err != 0 || ta->ta_argno == 0) GOTO(stop, rc = ta->ta_err); rc = out_trans_start(env, ta); if (unlikely(rc)) GOTO(stop, rc); for (i = 0; i < ta->ta_argno; i++) { rc = ta->ta_args[i].exec_fn(env, ta->ta_handle, &ta->ta_args[i]); if (unlikely(rc != 0)) { CDEBUG(D_INFO, "error during execution of #%u from" " %s:%d: rc = %d\n", i, ta->ta_args[i].file, ta->ta_args[i].line, rc); while (--i >= 0) { if (ta->ta_args[i].undo_fn != NULL) ta->ta_args[i].undo_fn(env, ta->ta_handle, &ta->ta_args[i]); else CERROR("%s: undo for %s:%d: rc = %d\n", dt_obd_name(ta->ta_dev), ta->ta_args[i].file, ta->ta_args[i].line, -ENOTSUPP); } break; } } /* Only fail for real update */ tsi->tsi_reply_fail_id = OBD_FAIL_OUT_UPDATE_NET_REP; stop: CDEBUG(D_INFO, "%s: executed %u/%u: rc = %d\n", dt_obd_name(ta->ta_dev), i, ta->ta_argno, rc); out_trans_stop(env, ta, rc); ta->ta_handle = NULL; ta->ta_argno = 0; ta->ta_err = 0; RETURN(rc); }
/** * Prepare bulk IO requests for processing. * * This function does initial checks of IO and calls corresponding * functions for read/write processing. * * \param[in] env execution environment * \param[in] cmd IO type (read/write) * \param[in] exp OBD export of client * \param[in] oa OBDO structure from request * \param[in] objcount always 1 * \param[in] obj object data * \param[in] rnb remote buffers * \param[in] nr_local number of local buffers * \param[in] lnb local buffers * * \retval 0 on successful prepare * \retval negative value on error */ int ofd_preprw(const struct lu_env *env, int cmd, struct obd_export *exp, struct obdo *oa, int objcount, struct obd_ioobj *obj, struct niobuf_remote *rnb, int *nr_local, struct niobuf_local *lnb) { struct tgt_session_info *tsi = tgt_ses_info(env); struct ofd_device *ofd = ofd_exp(exp); struct ofd_thread_info *info; char *jobid; const struct lu_fid *fid = &oa->o_oi.oi_fid; int rc = 0; if (*nr_local > PTLRPC_MAX_BRW_PAGES) { CERROR("%s: bulk has too many pages %d, which exceeds the" "maximum pages per RPC of %d\n", exp->exp_obd->obd_name, *nr_local, PTLRPC_MAX_BRW_PAGES); RETURN(-EPROTO); } if (tgt_ses_req(tsi) == NULL) { /* echo client case */ info = ofd_info_init(env, exp); jobid = NULL; } else { info = tsi2ofd_info(tsi); jobid = tsi->tsi_jobid; } LASSERT(oa != NULL); if (OBD_FAIL_CHECK(OBD_FAIL_SRV_ENOENT)) { struct ofd_seq *oseq; oseq = ofd_seq_load(env, ofd, ostid_seq(&oa->o_oi)); if (IS_ERR(oseq)) { CERROR("%s: Can not find seq for "DOSTID ": rc = %ld\n", ofd_name(ofd), POSTID(&oa->o_oi), PTR_ERR(oseq)); RETURN(-EINVAL); } if (oseq->os_destroys_in_progress == 0) { /* don't fail lookups for orphan recovery, it causes * later LBUGs when objects still exist during * precreate */ ofd_seq_put(env, oseq); RETURN(-ENOENT); } ofd_seq_put(env, oseq); } LASSERT(objcount == 1); LASSERT(obj->ioo_bufcnt > 0); if (cmd == OBD_BRW_WRITE) { la_from_obdo(&info->fti_attr, oa, OBD_MD_FLGETATTR); rc = ofd_preprw_write(env, exp, ofd, fid, &info->fti_attr, oa, objcount, obj, rnb, nr_local, lnb, jobid); } else if (cmd == OBD_BRW_READ) { ofd_grant_prepare_read(env, exp, oa); rc = ofd_preprw_read(env, exp, ofd, fid, &info->fti_attr, oa, obj->ioo_bufcnt, rnb, nr_local, lnb, jobid); obdo_from_la(oa, &info->fti_attr, LA_ATIME); } else { CERROR("%s: wrong cmd %d received!\n", exp->exp_obd->obd_name, cmd); rc = -EPROTO; } RETURN(rc); }
static int out_tx_end(const struct lu_env *env, struct thandle_exec_args *ta, int declare_ret) { struct tgt_session_info *tsi = tgt_ses_info(env); int i; int rc; int rc1; ENTRY; if (ta->ta_handle == NULL) RETURN(0); if (declare_ret != 0 || ta->ta_argno == 0) GOTO(stop, rc = declare_ret); LASSERT(ta->ta_handle->th_dev != NULL); rc = out_trans_start(env, ta); if (unlikely(rc != 0)) GOTO(stop, rc); for (i = 0; i < ta->ta_argno; i++) { rc = ta->ta_args[i]->exec_fn(env, ta->ta_handle, ta->ta_args[i]); if (unlikely(rc != 0)) { CDEBUG(D_INFO, "error during execution of #%u from" " %s:%d: rc = %d\n", i, ta->ta_args[i]->file, ta->ta_args[i]->line, rc); while (--i >= 0) { if (ta->ta_args[i]->undo_fn != NULL) ta->ta_args[i]->undo_fn(env, ta->ta_handle, ta->ta_args[i]); else CERROR("%s: undo for %s:%d: rc = %d\n", dt_obd_name(ta->ta_handle->th_dev), ta->ta_args[i]->file, ta->ta_args[i]->line, -ENOTSUPP); } break; } CDEBUG(D_INFO, "%s: executed %u/%u: rc = %d\n", dt_obd_name(ta->ta_handle->th_dev), i, ta->ta_argno, rc); } /* Only fail for real updates, XXX right now llog updates will be * ignore, whose updates count is usually 1, so failover test * case will spot this FAIL_UPDATE_NET_REP precisely, and it will * be removed after async update patch is landed. */ if (ta->ta_argno > 1) tsi->tsi_reply_fail_id = OBD_FAIL_OUT_UPDATE_NET_REP; stop: rc1 = out_trans_stop(env, ta, rc); if (rc == 0) rc = rc1; ta->ta_handle = NULL; ta->ta_argno = 0; RETURN(rc); }