Skip to content

Commit c14335e

Browse files
bvanasschemartinkpetersen
authored andcommitted
scsi: Revert "target/core: Inline transport_lun_remove_cmd()"
Commit 83f85b8 postponed the percpu_ref_put(&se_cmd->se_lun->lun_ref) call from command completion to the time when the final command reference is dropped. That approach is not compatible with the iSCSI target driver because the iSCSI target driver keeps the command with the highest stat_sn after it has completed until the next command is received (see also iscsit_ack_from_expstatsn()). Fix this regression by reverting commit 83f85b8. Fixes: 83f85b8 ("scsi: target/core: Inline transport_lun_remove_cmd()") Cc: Pavel Zakharov <[email protected]> Cc: Mike Christie <[email protected]> Cc: <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reported-by: Pavel Zakharov <[email protected]> Signed-off-by: Bart Van Assche <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent bb6d3fb commit c14335e

File tree

1 file changed

+28
-3
lines changed

1 file changed

+28
-3
lines changed

drivers/target/target_core_transport.c

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,11 @@ static int transport_cmd_check_stop_to_fabric(struct se_cmd *cmd)
666666

667667
target_remove_from_state_list(cmd);
668668

669+
/*
670+
* Clear struct se_cmd->se_lun before the handoff to FE.
671+
*/
672+
cmd->se_lun = NULL;
673+
669674
spin_lock_irqsave(&cmd->t_state_lock, flags);
670675
/*
671676
* Determine if frontend context caller is requesting the stopping of
@@ -693,6 +698,17 @@ static int transport_cmd_check_stop_to_fabric(struct se_cmd *cmd)
693698
return cmd->se_tfo->check_stop_free(cmd);
694699
}
695700

701+
static void transport_lun_remove_cmd(struct se_cmd *cmd)
702+
{
703+
struct se_lun *lun = cmd->se_lun;
704+
705+
if (!lun)
706+
return;
707+
708+
if (cmpxchg(&cmd->lun_ref_active, true, false))
709+
percpu_ref_put(&lun->lun_ref);
710+
}
711+
696712
static void target_complete_failure_work(struct work_struct *work)
697713
{
698714
struct se_cmd *cmd = container_of(work, struct se_cmd, work);
@@ -783,6 +799,8 @@ static void target_handle_abort(struct se_cmd *cmd)
783799

784800
WARN_ON_ONCE(kref_read(&cmd->cmd_kref) == 0);
785801

802+
transport_lun_remove_cmd(cmd);
803+
786804
transport_cmd_check_stop_to_fabric(cmd);
787805
}
788806

@@ -1708,6 +1726,7 @@ static void target_complete_tmr_failure(struct work_struct *work)
17081726
se_cmd->se_tmr_req->response = TMR_LUN_DOES_NOT_EXIST;
17091727
se_cmd->se_tfo->queue_tm_rsp(se_cmd);
17101728

1729+
transport_lun_remove_cmd(se_cmd);
17111730
transport_cmd_check_stop_to_fabric(se_cmd);
17121731
}
17131732

@@ -1898,6 +1917,7 @@ void transport_generic_request_failure(struct se_cmd *cmd,
18981917
goto queue_full;
18991918

19001919
check_stop:
1920+
transport_lun_remove_cmd(cmd);
19011921
transport_cmd_check_stop_to_fabric(cmd);
19021922
return;
19031923

@@ -2195,6 +2215,7 @@ static void transport_complete_qf(struct se_cmd *cmd)
21952215
transport_handle_queue_full(cmd, cmd->se_dev, ret, false);
21962216
return;
21972217
}
2218+
transport_lun_remove_cmd(cmd);
21982219
transport_cmd_check_stop_to_fabric(cmd);
21992220
}
22002221

@@ -2289,6 +2310,7 @@ static void target_complete_ok_work(struct work_struct *work)
22892310
if (ret)
22902311
goto queue_full;
22912312

2313+
transport_lun_remove_cmd(cmd);
22922314
transport_cmd_check_stop_to_fabric(cmd);
22932315
return;
22942316
}
@@ -2314,6 +2336,7 @@ static void target_complete_ok_work(struct work_struct *work)
23142336
if (ret)
23152337
goto queue_full;
23162338

2339+
transport_lun_remove_cmd(cmd);
23172340
transport_cmd_check_stop_to_fabric(cmd);
23182341
return;
23192342
}
@@ -2349,6 +2372,7 @@ static void target_complete_ok_work(struct work_struct *work)
23492372
if (ret)
23502373
goto queue_full;
23512374

2375+
transport_lun_remove_cmd(cmd);
23522376
transport_cmd_check_stop_to_fabric(cmd);
23532377
return;
23542378
}
@@ -2384,6 +2408,7 @@ static void target_complete_ok_work(struct work_struct *work)
23842408
break;
23852409
}
23862410

2411+
transport_lun_remove_cmd(cmd);
23872412
transport_cmd_check_stop_to_fabric(cmd);
23882413
return;
23892414

@@ -2710,6 +2735,9 @@ int transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks)
27102735
*/
27112736
if (cmd->state_active)
27122737
target_remove_from_state_list(cmd);
2738+
2739+
if (cmd->se_lun)
2740+
transport_lun_remove_cmd(cmd);
27132741
}
27142742
if (aborted)
27152743
cmd->free_compl = &compl;
@@ -2781,9 +2809,6 @@ static void target_release_cmd_kref(struct kref *kref)
27812809
struct completion *abrt_compl = se_cmd->abrt_compl;
27822810
unsigned long flags;
27832811

2784-
if (se_cmd->lun_ref_active)
2785-
percpu_ref_put(&se_cmd->se_lun->lun_ref);
2786-
27872812
if (se_sess) {
27882813
spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
27892814
list_del_init(&se_cmd->se_cmd_list);

0 commit comments

Comments
 (0)