Skip to content

Commit f05795d

Browse files
Johannes Thumshirnmartinkpetersen
Johannes Thumshirn
authored andcommitted
scsi: Add intermediate STARGET_REMOVE state to scsi_target_state
Add intermediate STARGET_REMOVE state to scsi_target_state to avoid running into the BUG_ON() in scsi_target_reap(). The STARGET_REMOVE state is only valid in the path from scsi_remove_target() to scsi_target_destroy() indicating this target is going to be removed. This re-fixes the problem introduced in commits bc3f02a ("[SCSI] scsi_remove_target: fix softlockup regression on hot remove") and 4099819 ("scsi: restart list search after unlock in scsi_remove_target") in a more comprehensive way. [mkp: Included James' fix for scsi_target_destroy()] Signed-off-by: Johannes Thumshirn <[email protected]> Fixes: 4099819 Cc: [email protected] Reported-by: Sergey Senozhatsky <[email protected]> Tested-by: Sergey Senozhatsky <[email protected]> Reviewed-by: Ewan D. Milne <[email protected]> Reviewed-by: Hannes Reinecke <[email protected]> Reviewed-by: James Bottomley <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent be2a266 commit f05795d

File tree

3 files changed

+4
-0
lines changed

3 files changed

+4
-0
lines changed

drivers/scsi/scsi_scan.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,7 @@ static void scsi_target_destroy(struct scsi_target *starget)
319319
struct Scsi_Host *shost = dev_to_shost(dev->parent);
320320
unsigned long flags;
321321

322+
BUG_ON(starget->state == STARGET_DEL);
322323
starget->state = STARGET_DEL;
323324
transport_destroy_device(dev);
324325
spin_lock_irqsave(shost->host_lock, flags);

drivers/scsi/scsi_sysfs.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1374,11 +1374,13 @@ void scsi_remove_target(struct device *dev)
13741374
spin_lock_irqsave(shost->host_lock, flags);
13751375
list_for_each_entry(starget, &shost->__targets, siblings) {
13761376
if (starget->state == STARGET_DEL ||
1377+
starget->state == STARGET_REMOVE ||
13771378
starget == last_target)
13781379
continue;
13791380
if (starget->dev.parent == dev || &starget->dev == dev) {
13801381
kref_get(&starget->reap_ref);
13811382
last_target = starget;
1383+
starget->state = STARGET_REMOVE;
13821384
spin_unlock_irqrestore(shost->host_lock, flags);
13831385
__scsi_remove_target(starget);
13841386
scsi_target_reap(starget);

include/scsi/scsi_device.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ scmd_printk(const char *, const struct scsi_cmnd *, const char *, ...);
248248
enum scsi_target_state {
249249
STARGET_CREATED = 1,
250250
STARGET_RUNNING,
251+
STARGET_REMOVE,
251252
STARGET_DEL,
252253
};
253254

0 commit comments

Comments
 (0)