aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/multipath.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /drivers/md/multipath.c
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'drivers/md/multipath.c')
-rw-r--r--drivers/md/multipath.c80
1 files changed, 39 insertions, 41 deletions
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 1642eae75a3..d5b5fb30017 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -20,7 +20,6 @@
20 */ 20 */
21 21
22#include <linux/blkdev.h> 22#include <linux/blkdev.h>
23#include <linux/module.h>
24#include <linux/raid/md_u.h> 23#include <linux/raid/md_u.h>
25#include <linux/seq_file.h> 24#include <linux/seq_file.h>
26#include <linux/slab.h> 25#include <linux/slab.h>
@@ -32,7 +31,7 @@
32#define NR_RESERVED_BUFS 32 31#define NR_RESERVED_BUFS 32
33 32
34 33
35static int multipath_map (struct mpconf *conf) 34static int multipath_map (multipath_conf_t *conf)
36{ 35{
37 int i, disks = conf->raid_disks; 36 int i, disks = conf->raid_disks;
38 37
@@ -43,7 +42,7 @@ static int multipath_map (struct mpconf *conf)
43 42
44 rcu_read_lock(); 43 rcu_read_lock();
45 for (i = 0; i < disks; i++) { 44 for (i = 0; i < disks; i++) {
46 struct md_rdev *rdev = rcu_dereference(conf->multipaths[i].rdev); 45 mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev);
47 if (rdev && test_bit(In_sync, &rdev->flags)) { 46 if (rdev && test_bit(In_sync, &rdev->flags)) {
48 atomic_inc(&rdev->nr_pending); 47 atomic_inc(&rdev->nr_pending);
49 rcu_read_unlock(); 48 rcu_read_unlock();
@@ -59,8 +58,8 @@ static int multipath_map (struct mpconf *conf)
59static void multipath_reschedule_retry (struct multipath_bh *mp_bh) 58static void multipath_reschedule_retry (struct multipath_bh *mp_bh)
60{ 59{
61 unsigned long flags; 60 unsigned long flags;
62 struct mddev *mddev = mp_bh->mddev; 61 mddev_t *mddev = mp_bh->mddev;
63 struct mpconf *conf = mddev->private; 62 multipath_conf_t *conf = mddev->private;
64 63
65 spin_lock_irqsave(&conf->device_lock, flags); 64 spin_lock_irqsave(&conf->device_lock, flags);
66 list_add(&mp_bh->retry_list, &conf->retry_list); 65 list_add(&mp_bh->retry_list, &conf->retry_list);
@@ -77,7 +76,7 @@ static void multipath_reschedule_retry (struct multipath_bh *mp_bh)
77static void multipath_end_bh_io (struct multipath_bh *mp_bh, int err) 76static void multipath_end_bh_io (struct multipath_bh *mp_bh, int err)
78{ 77{
79 struct bio *bio = mp_bh->master_bio; 78 struct bio *bio = mp_bh->master_bio;
80 struct mpconf *conf = mp_bh->mddev->private; 79 multipath_conf_t *conf = mp_bh->mddev->private;
81 80
82 bio_endio(bio, err); 81 bio_endio(bio, err);
83 mempool_free(mp_bh, conf->pool); 82 mempool_free(mp_bh, conf->pool);
@@ -87,8 +86,8 @@ static void multipath_end_request(struct bio *bio, int error)
87{ 86{
88 int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); 87 int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
89 struct multipath_bh *mp_bh = bio->bi_private; 88 struct multipath_bh *mp_bh = bio->bi_private;
90 struct mpconf *conf = mp_bh->mddev->private; 89 multipath_conf_t *conf = mp_bh->mddev->private;
91 struct md_rdev *rdev = conf->multipaths[mp_bh->path].rdev; 90 mdk_rdev_t *rdev = conf->multipaths[mp_bh->path].rdev;
92 91
93 if (uptodate) 92 if (uptodate)
94 multipath_end_bh_io(mp_bh, 0); 93 multipath_end_bh_io(mp_bh, 0);
@@ -107,15 +106,15 @@ static void multipath_end_request(struct bio *bio, int error)
107 rdev_dec_pending(rdev, conf->mddev); 106 rdev_dec_pending(rdev, conf->mddev);
108} 107}
109 108
110static void multipath_make_request(struct mddev *mddev, struct bio * bio) 109static int multipath_make_request(mddev_t *mddev, struct bio * bio)
111{ 110{
112 struct mpconf *conf = mddev->private; 111 multipath_conf_t *conf = mddev->private;
113 struct multipath_bh * mp_bh; 112 struct multipath_bh * mp_bh;
114 struct multipath_info *multipath; 113 struct multipath_info *multipath;
115 114
116 if (unlikely(bio->bi_rw & REQ_FLUSH)) { 115 if (unlikely(bio->bi_rw & REQ_FLUSH)) {
117 md_flush_request(mddev, bio); 116 md_flush_request(mddev, bio);
118 return; 117 return 0;
119 } 118 }
120 119
121 mp_bh = mempool_alloc(conf->pool, GFP_NOIO); 120 mp_bh = mempool_alloc(conf->pool, GFP_NOIO);
@@ -127,7 +126,7 @@ static void multipath_make_request(struct mddev *mddev, struct bio * bio)
127 if (mp_bh->path < 0) { 126 if (mp_bh->path < 0) {
128 bio_endio(bio, -EIO); 127 bio_endio(bio, -EIO);
129 mempool_free(mp_bh, conf->pool); 128 mempool_free(mp_bh, conf->pool);
130 return; 129 return 0;
131 } 130 }
132 multipath = conf->multipaths + mp_bh->path; 131 multipath = conf->multipaths + mp_bh->path;
133 132
@@ -138,12 +137,12 @@ static void multipath_make_request(struct mddev *mddev, struct bio * bio)
138 mp_bh->bio.bi_end_io = multipath_end_request; 137 mp_bh->bio.bi_end_io = multipath_end_request;
139 mp_bh->bio.bi_private = mp_bh; 138 mp_bh->bio.bi_private = mp_bh;
140 generic_make_request(&mp_bh->bio); 139 generic_make_request(&mp_bh->bio);
141 return; 140 return 0;
142} 141}
143 142
144static void multipath_status (struct seq_file *seq, struct mddev *mddev) 143static void multipath_status (struct seq_file *seq, mddev_t *mddev)
145{ 144{
146 struct mpconf *conf = mddev->private; 145 multipath_conf_t *conf = mddev->private;
147 int i; 146 int i;
148 147
149 seq_printf (seq, " [%d/%d] [", conf->raid_disks, 148 seq_printf (seq, " [%d/%d] [", conf->raid_disks,
@@ -157,8 +156,8 @@ static void multipath_status (struct seq_file *seq, struct mddev *mddev)
157 156
158static int multipath_congested(void *data, int bits) 157static int multipath_congested(void *data, int bits)
159{ 158{
160 struct mddev *mddev = data; 159 mddev_t *mddev = data;
161 struct mpconf *conf = mddev->private; 160 multipath_conf_t *conf = mddev->private;
162 int i, ret = 0; 161 int i, ret = 0;
163 162
164 if (mddev_congested(mddev, bits)) 163 if (mddev_congested(mddev, bits))
@@ -166,7 +165,7 @@ static int multipath_congested(void *data, int bits)
166 165
167 rcu_read_lock(); 166 rcu_read_lock();
168 for (i = 0; i < mddev->raid_disks ; i++) { 167 for (i = 0; i < mddev->raid_disks ; i++) {
169 struct md_rdev *rdev = rcu_dereference(conf->multipaths[i].rdev); 168 mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev);
170 if (rdev && !test_bit(Faulty, &rdev->flags)) { 169 if (rdev && !test_bit(Faulty, &rdev->flags)) {
171 struct request_queue *q = bdev_get_queue(rdev->bdev); 170 struct request_queue *q = bdev_get_queue(rdev->bdev);
172 171
@@ -184,9 +183,9 @@ static int multipath_congested(void *data, int bits)
184/* 183/*
185 * Careful, this can execute in IRQ contexts as well! 184 * Careful, this can execute in IRQ contexts as well!
186 */ 185 */
187static void multipath_error (struct mddev *mddev, struct md_rdev *rdev) 186static void multipath_error (mddev_t *mddev, mdk_rdev_t *rdev)
188{ 187{
189 struct mpconf *conf = mddev->private; 188 multipath_conf_t *conf = mddev->private;
190 char b[BDEVNAME_SIZE]; 189 char b[BDEVNAME_SIZE];
191 190
192 if (conf->raid_disks - mddev->degraded <= 1) { 191 if (conf->raid_disks - mddev->degraded <= 1) {
@@ -219,7 +218,7 @@ static void multipath_error (struct mddev *mddev, struct md_rdev *rdev)
219 conf->raid_disks - mddev->degraded); 218 conf->raid_disks - mddev->degraded);
220} 219}
221 220
222static void print_multipath_conf (struct mpconf *conf) 221static void print_multipath_conf (multipath_conf_t *conf)
223{ 222{
224 int i; 223 int i;
225 struct multipath_info *tmp; 224 struct multipath_info *tmp;
@@ -243,9 +242,9 @@ static void print_multipath_conf (struct mpconf *conf)
243} 242}
244 243
245 244
246static int multipath_add_disk(struct mddev *mddev, struct md_rdev *rdev) 245static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
247{ 246{
248 struct mpconf *conf = mddev->private; 247 multipath_conf_t *conf = mddev->private;
249 struct request_queue *q; 248 struct request_queue *q;
250 int err = -EEXIST; 249 int err = -EEXIST;
251 int path; 250 int path;
@@ -292,16 +291,17 @@ static int multipath_add_disk(struct mddev *mddev, struct md_rdev *rdev)
292 return err; 291 return err;
293} 292}
294 293
295static int multipath_remove_disk(struct mddev *mddev, struct md_rdev *rdev) 294static int multipath_remove_disk(mddev_t *mddev, int number)
296{ 295{
297 struct mpconf *conf = mddev->private; 296 multipath_conf_t *conf = mddev->private;
298 int err = 0; 297 int err = 0;
299 int number = rdev->raid_disk; 298 mdk_rdev_t *rdev;
300 struct multipath_info *p = conf->multipaths + number; 299 struct multipath_info *p = conf->multipaths + number;
301 300
302 print_multipath_conf(conf); 301 print_multipath_conf(conf);
303 302
304 if (rdev == p->rdev) { 303 rdev = p->rdev;
304 if (rdev) {
305 if (test_bit(In_sync, &rdev->flags) || 305 if (test_bit(In_sync, &rdev->flags) ||
306 atomic_read(&rdev->nr_pending)) { 306 atomic_read(&rdev->nr_pending)) {
307 printk(KERN_ERR "hot-remove-disk, slot %d is identified" 307 printk(KERN_ERR "hot-remove-disk, slot %d is identified"
@@ -335,13 +335,12 @@ abort:
335 * 3. Performs writes following reads for array syncronising. 335 * 3. Performs writes following reads for array syncronising.
336 */ 336 */
337 337
338static void multipathd(struct md_thread *thread) 338static void multipathd (mddev_t *mddev)
339{ 339{
340 struct mddev *mddev = thread->mddev;
341 struct multipath_bh *mp_bh; 340 struct multipath_bh *mp_bh;
342 struct bio *bio; 341 struct bio *bio;
343 unsigned long flags; 342 unsigned long flags;
344 struct mpconf *conf = mddev->private; 343 multipath_conf_t *conf = mddev->private;
345 struct list_head *head = &conf->retry_list; 344 struct list_head *head = &conf->retry_list;
346 345
347 md_check_recovery(mddev); 346 md_check_recovery(mddev);
@@ -380,7 +379,7 @@ static void multipathd(struct md_thread *thread)
380 spin_unlock_irqrestore(&conf->device_lock, flags); 379 spin_unlock_irqrestore(&conf->device_lock, flags);
381} 380}
382 381
383static sector_t multipath_size(struct mddev *mddev, sector_t sectors, int raid_disks) 382static sector_t multipath_size(mddev_t *mddev, sector_t sectors, int raid_disks)
384{ 383{
385 WARN_ONCE(sectors || raid_disks, 384 WARN_ONCE(sectors || raid_disks,
386 "%s does not support generic reshape\n", __func__); 385 "%s does not support generic reshape\n", __func__);
@@ -388,12 +387,12 @@ static sector_t multipath_size(struct mddev *mddev, sector_t sectors, int raid_d
388 return mddev->dev_sectors; 387 return mddev->dev_sectors;
389} 388}
390 389
391static int multipath_run (struct mddev *mddev) 390static int multipath_run (mddev_t *mddev)
392{ 391{
393 struct mpconf *conf; 392 multipath_conf_t *conf;
394 int disk_idx; 393 int disk_idx;
395 struct multipath_info *disk; 394 struct multipath_info *disk;
396 struct md_rdev *rdev; 395 mdk_rdev_t *rdev;
397 int working_disks; 396 int working_disks;
398 397
399 if (md_check_no_bitmap(mddev)) 398 if (md_check_no_bitmap(mddev))
@@ -410,7 +409,7 @@ static int multipath_run (struct mddev *mddev)
410 * should be freed in multipath_stop()] 409 * should be freed in multipath_stop()]
411 */ 410 */
412 411
413 conf = kzalloc(sizeof(struct mpconf), GFP_KERNEL); 412 conf = kzalloc(sizeof(multipath_conf_t), GFP_KERNEL);
414 mddev->private = conf; 413 mddev->private = conf;
415 if (!conf) { 414 if (!conf) {
416 printk(KERN_ERR 415 printk(KERN_ERR
@@ -429,7 +428,7 @@ static int multipath_run (struct mddev *mddev)
429 } 428 }
430 429
431 working_disks = 0; 430 working_disks = 0;
432 rdev_for_each(rdev, mddev) { 431 list_for_each_entry(rdev, &mddev->disks, same_set) {
433 disk_idx = rdev->raid_disk; 432 disk_idx = rdev->raid_disk;
434 if (disk_idx < 0 || 433 if (disk_idx < 0 ||
435 disk_idx >= mddev->raid_disks) 434 disk_idx >= mddev->raid_disks)
@@ -475,8 +474,7 @@ static int multipath_run (struct mddev *mddev)
475 } 474 }
476 475
477 { 476 {
478 mddev->thread = md_register_thread(multipathd, mddev, 477 mddev->thread = md_register_thread(multipathd, mddev, NULL);
479 "multipath");
480 if (!mddev->thread) { 478 if (!mddev->thread) {
481 printk(KERN_ERR "multipath: couldn't allocate thread" 479 printk(KERN_ERR "multipath: couldn't allocate thread"
482 " for %s\n", mdname(mddev)); 480 " for %s\n", mdname(mddev));
@@ -512,9 +510,9 @@ out:
512} 510}
513 511
514 512
515static int multipath_stop (struct mddev *mddev) 513static int multipath_stop (mddev_t *mddev)
516{ 514{
517 struct mpconf *conf = mddev->private; 515 multipath_conf_t *conf = mddev->private;
518 516
519 md_unregister_thread(&mddev->thread); 517 md_unregister_thread(&mddev->thread);
520 blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/ 518 blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
@@ -525,7 +523,7 @@ static int multipath_stop (struct mddev *mddev)
525 return 0; 523 return 0;
526} 524}
527 525
528static struct md_personality multipath_personality = 526static struct mdk_personality multipath_personality =
529{ 527{
530 .name = "multipath", 528 .name = "multipath",
531 .level = LEVEL_MULTIPATH, 529 .level = LEVEL_MULTIPATH,