Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
/**
 * 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);
}
Exemplo n.º 3
0
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);
}