aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-mpath.c16
-rw-r--r--drivers/md/dm.c12
2 files changed, 23 insertions, 5 deletions
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 71dd65aa31b6..c2fcf28b4c70 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -63,6 +63,7 @@ struct multipath {
63 63
64 const char *hw_handler_name; 64 const char *hw_handler_name;
65 struct work_struct activate_path; 65 struct work_struct activate_path;
66 struct pgpath *pgpath_to_activate;
66 unsigned nr_priority_groups; 67 unsigned nr_priority_groups;
67 struct list_head priority_groups; 68 struct list_head priority_groups;
68 unsigned pg_init_required; /* pg_init needs calling? */ 69 unsigned pg_init_required; /* pg_init needs calling? */
@@ -146,6 +147,7 @@ static struct priority_group *alloc_priority_group(void)
146 147
147static void free_pgpaths(struct list_head *pgpaths, struct dm_target *ti) 148static void free_pgpaths(struct list_head *pgpaths, struct dm_target *ti)
148{ 149{
150 unsigned long flags;
149 struct pgpath *pgpath, *tmp; 151 struct pgpath *pgpath, *tmp;
150 struct multipath *m = ti->private; 152 struct multipath *m = ti->private;
151 153
@@ -154,6 +156,10 @@ static void free_pgpaths(struct list_head *pgpaths, struct dm_target *ti)
154 if (m->hw_handler_name) 156 if (m->hw_handler_name)
155 scsi_dh_detach(bdev_get_queue(pgpath->path.dev->bdev)); 157 scsi_dh_detach(bdev_get_queue(pgpath->path.dev->bdev));
156 dm_put_device(ti, pgpath->path.dev); 158 dm_put_device(ti, pgpath->path.dev);
159 spin_lock_irqsave(&m->lock, flags);
160 if (m->pgpath_to_activate == pgpath)
161 m->pgpath_to_activate = NULL;
162 spin_unlock_irqrestore(&m->lock, flags);
157 free_pgpath(pgpath); 163 free_pgpath(pgpath);
158 } 164 }
159} 165}
@@ -421,6 +427,7 @@ static void process_queued_ios(struct work_struct *work)
421 __choose_pgpath(m); 427 __choose_pgpath(m);
422 428
423 pgpath = m->current_pgpath; 429 pgpath = m->current_pgpath;
430 m->pgpath_to_activate = m->current_pgpath;
424 431
425 if ((pgpath && !m->queue_io) || 432 if ((pgpath && !m->queue_io) ||
426 (!pgpath && !m->queue_if_no_path)) 433 (!pgpath && !m->queue_if_no_path))
@@ -1093,8 +1100,15 @@ static void activate_path(struct work_struct *work)
1093 int ret; 1100 int ret;
1094 struct multipath *m = 1101 struct multipath *m =
1095 container_of(work, struct multipath, activate_path); 1102 container_of(work, struct multipath, activate_path);
1096 struct dm_path *path = &m->current_pgpath->path; 1103 struct dm_path *path;
1104 unsigned long flags;
1097 1105
1106 spin_lock_irqsave(&m->lock, flags);
1107 path = &m->pgpath_to_activate->path;
1108 m->pgpath_to_activate = NULL;
1109 spin_unlock_irqrestore(&m->lock, flags);
1110 if (!path)
1111 return;
1098 ret = scsi_dh_activate(bdev_get_queue(path->dev->bdev)); 1112 ret = scsi_dh_activate(bdev_get_queue(path->dev->bdev));
1099 pg_init_done(path, ret); 1113 pg_init_done(path, ret);
1100} 1114}
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index bca448e11878..ace998ce59f6 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -837,12 +837,14 @@ static int dm_merge_bvec(struct request_queue *q,
837 struct dm_table *map = dm_get_table(md); 837 struct dm_table *map = dm_get_table(md);
838 struct dm_target *ti; 838 struct dm_target *ti;
839 sector_t max_sectors; 839 sector_t max_sectors;
840 int max_size; 840 int max_size = 0;
841 841
842 if (unlikely(!map)) 842 if (unlikely(!map))
843 return 0; 843 goto out;
844 844
845 ti = dm_table_find_target(map, bvm->bi_sector); 845 ti = dm_table_find_target(map, bvm->bi_sector);
846 if (!dm_target_is_valid(ti))
847 goto out_table;
846 848
847 /* 849 /*
848 * Find maximum amount of I/O that won't need splitting 850 * Find maximum amount of I/O that won't need splitting
@@ -861,14 +863,16 @@ static int dm_merge_bvec(struct request_queue *q,
861 if (max_size && ti->type->merge) 863 if (max_size && ti->type->merge)
862 max_size = ti->type->merge(ti, bvm, biovec, max_size); 864 max_size = ti->type->merge(ti, bvm, biovec, max_size);
863 865
866out_table:
867 dm_table_put(map);
868
869out:
864 /* 870 /*
865 * Always allow an entire first page 871 * Always allow an entire first page
866 */ 872 */
867 if (max_size <= biovec->bv_len && !(bvm->bi_size >> SECTOR_SHIFT)) 873 if (max_size <= biovec->bv_len && !(bvm->bi_size >> SECTOR_SHIFT))
868 max_size = biovec->bv_len; 874 max_size = biovec->bv_len;
869 875
870 dm_table_put(map);
871
872 return max_size; 876 return max_size;
873} 877}
874 878