diff options
-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 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; | |||
112 | static void process_queued_ios(struct work_struct *work); | 113 | static void process_queued_ios(struct work_struct *work); |
113 | static void trigger_event(struct work_struct *work); | 114 | static void trigger_event(struct work_struct *work); |
114 | static void activate_path(struct work_struct *work); | 115 | static void activate_path(struct work_struct *work); |
116 | static 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 | ||
140 | static 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 | |||
136 | static struct priority_group *alloc_priority_group(void) | 148 | static 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 | ||
874 | out: | 887 | out: |
875 | spin_unlock_irqrestore(&m->lock, flags); | 888 | spin_unlock_irqrestore(&m->lock, flags); |