diff options
author | Mike Snitzer <snitzer@redhat.com> | 2018-03-12 20:30:43 -0400 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2018-03-13 15:09:56 -0400 |
commit | c37366742baa2bb3225be507d283baef151c5f8a (patch) | |
tree | 9526b900d1fe467562bf53d368703a2a3ee8450a | |
parent | 0c8efd610b58cb23cefdfa12015799079aef94ae (diff) |
dm mpath: fix uninitialized 'pg_init_wait' waitqueue_head NULL pointer
Initialize all the scsi_dh related 'struct multipath' members regardless
of whether a scsi_dh is in use or not.
The subtle (and fragile) SCSI-assuming legacy code clearly needs further
decoupling from non-SCSI (and/or developer understanding).
Fixes: 8d47e65948dd ("dm mpath: remove unnecessary NVMe branching in favor of scsi_dh checks")
Reported-by: Bart Van Assche <bart.vanassche@wdc.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
-rw-r--r-- | drivers/md/dm-mpath.c | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 3fde9e9faddd..87c404eebe9f 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
@@ -223,6 +223,16 @@ static int alloc_multipath_stage2(struct dm_target *ti, struct multipath *m) | |||
223 | 223 | ||
224 | dm_table_set_type(ti->table, m->queue_mode); | 224 | dm_table_set_type(ti->table, m->queue_mode); |
225 | 225 | ||
226 | /* | ||
227 | * Init fields that are only used when a scsi_dh is attached | ||
228 | * - must do this unconditionally (really doesn't hurt non-SCSI uses) | ||
229 | */ | ||
230 | set_bit(MPATHF_QUEUE_IO, &m->flags); | ||
231 | atomic_set(&m->pg_init_in_progress, 0); | ||
232 | atomic_set(&m->pg_init_count, 0); | ||
233 | m->pg_init_delay_msecs = DM_PG_INIT_DELAY_DEFAULT; | ||
234 | init_waitqueue_head(&m->pg_init_wait); | ||
235 | |||
226 | return 0; | 236 | return 0; |
227 | } | 237 | } |
228 | 238 | ||
@@ -331,7 +341,6 @@ static void __switch_pg(struct multipath *m, struct priority_group *pg) | |||
331 | set_bit(MPATHF_PG_INIT_REQUIRED, &m->flags); | 341 | set_bit(MPATHF_PG_INIT_REQUIRED, &m->flags); |
332 | set_bit(MPATHF_QUEUE_IO, &m->flags); | 342 | set_bit(MPATHF_QUEUE_IO, &m->flags); |
333 | } else { | 343 | } else { |
334 | /* FIXME: not needed if no scsi_dh is attached */ | ||
335 | clear_bit(MPATHF_PG_INIT_REQUIRED, &m->flags); | 344 | clear_bit(MPATHF_PG_INIT_REQUIRED, &m->flags); |
336 | clear_bit(MPATHF_QUEUE_IO, &m->flags); | 345 | clear_bit(MPATHF_QUEUE_IO, &m->flags); |
337 | } | 346 | } |
@@ -823,16 +832,6 @@ retain: | |||
823 | */ | 832 | */ |
824 | kfree(m->hw_handler_name); | 833 | kfree(m->hw_handler_name); |
825 | m->hw_handler_name = attached_handler_name; | 834 | m->hw_handler_name = attached_handler_name; |
826 | |||
827 | /* | ||
828 | * Init fields that are only used when a scsi_dh is attached | ||
829 | */ | ||
830 | if (!test_and_set_bit(MPATHF_QUEUE_IO, &m->flags)) { | ||
831 | atomic_set(&m->pg_init_in_progress, 0); | ||
832 | atomic_set(&m->pg_init_count, 0); | ||
833 | m->pg_init_delay_msecs = DM_PG_INIT_DELAY_DEFAULT; | ||
834 | init_waitqueue_head(&m->pg_init_wait); | ||
835 | } | ||
836 | } | 835 | } |
837 | } | 836 | } |
838 | 837 | ||