diff options
| author | Alexander Viro <viro@math.psu.edu> | 2002-04-24 23:50:10 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@penguin.transmeta.com> | 2002-04-24 23:50:10 -0700 |
| commit | 5651c8e7a2d5af7e9f60a17c1236e9dec5411372 (patch) | |
| tree | d72e3ee81b55419ffde05fa8b601c8ff414e7f2e | |
| parent | efb0023262a442fd5bd2b443f8431c10c5e08fb0 (diff) | |
[PATCH] (7/15) big struct block_device * push (first series)
- md/multipath.c convert to bio, compile fixes, bring struct
block_device * into private data.
| -rw-r--r-- | drivers/md/multipath.c | 136 | ||||
| -rw-r--r-- | include/linux/raid/multipath.h | 9 |
2 files changed, 78 insertions, 67 deletions
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 792e787fc7ab..1dab6f53b08a 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c @@ -49,7 +49,7 @@ static mdk_personality_t multipath_personality; -static md_spinlock_t retry_list_lock = MD_SPIN_LOCK_UNLOCKED; +static spinlock_t retry_list_lock = SPIN_LOCK_UNLOCKED; struct multipath_bh *multipath_retry_list = NULL, **multipath_retry_tail; static int multipath_diskop(mddev_t *mddev, mdp_disk_t **d, int state); @@ -61,16 +61,15 @@ static struct multipath_bh *multipath_alloc_mpbh(multipath_conf_t *conf) struct multipath_bh *mp_bh = NULL; do { - md_spin_lock_irq(&conf->device_lock); + spin_lock_irq(&conf->device_lock); if (!conf->freer1_blocked && conf->freer1) { mp_bh = conf->freer1; conf->freer1 = mp_bh->next_mp; conf->freer1_cnt--; mp_bh->next_mp = NULL; mp_bh->state = (1 << MPBH_PreAlloc); - mp_bh->bh_req.b_state = 0; } - md_spin_unlock_irq(&conf->device_lock); + spin_unlock_irq(&conf->device_lock); if (mp_bh) return mp_bh; mp_bh = (struct multipath_bh *) kmalloc(sizeof(struct multipath_bh), @@ -94,6 +93,7 @@ static inline void multipath_free_mpbh(struct multipath_bh *mp_bh) if (test_bit(MPBH_PreAlloc, &mp_bh->state)) { unsigned long flags; + mp_bh->bio = NULL; spin_lock_irqsave(&conf->device_lock, flags); mp_bh->next_mp = conf->freer1; conf->freer1 = mp_bh; @@ -126,18 +126,18 @@ static int multipath_grow_mpbh (multipath_conf_t *conf, int cnt) static void multipath_shrink_mpbh(multipath_conf_t *conf) { - md_spin_lock_irq(&conf->device_lock); + spin_lock_irq(&conf->device_lock); while (conf->freer1) { struct multipath_bh *mp_bh = conf->freer1; conf->freer1 = mp_bh->next_mp; conf->freer1_cnt--; kfree(mp_bh); } - md_spin_unlock_irq(&conf->device_lock); + spin_unlock_irq(&conf->device_lock); } -static int multipath_map (mddev_t *mddev, kdev_t *rdev) +static int multipath_map (mddev_t *mddev, kdev_t *dev) { multipath_conf_t *conf = mddev_to_conf(mddev); int i, disks = MD_SB_DISKS; @@ -149,7 +149,7 @@ static int multipath_map (mddev_t *mddev, kdev_t *rdev) for (i = 0; i < disks; i++) { if (conf->multipaths[i].operational) { - *rdev = conf->multipaths[i].dev; + *dev = conf->multipaths[i].dev; return (0); } } @@ -164,13 +164,13 @@ static void multipath_reschedule_retry (struct multipath_bh *mp_bh) mddev_t *mddev = mp_bh->mddev; multipath_conf_t *conf = mddev_to_conf(mddev); - md_spin_lock_irqsave(&retry_list_lock, flags); + spin_lock_irqsave(&retry_list_lock, flags); if (multipath_retry_list == NULL) multipath_retry_tail = &multipath_retry_list; *multipath_retry_tail = mp_bh; multipath_retry_tail = &mp_bh->next_mp; mp_bh->next_mp = NULL; - md_spin_unlock_irqrestore(&retry_list_lock, flags); + spin_unlock_irqrestore(&retry_list_lock, flags); md_wakeup_thread(conf->thread); } @@ -182,21 +182,23 @@ static void multipath_reschedule_retry (struct multipath_bh *mp_bh) */ static void multipath_end_bh_io (struct multipath_bh *mp_bh, int uptodate) { - struct buffer_head *bh = mp_bh->master_bh; + struct bio *bio = mp_bh->master_bio; - bh->b_end_io(bh, uptodate); + bio_endio(bio, uptodate); + bio_put(mp_bh->bio); multipath_free_mpbh(mp_bh); } -void multipath_end_request (struct buffer_head *bh, int uptodate) +void multipath_end_request(struct bio *bio) { - struct multipath_bh * mp_bh = (struct multipath_bh *)(bh->b_private); + int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); + struct multipath_bh * mp_bh = (struct multipath_bh *)(bio->bi_private); /* * this branch is our 'one multipath IO has finished' event handler: */ if (!uptodate) - md_error (mp_bh->mddev, bh->b_dev); + md_error (mp_bh->mddev, bio->bi_dev); else /* * Set MPBH_Uptodate in our master buffer_head, so that @@ -217,8 +219,8 @@ void multipath_end_request (struct buffer_head *bh, int uptodate) /* * oops, IO error: */ - printk(KERN_ERR "multipath: %s: rescheduling block %lu\n", - partition_name(bh->b_dev), bh->b_blocknr); + printk(KERN_ERR "multipath: %s: rescheduling sector %lu\n", + partition_name(bio->bi_dev), bio->bi_sector); multipath_reschedule_retry(mp_bh); return; } @@ -239,17 +241,13 @@ static int multipath_read_balance (multipath_conf_t *conf) return 0; } -static int multipath_make_request (mddev_t *mddev, int rw, - struct buffer_head * bh) +static int multipath_make_request (mddev_t *mddev, int rw, struct bio * bio) { multipath_conf_t *conf = mddev_to_conf(mddev); - struct buffer_head *bh_req; + struct bio *real_bio; struct multipath_bh * mp_bh; struct multipath_info *multipath; - if (!buffer_locked(bh)) - BUG(); - /* * make_request() can abort the operation when READA is being * used and no empty request is available. @@ -261,7 +259,7 @@ static int multipath_make_request (mddev_t *mddev, int rw, mp_bh = multipath_alloc_mpbh (conf); - mp_bh->master_bh = bh; + mp_bh->master_bio = bio; mp_bh->mddev = mddev; mp_bh->cmd = rw; @@ -270,16 +268,13 @@ static int multipath_make_request (mddev_t *mddev, int rw, */ multipath = conf->multipaths + multipath_read_balance(conf); - bh_req = &mp_bh->bh_req; - memcpy(bh_req, bh, sizeof(*bh)); - bh_req->b_blocknr = bh->b_rsector; - bh_req->b_dev = multipath->dev; - /* FIXME - later we will need bdev here */ - bh_req->b_rdev = multipath->dev; -/* bh_req->b_rsector = bh->n_rsector; */ - bh_req->b_end_io = multipath_end_request; - bh_req->b_private = mp_bh; - generic_make_request (rw, bh_req); + real_bio = bio_clone(bio, GFP_NOIO); + real_bio->bi_dev = multipath->dev; + real_bio->bi_rw = rw; + real_bio->bi_end_io = multipath_end_request; + real_bio->bi_private = mp_bh; + mp_bh->bio = real_bio; + generic_make_request(real_bio); return 0; } @@ -429,9 +424,10 @@ static int multipath_diskop(mddev_t *mddev, mdp_disk_t **d, int state) mdp_super_t *sb = mddev->sb; mdp_disk_t *failed_desc, *spare_desc, *added_desc; mdk_rdev_t *spare_rdev, *failed_rdev; + struct block_device *bdev; print_multipath_conf(conf); - md_spin_lock_irq(&conf->device_lock); + spin_lock_irq(&conf->device_lock); /* * find the disk ... */ @@ -607,7 +603,7 @@ static int multipath_diskop(mddev_t *mddev, mdp_disk_t **d, int state) *d = failed_desc; - if (kdev_none(sdisk->dev)) + if (!sdisk->bdev) sdisk->used_slot = 0; /* * this really activates the spare. @@ -632,9 +628,12 @@ static int multipath_diskop(mddev_t *mddev, mdp_disk_t **d, int state) err = 1; goto abort; } + bdev = rdisk->bdev; rdisk->dev = NODEV; + rdisk->bdev = NULL; rdisk->used_slot = 0; conf->nr_disks--; + bdput(bdev); break; case DISKOP_HOT_ADD_DISK: @@ -650,6 +649,8 @@ static int multipath_diskop(mddev_t *mddev, mdp_disk_t **d, int state) adisk->number = added_desc->number; adisk->raid_disk = added_desc->raid_disk; adisk->dev = mk_kdev(added_desc->major,added_desc->minor); + /* it will be held open by rdev */ + adisk->bdev = bdget(kdev_t_to_nr(adisk->dev)); adisk->operational = 0; adisk->spare = 1; @@ -659,12 +660,12 @@ static int multipath_diskop(mddev_t *mddev, mdp_disk_t **d, int state) break; default: - MD_BUG(); + MD_BUG(); err = 1; goto abort; } abort: - md_spin_unlock_irq(&conf->device_lock); + spin_unlock_irq(&conf->device_lock); print_multipath_conf(conf); return err; @@ -688,19 +689,18 @@ abort: static void multipathd (void *data) { struct multipath_bh *mp_bh; - struct buffer_head *bh; + struct bio *bio; unsigned long flags; mddev_t *mddev; kdev_t dev; - for (;;) { - md_spin_lock_irqsave(&retry_list_lock, flags); + spin_lock_irqsave(&retry_list_lock, flags); mp_bh = multipath_retry_list; if (!mp_bh) break; multipath_retry_list = mp_bh->next_mp; - md_spin_unlock_irqrestore(&retry_list_lock, flags); + spin_unlock_irqrestore(&retry_list_lock, flags); mddev = mp_bh->mddev; if (mddev->sb_dirty) { @@ -708,22 +708,21 @@ static void multipathd (void *data) mddev->sb_dirty = 0; md_update_sb(mddev); } - bh = &mp_bh->bh_req; - dev = bh->b_dev; + bio = mp_bh->bio; + dev = bio->bi_dev; - multipath_map (mddev, &bh->b_dev); - if (kdev_same(bh->b_dev, dev)) { - printk (IO_ERROR, partition_name(bh->b_dev), bh->b_blocknr); + multipath_map (mddev, &bio->bi_dev); + if (kdev_same(bio->bi_dev, dev)) { + printk(IO_ERROR, + partition_name(bio->bi_dev), bio->bi_sector); multipath_end_bh_io(mp_bh, 0); } else { - printk (REDIRECT_SECTOR, - partition_name(bh->b_dev), bh->b_blocknr); - bh->b_rdev = bh->b_dev; - bh->b_rsector = bh->b_blocknr; - generic_make_request (mp_bh->cmd, bh); + printk(REDIRECT_SECTOR, + partition_name(bio->bi_dev), bio->bi_sector); + generic_make_request(bio); } } - md_spin_unlock_irqrestore(&retry_list_lock, flags); + spin_unlock_irqrestore(&retry_list_lock, flags); } #undef IO_ERROR #undef REDIRECT_SECTOR @@ -740,6 +739,7 @@ static int __check_consistency (mddev_t *mddev, int row) multipath_conf_t *conf = mddev_to_conf(mddev); int disks = MD_SB_DISKS; kdev_t dev; + struct block_device *bdev; struct buffer_head *bh = NULL; int i, rc = 0; char *buffer = NULL; @@ -749,8 +749,9 @@ static int __check_consistency (mddev_t *mddev, int row) continue; printk("(checking disk %d)\n",i); dev = conf->multipaths[i].dev; + bdev = conf->multipaths[i].bdev; set_blocksize(dev, 4096); - if ((bh = bread(dev, row / 4, 4096)) == NULL) + if ((bh = __bread(bdev, row / 4, 4096)) == NULL) break; if (!buffer) { buffer = (char *) __get_free_page(GFP_KERNEL); @@ -762,17 +763,17 @@ static int __check_consistency (mddev_t *mddev, int row) break; } bforget(bh); - fsync_dev(dev); - invalidate_buffers(dev); + fsync_bdev(bdev); + invalidate_bdev(bdev, 0); bh = NULL; } if (buffer) free_page((unsigned long) buffer); if (bh) { - dev = bh->b_dev; + bdev = bh->b_bdev; bforget(bh); - fsync_dev(dev); - invalidate_buffers(dev); + fsync_bdev(bdev); + invalidate_bdev(bdev, 0); } return rc; } @@ -837,7 +838,7 @@ static int multipath_run (mddev_t *mddev) mdp_super_t *sb = mddev->sb; mdp_disk_t *desc, *desc2; mdk_rdev_t *rdev, *def_rdev = NULL; - struct md_list_head *tmp; + struct list_head *tmp; int num_rdevs = 0; MOD_INC_USE_COUNT; @@ -894,6 +895,8 @@ static int multipath_run (mddev_t *mddev) disk->number = desc->number; disk->raid_disk = desc->raid_disk; disk->dev = rdev->dev; + disk->bdev = rdev->bdev; + atomic_inc(&rdev->bdev->bd_count); disk->operational = 0; disk->spare = 1; disk->used_slot = 1; @@ -952,7 +955,7 @@ static int multipath_run (mddev_t *mddev) sb->spare_disks = num_rdevs - 1; mddev->sb_dirty = 1; conf->mddev = mddev; - conf->device_lock = MD_SPIN_LOCK_UNLOCKED; + conf->device_lock = SPIN_LOCK_UNLOCKED; init_waitqueue_head(&conf->wait_buffer); @@ -1018,6 +1021,9 @@ static int multipath_run (mddev_t *mddev) out_free_conf: multipath_shrink_mpbh(conf); + for (i = 0; i < MD_SB_DISKS; i++) + if (conf->multipaths[i].bdev) + bdput(conf->multipaths[i].bdev); kfree(conf); mddev->private = NULL; out: @@ -1040,9 +1046,13 @@ out: static int multipath_stop (mddev_t *mddev) { multipath_conf_t *conf = mddev_to_conf(mddev); + int i; md_unregister_thread(conf->thread); multipath_shrink_mpbh(conf); + for (i = 0; i < MD_SB_DISKS; i++) + if (conf->multipaths[i].bdev) + bdput(conf->multipaths[i].bdev); kfree(conf); mddev->private = NULL; MOD_DEC_USE_COUNT; @@ -1060,12 +1070,12 @@ static mdk_personality_t multipath_personality= diskop: multipath_diskop, }; -static int md__init multipath_init (void) +static int __init multipath_init (void) { return register_md_personality (MULTIPATH, &multipath_personality); } -static void multipath_exit (void) +static void __exit multipath_exit (void) { unregister_md_personality (MULTIPATH); } diff --git a/include/linux/raid/multipath.h b/include/linux/raid/multipath.h index 261c1c837d7b..9c9cdc77fa05 100644 --- a/include/linux/raid/multipath.h +++ b/include/linux/raid/multipath.h @@ -7,6 +7,7 @@ struct multipath_info { int number; int raid_disk; kdev_t dev; + struct block_device *bdev; /* * State bits: @@ -25,7 +26,7 @@ struct multipath_private_data { int working_disks; mdk_thread_t *thread; struct multipath_info *spare; - md_spinlock_t device_lock; + spinlock_t device_lock; /* buffer pool */ /* buffer_heads that we have pre-allocated have b_pprev -> &freebh @@ -36,7 +37,7 @@ struct multipath_private_data { struct multipath_bh *freer1; int freer1_blocked; int freer1_cnt; - md_wait_queue_head_t wait_buffer; + wait_queue_head_t wait_buffer; }; typedef struct multipath_private_data multipath_conf_t; @@ -60,8 +61,8 @@ struct multipath_bh { int cmd; unsigned long state; mddev_t *mddev; - struct buffer_head *master_bh; - struct buffer_head bh_req; + struct bio *master_bio; + struct bio *bio; struct multipath_bh *next_mp; /* next for retry or in free list */ }; /* bits for multipath_bh.state */ |
