summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Viro <viro@math.psu.edu>2002-04-24 23:50:10 -0700
committerLinus Torvalds <torvalds@penguin.transmeta.com>2002-04-24 23:50:10 -0700
commit5651c8e7a2d5af7e9f60a17c1236e9dec5411372 (patch)
treed72e3ee81b55419ffde05fa8b601c8ff414e7f2e
parentefb0023262a442fd5bd2b443f8431c10c5e08fb0 (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.c136
-rw-r--r--include/linux/raid/multipath.h9
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 */