aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorMike Anderson <andmike@linux.vnet.ibm.com>2008-08-29 03:36:09 -0400
committerJens Axboe <jens.axboe@oracle.com>2008-10-09 02:56:14 -0400
commit224cb3e981f1b2f9f93dbd49eaef505d17d894c2 (patch)
tree41f2201e228a1cdb46430779deeaa474cedab7ed /drivers/md
parent11914a53d2ec2974a565311af327b8983d8c820d (diff)
dm: Call blk_abort_queue on failed paths
Signed-off-by: Mike Anderson <andmike@linux.vnet.ibm.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-mpath.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index c2fcf28b4c70..3d3848132c69 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -33,6 +33,7 @@ struct pgpath {
33 unsigned fail_count; /* Cumulative failure count */ 33 unsigned fail_count; /* Cumulative failure count */
34 34
35 struct dm_path path; 35 struct dm_path path;
36 struct work_struct deactivate_path;
36}; 37};
37 38
38#define path_to_pgpath(__pgp) container_of((__pgp), struct pgpath, path) 39#define path_to_pgpath(__pgp) container_of((__pgp), struct pgpath, path)
@@ -112,6 +113,7 @@ static struct workqueue_struct *kmultipathd, *kmpath_handlerd;
112static void process_queued_ios(struct work_struct *work); 113static void process_queued_ios(struct work_struct *work);
113static void trigger_event(struct work_struct *work); 114static void trigger_event(struct work_struct *work);
114static void activate_path(struct work_struct *work); 115static void activate_path(struct work_struct *work);
116static void deactivate_path(struct work_struct *work);
115 117
116 118
117/*----------------------------------------------- 119/*-----------------------------------------------
@@ -122,8 +124,10 @@ static struct pgpath *alloc_pgpath(void)
122{ 124{
123 struct pgpath *pgpath = kzalloc(sizeof(*pgpath), GFP_KERNEL); 125 struct pgpath *pgpath = kzalloc(sizeof(*pgpath), GFP_KERNEL);
124 126
125 if (pgpath) 127 if (pgpath) {
126 pgpath->path.is_active = 1; 128 pgpath->path.is_active = 1;
129 INIT_WORK(&pgpath->deactivate_path, deactivate_path);
130 }
127 131
128 return pgpath; 132 return pgpath;
129} 133}
@@ -133,6 +137,14 @@ static void free_pgpath(struct pgpath *pgpath)
133 kfree(pgpath); 137 kfree(pgpath);
134} 138}
135 139
140static void deactivate_path(struct work_struct *work)
141{
142 struct pgpath *pgpath =
143 container_of(work, struct pgpath, deactivate_path);
144
145 blk_abort_queue(pgpath->path.dev->bdev->bd_disk->queue);
146}
147
136static struct priority_group *alloc_priority_group(void) 148static struct priority_group *alloc_priority_group(void)
137{ 149{
138 struct priority_group *pg; 150 struct priority_group *pg;
@@ -870,6 +882,7 @@ static int fail_path(struct pgpath *pgpath)
870 pgpath->path.dev->name, m->nr_valid_paths); 882 pgpath->path.dev->name, m->nr_valid_paths);
871 883
872 queue_work(kmultipathd, &m->trigger_event); 884 queue_work(kmultipathd, &m->trigger_event);
885 queue_work(kmultipathd, &pgpath->deactivate_path);
873 886
874out: 887out:
875 spin_unlock_irqrestore(&m->lock, flags); 888 spin_unlock_irqrestore(&m->lock, flags);