aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBart Van Assche <bart.vanassche@sandisk.com>2017-03-17 20:02:02 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2017-03-19 13:16:17 -0400
commit7cb689fe42927281b8d98606ae5450173fcc66a9 (patch)
tree802764e7495d034b88a3868e6e23d1c4d75e6bfa
parent625fe857e4fac6518716f3c0ff5e5deb8ec6d238 (diff)
scsi: scsi_dh_alua: Ensure that alua_activate() calls the completion function
Callers of scsi_dh_activate(), e.g. dm-mpath, assume that this function either returns an error code or calls the completion function. Make alua_activate() call the completion function even if scsi_device_get() fails. Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com> Cc: Hannes Reinecke <hare@suse.de> Cc: Tang Junhui <tang.junhui@zte.com.cn> Cc: <stable@vger.kernel.org> Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/device_handler/scsi_dh_alua.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index e0b15f3dd303..b6849d3ecefe 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -113,7 +113,7 @@ struct alua_queue_data {
113#define ALUA_POLICY_SWITCH_ALL 1 113#define ALUA_POLICY_SWITCH_ALL 1
114 114
115static void alua_rtpg_work(struct work_struct *work); 115static void alua_rtpg_work(struct work_struct *work);
116static void alua_rtpg_queue(struct alua_port_group *pg, 116static bool alua_rtpg_queue(struct alua_port_group *pg,
117 struct scsi_device *sdev, 117 struct scsi_device *sdev,
118 struct alua_queue_data *qdata, bool force); 118 struct alua_queue_data *qdata, bool force);
119static void alua_check(struct scsi_device *sdev, bool force); 119static void alua_check(struct scsi_device *sdev, bool force);
@@ -862,7 +862,13 @@ static void alua_rtpg_work(struct work_struct *work)
862 kref_put(&pg->kref, release_port_group); 862 kref_put(&pg->kref, release_port_group);
863} 863}
864 864
865static void alua_rtpg_queue(struct alua_port_group *pg, 865/**
866 * alua_rtpg_queue() - cause RTPG to be submitted asynchronously
867 *
868 * Returns true if and only if alua_rtpg_work() will be called asynchronously.
869 * That function is responsible for calling @qdata->fn().
870 */
871static bool alua_rtpg_queue(struct alua_port_group *pg,
866 struct scsi_device *sdev, 872 struct scsi_device *sdev,
867 struct alua_queue_data *qdata, bool force) 873 struct alua_queue_data *qdata, bool force)
868{ 874{
@@ -871,7 +877,7 @@ static void alua_rtpg_queue(struct alua_port_group *pg,
871 struct workqueue_struct *alua_wq = kaluad_wq; 877 struct workqueue_struct *alua_wq = kaluad_wq;
872 878
873 if (!pg || scsi_device_get(sdev)) 879 if (!pg || scsi_device_get(sdev))
874 return; 880 return false;
875 881
876 spin_lock_irqsave(&pg->lock, flags); 882 spin_lock_irqsave(&pg->lock, flags);
877 if (qdata) { 883 if (qdata) {
@@ -907,6 +913,8 @@ static void alua_rtpg_queue(struct alua_port_group *pg,
907 } 913 }
908 if (sdev) 914 if (sdev)
909 scsi_device_put(sdev); 915 scsi_device_put(sdev);
916
917 return true;
910} 918}
911 919
912/* 920/*
@@ -1007,11 +1015,13 @@ static int alua_activate(struct scsi_device *sdev,
1007 mutex_unlock(&h->init_mutex); 1015 mutex_unlock(&h->init_mutex);
1008 goto out; 1016 goto out;
1009 } 1017 }
1010 fn = NULL;
1011 rcu_read_unlock(); 1018 rcu_read_unlock();
1012 mutex_unlock(&h->init_mutex); 1019 mutex_unlock(&h->init_mutex);
1013 1020
1014 alua_rtpg_queue(pg, sdev, qdata, true); 1021 if (alua_rtpg_queue(pg, sdev, qdata, true))
1022 fn = NULL;
1023 else
1024 err = SCSI_DH_DEV_OFFLINED;
1015 kref_put(&pg->kref, release_port_group); 1025 kref_put(&pg->kref, release_port_group);
1016out: 1026out:
1017 if (fn) 1027 if (fn)