scsi: scsi_transport_fc: return -EBUSY for deleted vport
authorHannes Reinecke <hare@suse.de>
Mon, 24 Jul 2017 10:09:36 +0000 (12:09 +0200)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 25 Jul 2017 02:17:30 +0000 (22:17 -0400)
When trying to delete a vport via 'vport_delete' sysfs attribute we
should be checking if the port is already in state VPORT_DELETING; if so
there's no need to do anything.

Signed-off-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/scsi_transport_fc.c

index 7e24aa30c3b05b487130b028d4aa5688d3f7b6cf..892fbd9800d986a8dba22efac7ac4803be2c5f17 100644 (file)
@@ -1286,7 +1286,7 @@ store_fc_vport_delete(struct device *dev, struct device_attribute *attr,
        unsigned long flags;
 
        spin_lock_irqsave(shost->host_lock, flags);
-       if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) {
+       if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING | FC_VPORT_DELETING)) {
                spin_unlock_irqrestore(shost->host_lock, flags);
                return -EBUSY;
        }
@@ -2430,8 +2430,10 @@ fc_remove_host(struct Scsi_Host *shost)
        spin_lock_irqsave(shost->host_lock, flags);
 
        /* Remove any vports */
-       list_for_each_entry_safe(vport, next_vport, &fc_host->vports, peers)
+       list_for_each_entry_safe(vport, next_vport, &fc_host->vports, peers) {
+               vport->flags |= FC_VPORT_DELETING;
                fc_queue_work(shost, &vport->vport_delete_work);
+       }
 
        /* Remove any remote ports */
        list_for_each_entry_safe(rport, next_rport,