Skip to content

Commit 5bfa25d

Browse files
igawSasha Levin
authored andcommitted
nvmet-fcloop: access fcpreq only when holding reqlock
[ Upstream commit 47a827c ] The abort handling logic expects that the state and the fcpreq are only accessed when holding the reqlock lock. While at it, only handle the aborts in the abort handler. Signed-off-by: Daniel Wagner <wagi@kernel.org> Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 1e2dda2 commit 5bfa25d

File tree

1 file changed

+16
-15
lines changed

1 file changed

+16
-15
lines changed

drivers/nvme/target/fcloop.c

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -618,12 +618,13 @@ fcloop_fcp_recv_work(struct work_struct *work)
618618
{
619619
struct fcloop_fcpreq *tfcp_req =
620620
container_of(work, struct fcloop_fcpreq, fcp_rcv_work);
621-
struct nvmefc_fcp_req *fcpreq = tfcp_req->fcpreq;
621+
struct nvmefc_fcp_req *fcpreq;
622622
unsigned long flags;
623623
int ret = 0;
624624
bool aborted = false;
625625

626626
spin_lock_irqsave(&tfcp_req->reqlock, flags);
627+
fcpreq = tfcp_req->fcpreq;
627628
switch (tfcp_req->inistate) {
628629
case INI_IO_START:
629630
tfcp_req->inistate = INI_IO_ACTIVE;
@@ -638,16 +639,19 @@ fcloop_fcp_recv_work(struct work_struct *work)
638639
}
639640
spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
640641

641-
if (unlikely(aborted))
642-
ret = -ECANCELED;
643-
else {
644-
if (likely(!check_for_drop(tfcp_req)))
645-
ret = nvmet_fc_rcv_fcp_req(tfcp_req->tport->targetport,
646-
&tfcp_req->tgt_fcp_req,
647-
fcpreq->cmdaddr, fcpreq->cmdlen);
648-
else
649-
pr_info("%s: dropped command ********\n", __func__);
642+
if (unlikely(aborted)) {
643+
/* the abort handler will call fcloop_call_host_done */
644+
return;
645+
}
646+
647+
if (unlikely(check_for_drop(tfcp_req))) {
648+
pr_info("%s: dropped command ********\n", __func__);
649+
return;
650650
}
651+
652+
ret = nvmet_fc_rcv_fcp_req(tfcp_req->tport->targetport,
653+
&tfcp_req->tgt_fcp_req,
654+
fcpreq->cmdaddr, fcpreq->cmdlen);
651655
if (ret)
652656
fcloop_call_host_done(fcpreq, tfcp_req, ret);
653657
}
@@ -662,9 +666,10 @@ fcloop_fcp_abort_recv_work(struct work_struct *work)
662666
unsigned long flags;
663667

664668
spin_lock_irqsave(&tfcp_req->reqlock, flags);
665-
fcpreq = tfcp_req->fcpreq;
666669
switch (tfcp_req->inistate) {
667670
case INI_IO_ABORTED:
671+
fcpreq = tfcp_req->fcpreq;
672+
tfcp_req->fcpreq = NULL;
668673
break;
669674
case INI_IO_COMPLETED:
670675
completed = true;
@@ -686,10 +691,6 @@ fcloop_fcp_abort_recv_work(struct work_struct *work)
686691
nvmet_fc_rcv_fcp_abort(tfcp_req->tport->targetport,
687692
&tfcp_req->tgt_fcp_req);
688693

689-
spin_lock_irqsave(&tfcp_req->reqlock, flags);
690-
tfcp_req->fcpreq = NULL;
691-
spin_unlock_irqrestore(&tfcp_req->reqlock, flags);
692-
693694
fcloop_call_host_done(fcpreq, tfcp_req, -ECANCELED);
694695
/* call_host_done releases reference for abort downcall */
695696
}

0 commit comments

Comments
 (0)