diff options
Diffstat (limited to 'drivers/md/dm-mpath.c')
-rw-r--r-- | drivers/md/dm-mpath.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index b2ab8489d0e..103304c1e3b 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
@@ -34,6 +34,7 @@ struct pgpath { | |||
34 | unsigned fail_count; /* Cumulative failure count */ | 34 | unsigned fail_count; /* Cumulative failure count */ |
35 | 35 | ||
36 | struct dm_path path; | 36 | struct dm_path path; |
37 | struct work_struct deactivate_path; | ||
37 | }; | 38 | }; |
38 | 39 | ||
39 | #define path_to_pgpath(__pgp) container_of((__pgp), struct pgpath, path) | 40 | #define path_to_pgpath(__pgp) container_of((__pgp), struct pgpath, path) |
@@ -113,6 +114,7 @@ static struct workqueue_struct *kmultipathd, *kmpath_handlerd; | |||
113 | static void process_queued_ios(struct work_struct *work); | 114 | static void process_queued_ios(struct work_struct *work); |
114 | static void trigger_event(struct work_struct *work); | 115 | static void trigger_event(struct work_struct *work); |
115 | static void activate_path(struct work_struct *work); | 116 | static void activate_path(struct work_struct *work); |
117 | static void deactivate_path(struct work_struct *work); | ||
116 | 118 | ||
117 | 119 | ||
118 | /*----------------------------------------------- | 120 | /*----------------------------------------------- |
@@ -123,8 +125,10 @@ static struct pgpath *alloc_pgpath(void) | |||
123 | { | 125 | { |
124 | struct pgpath *pgpath = kzalloc(sizeof(*pgpath), GFP_KERNEL); | 126 | struct pgpath *pgpath = kzalloc(sizeof(*pgpath), GFP_KERNEL); |
125 | 127 | ||
126 | if (pgpath) | 128 | if (pgpath) { |
127 | pgpath->is_active = 1; | 129 | pgpath->is_active = 1; |
130 | INIT_WORK(&pgpath->deactivate_path, deactivate_path); | ||
131 | } | ||
128 | 132 | ||
129 | return pgpath; | 133 | return pgpath; |
130 | } | 134 | } |
@@ -134,6 +138,14 @@ static void free_pgpath(struct pgpath *pgpath) | |||
134 | kfree(pgpath); | 138 | kfree(pgpath); |
135 | } | 139 | } |
136 | 140 | ||
141 | static void deactivate_path(struct work_struct *work) | ||
142 | { | ||
143 | struct pgpath *pgpath = | ||
144 | container_of(work, struct pgpath, deactivate_path); | ||
145 | |||
146 | blk_abort_queue(pgpath->path.dev->bdev->bd_disk->queue); | ||
147 | } | ||
148 | |||
137 | static struct priority_group *alloc_priority_group(void) | 149 | static struct priority_group *alloc_priority_group(void) |
138 | { | 150 | { |
139 | struct priority_group *pg; | 151 | struct priority_group *pg; |
@@ -873,6 +885,7 @@ static int fail_path(struct pgpath *pgpath) | |||
873 | pgpath->path.dev->name, m->nr_valid_paths); | 885 | pgpath->path.dev->name, m->nr_valid_paths); |
874 | 886 | ||
875 | queue_work(kmultipathd, &m->trigger_event); | 887 | queue_work(kmultipathd, &m->trigger_event); |
888 | queue_work(kmultipathd, &pgpath->deactivate_path); | ||
876 | 889 | ||
877 | out: | 890 | out: |
878 | spin_unlock_irqrestore(&m->lock, flags); | 891 | spin_unlock_irqrestore(&m->lock, flags); |