~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/md/multipath.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
106
106
        rdev_dec_pending(rdev, conf->mddev);
107
107
}
108
108
 
109
 
static void unplug_slaves(mddev_t *mddev)
110
 
{
111
 
        multipath_conf_t *conf = mddev->private;
112
 
        int i;
113
 
 
114
 
        rcu_read_lock();
115
 
        for (i=0; i<mddev->raid_disks; i++) {
116
 
                mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev);
117
 
                if (rdev && !test_bit(Faulty, &rdev->flags)
118
 
                    && atomic_read(&rdev->nr_pending)) {
119
 
                        struct request_queue *r_queue = bdev_get_queue(rdev->bdev);
120
 
 
121
 
                        atomic_inc(&rdev->nr_pending);
122
 
                        rcu_read_unlock();
123
 
 
124
 
                        blk_unplug(r_queue);
125
 
 
126
 
                        rdev_dec_pending(rdev, mddev);
127
 
                        rcu_read_lock();
128
 
                }
129
 
        }
130
 
        rcu_read_unlock();
131
 
}
132
 
 
133
 
static void multipath_unplug(struct request_queue *q)
134
 
{
135
 
        unplug_slaves(q->queuedata);
136
 
}
137
 
 
138
 
 
139
109
static int multipath_make_request(mddev_t *mddev, struct bio * bio)
140
110
{
141
111
        multipath_conf_t *conf = mddev->private;
176
146
        int i;
177
147
        
178
148
        seq_printf (seq, " [%d/%d] [", conf->raid_disks,
179
 
                                                 conf->working_disks);
 
149
                    conf->raid_disks - mddev->degraded);
180
150
        for (i = 0; i < conf->raid_disks; i++)
181
151
                seq_printf (seq, "%s",
182
152
                               conf->multipaths[i].rdev && 
216
186
static void multipath_error (mddev_t *mddev, mdk_rdev_t *rdev)
217
187
{
218
188
        multipath_conf_t *conf = mddev->private;
 
189
        char b[BDEVNAME_SIZE];
219
190
 
220
 
        if (conf->working_disks <= 1) {
 
191
        if (conf->raid_disks - mddev->degraded <= 1) {
221
192
                /*
222
193
                 * Uh oh, we can do nothing if this is our last path, but
223
194
                 * first check if this is a queued request for a device
224
195
                 * which has just failed.
225
196
                 */
226
197
                printk(KERN_ALERT 
227
 
                        "multipath: only one IO path left and IO error.\n");
 
198
                       "multipath: only one IO path left and IO error.\n");
228
199
                /* leave it active... it's all we have */
229
 
        } else {
230
 
                /*
231
 
                 * Mark disk as unusable
232
 
                 */
233
 
                if (!test_bit(Faulty, &rdev->flags)) {
234
 
                        char b[BDEVNAME_SIZE];
235
 
                        clear_bit(In_sync, &rdev->flags);
236
 
                        set_bit(Faulty, &rdev->flags);
237
 
                        set_bit(MD_CHANGE_DEVS, &mddev->flags);
238
 
                        conf->working_disks--;
239
 
                        mddev->degraded++;
240
 
                        printk(KERN_ALERT "multipath: IO failure on %s,"
241
 
                                " disabling IO path.\n"
242
 
                                "multipath: Operation continuing"
243
 
                                " on %d IO paths.\n",
244
 
                                bdevname (rdev->bdev,b),
245
 
                                conf->working_disks);
246
 
                }
247
 
        }
 
200
                return;
 
201
        }
 
202
        /*
 
203
         * Mark disk as unusable
 
204
         */
 
205
        if (test_and_clear_bit(In_sync, &rdev->flags)) {
 
206
                unsigned long flags;
 
207
                spin_lock_irqsave(&conf->device_lock, flags);
 
208
                mddev->degraded++;
 
209
                spin_unlock_irqrestore(&conf->device_lock, flags);
 
210
        }
 
211
        set_bit(Faulty, &rdev->flags);
 
212
        set_bit(MD_CHANGE_DEVS, &mddev->flags);
 
213
        printk(KERN_ALERT "multipath: IO failure on %s,"
 
214
               " disabling IO path.\n"
 
215
               "multipath: Operation continuing"
 
216
               " on %d IO paths.\n",
 
217
               bdevname(rdev->bdev, b),
 
218
               conf->raid_disks - mddev->degraded);
248
219
}
249
220
 
