Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a0421da4 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull target fixes from Nicholas Bellinger:
 "Pull two tcm_fc fabric related fixes for -rc2:

  Note that both have been CC'ed to stable, and patch #1 is the
  important one that addresses a memory corruption bug related to FC
  exchange timeouts + command abort.

  Thanks again to MDR for tracking down this issue!"

* '3.4-rc-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending:
  tcm_fc: Do not free tpg structure during wq allocation failure
  tcm_fc: Add abort flag for gracefully handling exchange timeout
parents 4157368e 06383f10
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -122,6 +122,7 @@ struct ft_cmd {
	/* Local sense buffer */
	unsigned char ft_sense_buffer[TRANSPORT_SENSE_BUFFER];
	u32 was_ddp_setup:1;		/* Set only if ddp is setup */
	u32 aborted:1;			/* Set if aborted by reset or timeout */
	struct scatterlist *sg;		/* Set only if DDP is setup */
	u32 sg_cnt;			/* No. of item in scatterlist */
};
+8 −2
Original line number Diff line number Diff line
@@ -121,6 +121,8 @@ int ft_queue_status(struct se_cmd *se_cmd)
	struct fc_exch *ep;
	size_t len;

	if (cmd->aborted)
		return 0;
	ft_dump_cmd(cmd, __func__);
	ep = fc_seq_exch(cmd->seq);
	lport = ep->lp;
@@ -187,6 +189,8 @@ int ft_write_pending(struct se_cmd *se_cmd)

	ft_dump_cmd(cmd, __func__);

	if (cmd->aborted)
		return 0;
	ep = fc_seq_exch(cmd->seq);
	lport = ep->lp;
	fp = fc_frame_alloc(lport, sizeof(*txrdy));
@@ -252,10 +256,10 @@ static void ft_recv_seq(struct fc_seq *sp, struct fc_frame *fp, void *arg)
	struct ft_cmd *cmd = arg;
	struct fc_frame_header *fh;

	if (IS_ERR(fp)) {
	if (unlikely(IS_ERR(fp))) {
		/* XXX need to find cmd if queued */
		cmd->seq = NULL;
		transport_generic_free_cmd(&cmd->se_cmd, 0);
		cmd->aborted = true;
		return;
	}

@@ -399,6 +403,8 @@ int ft_queue_tm_resp(struct se_cmd *se_cmd)
	struct se_tmr_req *tmr = se_cmd->se_tmr_req;
	enum fcp_resp_rsp_codes code;

	if (cmd->aborted)
		return 0;
	switch (tmr->response) {
	case TMR_FUNCTION_COMPLETE:
		code = FCP_TMF_CMPL;
+8 −5
Original line number Diff line number Diff line
@@ -300,6 +300,7 @@ static struct se_portal_group *ft_add_tpg(
{
	struct ft_lport_acl *lacl;
	struct ft_tpg *tpg;
	struct workqueue_struct *wq;
	unsigned long index;
	int ret;

@@ -321,18 +322,20 @@ static struct se_portal_group *ft_add_tpg(
	tpg->lport_acl = lacl;
	INIT_LIST_HEAD(&tpg->lun_list);

	ret = core_tpg_register(&ft_configfs->tf_ops, wwn, &tpg->se_tpg,
				tpg, TRANSPORT_TPG_TYPE_NORMAL);
	if (ret < 0) {
	wq = alloc_workqueue("tcm_fc", 0, 1);
	if (!wq) {
		kfree(tpg);
		return NULL;
	}

	tpg->workqueue = alloc_workqueue("tcm_fc", 0, 1);
	if (!tpg->workqueue) {
	ret = core_tpg_register(&ft_configfs->tf_ops, wwn, &tpg->se_tpg,
				tpg, TRANSPORT_TPG_TYPE_NORMAL);
	if (ret < 0) {
		destroy_workqueue(wq);
		kfree(tpg);
		return NULL;
	}
	tpg->workqueue = wq;

	mutex_lock(&ft_lport_lock);
	list_add_tail(&tpg->list, &lacl->tpg_list);
+2 −0
Original line number Diff line number Diff line
@@ -81,6 +81,8 @@ int ft_queue_data_in(struct se_cmd *se_cmd)
	void *from;
	void *to = NULL;

	if (cmd->aborted)
		return 0;
	ep = fc_seq_exch(cmd->seq);
	lport = ep->lp;
	cmd->seq = lport->tt.seq_start_next(cmd->seq);