static void multipathd(struct md_thread *thread) { for (;;) { if ((mp_bh->path = multipath_map (conf))<0) { printk(KERN_ERR "multipath: %s: redirecting sector %llu" " to another IO path\n", bdevname(bio->bi_bdev,b), (unsigned long long)bio->bi_iter.bi_sector); } } }
static int multipath_make_request (struct request_queue *q, struct bio * bio) { mddev_t *mddev = q->queuedata; multipath_conf_t *conf = mddev_to_conf(mddev); struct multipath_bh * mp_bh; struct multipath_info *multipath; const int rw = bio_data_dir(bio); int cpu; if (unlikely(bio_barrier(bio))) { bio_endio(bio, -EOPNOTSUPP); return 0; } mp_bh = mempool_alloc(conf->pool, GFP_NOIO); mp_bh->master_bio = bio; mp_bh->mddev = mddev; cpu = part_stat_lock(); part_stat_inc(cpu, &mddev->gendisk->part0, ios[rw]); part_stat_add(cpu, &mddev->gendisk->part0, sectors[rw], bio_sectors(bio)); part_stat_unlock(); mp_bh->path = multipath_map(conf); if (mp_bh->path < 0) { bio_endio(bio, -EIO); mempool_free(mp_bh, conf->pool); return 0; } multipath = conf->multipaths + mp_bh->path; mp_bh->bio = *bio; mp_bh->bio.bi_sector += multipath->rdev->data_offset; mp_bh->bio.bi_bdev = multipath->rdev->bdev; mp_bh->bio.bi_rw |= (1 << BIO_RW_FAILFAST_TRANSPORT); mp_bh->bio.bi_end_io = multipath_end_request; mp_bh->bio.bi_private = mp_bh; generic_make_request(&mp_bh->bio); return 0; }
static int multipath_make_request (request_queue_t *q, struct bio * bio) { mddev_t *mddev = q->queuedata; multipath_conf_t *conf = mddev_to_conf(mddev); struct multipath_bh * mp_bh; struct multipath_info *multipath; if (unlikely(bio_barrier(bio))) { bio_endio(bio, bio->bi_size, -EOPNOTSUPP); return 0; } mp_bh = mempool_alloc(conf->pool, GFP_NOIO); mp_bh->master_bio = bio; mp_bh->mddev = mddev; if (bio_data_dir(bio)==WRITE) { disk_stat_inc(mddev->gendisk, writes); disk_stat_add(mddev->gendisk, write_sectors, bio_sectors(bio)); } else { disk_stat_inc(mddev->gendisk, reads); disk_stat_add(mddev->gendisk, read_sectors, bio_sectors(bio)); } mp_bh->path = multipath_map(conf); if (mp_bh->path < 0) { bio_endio(bio, bio->bi_size, -EIO); mempool_free(mp_bh, conf->pool); return 0; } multipath = conf->multipaths + mp_bh->path; mp_bh->bio = *bio; mp_bh->bio.bi_bdev = multipath->rdev->bdev; mp_bh->bio.bi_rw |= (1 << BIO_RW_FAILFAST); mp_bh->bio.bi_end_io = multipath_end_request; mp_bh->bio.bi_private = mp_bh; generic_make_request(&mp_bh->bio); return 0; }