250
221
static void print_multipath_conf (multipath_conf_t *conf)
257
228
                printk("(conf==NULL)\n");
258
229
                return;
259
230
        }
260
 
        printk(" --- wd:%d rd:%d\n", conf->working_disks,
 
231
        printk(" --- wd:%d rd:%d\n", conf->raid_disks - conf->mddev->degraded,
261
232
                         conf->raid_disks);
262
233
 
263
234
        for (i = 0; i < conf->raid_disks; i++) {
304
275
                                                           PAGE_CACHE_SIZE - 1);
305
276
                        }
306
277
 
307
 
                        conf->working_disks++;
 
278
                        spin_lock_irq(&conf->device_lock);
308
279
                        mddev->degraded--;
309
280
                        rdev->raid_disk = path;
310
281
                        set_bit(In_sync, &rdev->flags);
 
282
                        spin_unlock_irq(&conf->device_lock);
311
283
                        rcu_assign_pointer(p->rdev, rdev);
312
284
                        err = 0;
313
285
                        md_integrity_add_rdev(rdev, mddev);
345
317
                        p->rdev = rdev;
346
318
                        goto abort;
347
319
                }
348
 
                md_integrity_register(mddev);
 
320
                err = md_integrity_register(mddev);
349
321
        }
350
322
abort:
351
323
 
421
393
        int disk_idx;
422
394
        struct multipath_info *disk;
423
395
        mdk_rdev_t *rdev;
 
396
        int working_disks;
424
397
 
425
398
        if (md_check_no_bitmap(mddev))
426
399
                return -EINVAL;
454
427
                goto out_free_conf;
455
428
        }
456
429
 
457
 
        conf->working_disks = 0;
 
430
        working_disks = 0;
458
431
        list_for_each_entry(rdev, &mddev->disks, same_set) {
459
432
                disk_idx = rdev->raid_disk;
460
433
                if (disk_idx < 0 ||
476
449
                }
477
450
 
478
451
                if (!test_bit(Faulty, &rdev->flags))
479
 
                        conf->working_disks++;
 
452
                        working_disks++;
480
453
        }
481
454
 
482
455
        conf->raid_disks = mddev->raid_disks;
484
457
        spin_lock_init(&conf->device_lock);
485
458
        INIT_LIST_HEAD(&conf->retry_list);
486
459
 
487
 
        if (!conf->working_disks) {
 
460
        if (!working_disks) {
488
461
                printk(KERN_ERR "multipath: no operational IO paths for %s\n",
489
462
                        mdname(mddev));
490
463
                goto out_free_conf;
491
464
        }
492
 
        mddev->degraded = conf->raid_disks - conf->working_disks;
 
465
        mddev->degraded = conf->raid_disks - working_disks;
493
466
 
494
467
        conf->pool = mempool_create_kmalloc_pool(NR_RESERVED_BUFS,
495
468
                                                 sizeof(struct multipath_bh));
511
484
 
512
485
        printk(KERN_INFO 
513
486
                "multipath: array %s active with %d out of %d IO paths\n",
514
 
                mdname(mddev), conf->working_disks, mddev->raid_disks);
 
487
                mdname(mddev), conf->raid_disks - mddev->degraded,
 
488
               mddev->raid_disks);
515
489
        /*
516
490
         * Ok, everything is just fine now
517
491
         */
518
492
        md_set_array_sectors(mddev, multipath_size(mddev, 0, 0));
519
493
 
520
 
        mddev->queue->unplug_fn = multipath_unplug;
521
494
        mddev->queue->backing_dev_info.congested_fn = multipath_congested;
522
495
        mddev->queue->backing_dev_info.congested_data = mddev;
523
 
        md_integrity_register(mddev);
 
496
 
 
497
        if (md_integrity_register(mddev))
 
498
                goto out_free_conf;
 
499
 
524
500
        return 0;
525
501
 
526
502
out_free_conf: