]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] (7/15) big struct block_device * push (first series)
authorAlexander Viro <viro@math.psu.edu>
Thu, 25 Apr 2002 06:50:10 +0000 (23:50 -0700)
committerLinus Torvalds <torvalds@penguin.transmeta.com>
Thu, 25 Apr 2002 06:50:10 +0000 (23:50 -0700)
 - md/multipath.c convert to bio, compile fixes, bring struct
   block_device * into private data.

drivers/md/multipath.c
include/linux/raid/multipath.h

index 792e787fc7abf1fda0f27657c55b49cf10f51f59..1dab6f53b08a3af3cb0cc4fd8465f5fed9a1f68a 100644 (file)
@@ -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);
 }
index 261c1c837d7b7f27e166ae804cc92f8327ddc27b..9c9cdc77fa059167a18e8168991682e39a973c42 100644 (file)
@@ -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 */