Commit 5651c8e7 authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[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.
parent efb00232
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
static mdk_personality_t multipath_personality; 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; struct multipath_bh *multipath_retry_list = NULL, **multipath_retry_tail;
static int multipath_diskop(mddev_t *mddev, mdp_disk_t **d, int state); 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) ...@@ -61,16 +61,15 @@ static struct multipath_bh *multipath_alloc_mpbh(multipath_conf_t *conf)
struct multipath_bh *mp_bh = NULL; struct multipath_bh *mp_bh = NULL;
do { do {
md_spin_lock_irq(&conf->device_lock); spin_lock_irq(&conf->device_lock);
if (!conf->freer1_blocked && conf->freer1) { if (!conf->freer1_blocked && conf->freer1) {
mp_bh = conf->freer1; mp_bh = conf->freer1;
conf->freer1 = mp_bh->next_mp; conf->freer1 = mp_bh->next_mp;
conf->freer1_cnt--; conf->freer1_cnt--;
mp_bh->next_mp = NULL; mp_bh->next_mp = NULL;
mp_bh->state = (1 << MPBH_PreAlloc); 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) if (mp_bh)
return mp_bh; return mp_bh;
mp_bh = (struct multipath_bh *) kmalloc(sizeof(struct multipath_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) ...@@ -94,6 +93,7 @@ static inline void multipath_free_mpbh(struct multipath_bh *mp_bh)
if (test_bit(MPBH_PreAlloc, &mp_bh->state)) { if (test_bit(MPBH_PreAlloc, &mp_bh->state)) {
unsigned long flags; unsigned long flags;
mp_bh->bio = NULL;
spin_lock_irqsave(&conf->device_lock, flags); spin_lock_irqsave(&conf->device_lock, flags);
mp_bh->next_mp = conf->freer1; mp_bh->next_mp = conf->freer1;
conf->freer1 = mp_bh; conf->freer1 = mp_bh;
...@@ -126,18 +126,18 @@ static int multipath_grow_mpbh (multipath_conf_t *conf, int cnt) ...@@ -126,18 +126,18 @@ static int multipath_grow_mpbh (multipath_conf_t *conf, int cnt)
static void multipath_shrink_mpbh(multipath_conf_t *conf) 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) { while (conf->freer1) {
struct multipath_bh *mp_bh = conf->freer1; struct multipath_bh *mp_bh = conf->freer1;
conf->freer1 = mp_bh->next_mp; conf->freer1 = mp_bh->next_mp;
conf->freer1_cnt--; conf->freer1_cnt--;
kfree(mp_bh); 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); multipath_conf_t *conf = mddev_to_conf(mddev);
int i, disks = MD_SB_DISKS; int i, disks = MD_SB_DISKS;
...@@ -149,7 +149,7 @@ static int multipath_map (mddev_t *mddev, kdev_t *rdev) ...@@ -149,7 +149,7 @@ static int multipath_map (mddev_t *mddev, kdev_t *rdev)
for (i = 0; i < disks; i++) { for (i = 0; i < disks; i++) {
if (conf->multipaths[i].operational) { if (conf->multipaths[i].operational) {
*rdev = conf->multipaths[i].dev; *dev = conf->multipaths[i].dev;
return (0); return (0);
} }
} }
...@@ -164,13 +164,13 @@ static void multipath_reschedule_retry (struct multipath_bh *mp_bh) ...@@ -164,13 +164,13 @@ static void multipath_reschedule_retry (struct multipath_bh *mp_bh)
mddev_t *mddev = mp_bh->mddev; mddev_t *mddev = mp_bh->mddev;
multipath_conf_t *conf = mddev_to_conf(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) if (multipath_retry_list == NULL)
multipath_retry_tail = &multipath_retry_list; multipath_retry_tail = &multipath_retry_list;
*multipath_retry_tail = mp_bh; *multipath_retry_tail = mp_bh;
multipath_retry_tail = &mp_bh->next_mp; multipath_retry_tail = &mp_bh->next_mp;
mp_bh->next_mp = NULL; 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); md_wakeup_thread(conf->thread);
} }
...@@ -182,21 +182,23 @@ static void multipath_reschedule_retry (struct multipath_bh *mp_bh) ...@@ -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) 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); 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: * this branch is our 'one multipath IO has finished' event handler:
*/ */
if (!uptodate) if (!uptodate)
md_error (mp_bh->mddev, bh->b_dev); md_error (mp_bh->mddev, bio->bi_dev);
else else
/* /*
* Set MPBH_Uptodate in our master buffer_head, so that * Set MPBH_Uptodate in our master buffer_head, so that
...@@ -217,8 +219,8 @@ void multipath_end_request (struct buffer_head *bh, int uptodate) ...@@ -217,8 +219,8 @@ void multipath_end_request (struct buffer_head *bh, int uptodate)
/* /*
* oops, IO error: * oops, IO error:
*/ */
printk(KERN_ERR "multipath: %s: rescheduling block %lu\n", printk(KERN_ERR "multipath: %s: rescheduling sector %lu\n",
partition_name(bh->b_dev), bh->b_blocknr); partition_name(bio->bi_dev), bio->bi_sector);
multipath_reschedule_retry(mp_bh); multipath_reschedule_retry(mp_bh);
return; return;
} }
...@@ -239,17 +241,13 @@ static int multipath_read_balance (multipath_conf_t *conf) ...@@ -239,17 +241,13 @@ static int multipath_read_balance (multipath_conf_t *conf)
return 0; return 0;
} }
static int multipath_make_request (mddev_t *mddev, int rw, static int multipath_make_request (mddev_t *mddev, int rw, struct bio * bio)
struct buffer_head * bh)
{ {
multipath_conf_t *conf = mddev_to_conf(mddev); multipath_conf_t *conf = mddev_to_conf(mddev);
struct buffer_head *bh_req; struct bio *real_bio;
struct multipath_bh * mp_bh; struct multipath_bh * mp_bh;
struct multipath_info *multipath; struct multipath_info *multipath;
if (!buffer_locked(bh))
BUG();
/* /*
* make_request() can abort the operation when READA is being * make_request() can abort the operation when READA is being
* used and no empty request is available. * used and no empty request is available.
...@@ -261,7 +259,7 @@ static int multipath_make_request (mddev_t *mddev, int rw, ...@@ -261,7 +259,7 @@ static int multipath_make_request (mddev_t *mddev, int rw,
mp_bh = multipath_alloc_mpbh (conf); mp_bh = multipath_alloc_mpbh (conf);
mp_bh->master_bh = bh; mp_bh->master_bio = bio;
mp_bh->mddev = mddev; mp_bh->mddev = mddev;
mp_bh->cmd = rw; mp_bh->cmd = rw;
...@@ -270,16 +268,13 @@ static int multipath_make_request (mddev_t *mddev, int rw, ...@@ -270,16 +268,13 @@ static int multipath_make_request (mddev_t *mddev, int rw,
*/ */
multipath = conf->multipaths + multipath_read_balance(conf); multipath = conf->multipaths + multipath_read_balance(conf);
bh_req = &mp_bh->bh_req; real_bio = bio_clone(bio, GFP_NOIO);
memcpy(bh_req, bh, sizeof(*bh)); real_bio->bi_dev = multipath->dev;
bh_req->b_blocknr = bh->b_rsector; real_bio->bi_rw = rw;
bh_req->b_dev = multipath->dev; real_bio->bi_end_io = multipath_end_request;
/* FIXME - later we will need bdev here */ real_bio->bi_private = mp_bh;
bh_req->b_rdev = multipath->dev; mp_bh->bio = real_bio;
/* bh_req->b_rsector = bh->n_rsector; */ generic_make_request(real_bio);
bh_req->b_end_io = multipath_end_request;
bh_req->b_private = mp_bh;
generic_make_request (rw, bh_req);
return 0; return 0;
} }
...@@ -429,9 +424,10 @@ static int multipath_diskop(mddev_t *mddev, mdp_disk_t **d, int state) ...@@ -429,9 +424,10 @@ static int multipath_diskop(mddev_t *mddev, mdp_disk_t **d, int state)
mdp_super_t *sb = mddev->sb; mdp_super_t *sb = mddev->sb;
mdp_disk_t *failed_desc, *spare_desc, *added_desc; mdp_disk_t *failed_desc, *spare_desc, *added_desc;
mdk_rdev_t *spare_rdev, *failed_rdev; mdk_rdev_t *spare_rdev, *failed_rdev;
struct block_device *bdev;
print_multipath_conf(conf); print_multipath_conf(conf);
md_spin_lock_irq(&conf->device_lock); spin_lock_irq(&conf->device_lock);
/* /*
* find the disk ... * find the disk ...
*/ */
...@@ -607,7 +603,7 @@ static int multipath_diskop(mddev_t *mddev, mdp_disk_t **d, int state) ...@@ -607,7 +603,7 @@ static int multipath_diskop(mddev_t *mddev, mdp_disk_t **d, int state)
*d = failed_desc; *d = failed_desc;
if (kdev_none(sdisk->dev)) if (!sdisk->bdev)
sdisk->used_slot = 0; sdisk->used_slot = 0;
/* /*
* this really activates the spare. * this really activates the spare.
...@@ -632,9 +628,12 @@ static int multipath_diskop(mddev_t *mddev, mdp_disk_t **d, int state) ...@@ -632,9 +628,12 @@ static int multipath_diskop(mddev_t *mddev, mdp_disk_t **d, int state)
err = 1; err = 1;
goto abort; goto abort;
} }
bdev = rdisk->bdev;
rdisk->dev = NODEV; rdisk->dev = NODEV;
rdisk->bdev = NULL;
rdisk->used_slot = 0; rdisk->used_slot = 0;
conf->nr_disks--; conf->nr_disks--;
bdput(bdev);
break; break;
case DISKOP_HOT_ADD_DISK: case DISKOP_HOT_ADD_DISK:
...@@ -650,6 +649,8 @@ static int multipath_diskop(mddev_t *mddev, mdp_disk_t **d, int state) ...@@ -650,6 +649,8 @@ static int multipath_diskop(mddev_t *mddev, mdp_disk_t **d, int state)
adisk->number = added_desc->number; adisk->number = added_desc->number;
adisk->raid_disk = added_desc->raid_disk; adisk->raid_disk = added_desc->raid_disk;
adisk->dev = mk_kdev(added_desc->major,added_desc->minor); 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->operational = 0;
adisk->spare = 1; adisk->spare = 1;
...@@ -659,12 +660,12 @@ static int multipath_diskop(mddev_t *mddev, mdp_disk_t **d, int state) ...@@ -659,12 +660,12 @@ static int multipath_diskop(mddev_t *mddev, mdp_disk_t **d, int state)
break; break;
default: default:
MD_BUG(); MD_BUG();
err = 1; err = 1;
goto abort; goto abort;
} }
abort: abort:
md_spin_unlock_irq(&conf->device_lock); spin_unlock_irq(&conf->device_lock);
print_multipath_conf(conf); print_multipath_conf(conf);
return err; return err;
...@@ -688,19 +689,18 @@ static int multipath_diskop(mddev_t *mddev, mdp_disk_t **d, int state) ...@@ -688,19 +689,18 @@ static int multipath_diskop(mddev_t *mddev, mdp_disk_t **d, int state)
static void multipathd (void *data) static void multipathd (void *data)
{ {
struct multipath_bh *mp_bh; struct multipath_bh *mp_bh;
struct buffer_head *bh; struct bio *bio;
unsigned long flags; unsigned long flags;
mddev_t *mddev; mddev_t *mddev;
kdev_t dev; kdev_t dev;
for (;;) { for (;;) {
md_spin_lock_irqsave(&retry_list_lock, flags); spin_lock_irqsave(&retry_list_lock, flags);
mp_bh = multipath_retry_list; mp_bh = multipath_retry_list;
if (!mp_bh) if (!mp_bh)
break; break;
multipath_retry_list = mp_bh->next_mp; 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; mddev = mp_bh->mddev;
if (mddev->sb_dirty) { if (mddev->sb_dirty) {
...@@ -708,22 +708,21 @@ static void multipathd (void *data) ...@@ -708,22 +708,21 @@ static void multipathd (void *data)
mddev->sb_dirty = 0; mddev->sb_dirty = 0;
md_update_sb(mddev); md_update_sb(mddev);
} }
bh = &mp_bh->bh_req; bio = mp_bh->bio;
dev = bh->b_dev; dev = bio->bi_dev;
multipath_map (mddev, &bh->b_dev); multipath_map (mddev, &bio->bi_dev);
if (kdev_same(bh->b_dev, dev)) { if (kdev_same(bio->bi_dev, dev)) {
printk (IO_ERROR, partition_name(bh->b_dev), bh->b_blocknr); printk(IO_ERROR,
partition_name(bio->bi_dev), bio->bi_sector);
multipath_end_bh_io(mp_bh, 0); multipath_end_bh_io(mp_bh, 0);
} else { } else {
printk (REDIRECT_SECTOR, printk(REDIRECT_SECTOR,
partition_name(bh->b_dev), bh->b_blocknr); partition_name(bio->bi_dev), bio->bi_sector);
bh->b_rdev = bh->b_dev; generic_make_request(bio);
bh->b_rsector = bh->b_blocknr;
generic_make_request (mp_bh->cmd, bh);
} }
} }
md_spin_unlock_irqrestore(&retry_list_lock, flags); spin_unlock_irqrestore(&retry_list_lock, flags);
} }
#undef IO_ERROR #undef IO_ERROR
#undef REDIRECT_SECTOR #undef REDIRECT_SECTOR
...@@ -740,6 +739,7 @@ static int __check_consistency (mddev_t *mddev, int row) ...@@ -740,6 +739,7 @@ static int __check_consistency (mddev_t *mddev, int row)
multipath_conf_t *conf = mddev_to_conf(mddev); multipath_conf_t *conf = mddev_to_conf(mddev);
int disks = MD_SB_DISKS; int disks = MD_SB_DISKS;
kdev_t dev; kdev_t dev;
struct block_device *bdev;
struct buffer_head *bh = NULL; struct buffer_head *bh = NULL;
int i, rc = 0; int i, rc = 0;
char *buffer = NULL; char *buffer = NULL;
...@@ -749,8 +749,9 @@ static int __check_consistency (mddev_t *mddev, int row) ...@@ -749,8 +749,9 @@ static int __check_consistency (mddev_t *mddev, int row)
continue; continue;
printk("(checking disk %d)\n",i); printk("(checking disk %d)\n",i);
dev = conf->multipaths[i].dev; dev = conf->multipaths[i].dev;
bdev = conf->multipaths[i].bdev;
set_blocksize(dev, 4096); set_blocksize(dev, 4096);
if ((bh = bread(dev, row / 4, 4096)) == NULL) if ((bh = __bread(bdev, row / 4, 4096)) == NULL)
break; break;
if (!buffer) { if (!buffer) {
buffer = (char *) __get_free_page(GFP_KERNEL); buffer = (char *) __get_free_page(GFP_KERNEL);
...@@ -762,17 +763,17 @@ static int __check_consistency (mddev_t *mddev, int row) ...@@ -762,17 +763,17 @@ static int __check_consistency (mddev_t *mddev, int row)
break; break;
} }
bforget(bh); bforget(bh);
fsync_dev(dev); fsync_bdev(bdev);
invalidate_buffers(dev); invalidate_bdev(bdev, 0);
bh = NULL; bh = NULL;
} }
if (buffer) if (buffer)
free_page((unsigned long) buffer); free_page((unsigned long) buffer);
if (bh) { if (bh) {
dev = bh->b_dev; bdev = bh->b_bdev;
bforget(bh); bforget(bh);
fsync_dev(dev); fsync_bdev(bdev);
invalidate_buffers(dev); invalidate_bdev(bdev, 0);
} }
return rc; return rc;
} }
...@@ -837,7 +838,7 @@ static int multipath_run (mddev_t *mddev) ...@@ -837,7 +838,7 @@ static int multipath_run (mddev_t *mddev)
mdp_super_t *sb = mddev->sb; mdp_super_t *sb = mddev->sb;
mdp_disk_t *desc, *desc2; mdp_disk_t *desc, *desc2;
mdk_rdev_t *rdev, *def_rdev = NULL; mdk_rdev_t *rdev, *def_rdev = NULL;
struct md_list_head *tmp; struct list_head *tmp;
int num_rdevs = 0; int num_rdevs = 0;
MOD_INC_USE_COUNT; MOD_INC_USE_COUNT;
...@@ -894,6 +895,8 @@ static int multipath_run (mddev_t *mddev) ...@@ -894,6 +895,8 @@ static int multipath_run (mddev_t *mddev)
disk->number = desc->number; disk->number = desc->number;
disk->raid_disk = desc->raid_disk; disk->raid_disk = desc->raid_disk;
disk->dev = rdev->dev; disk->dev = rdev->dev;
disk->bdev = rdev->bdev;
atomic_inc(&rdev->bdev->bd_count);
disk->operational = 0; disk->operational = 0;
disk->spare = 1; disk->spare = 1;
disk->used_slot = 1; disk->used_slot = 1;
...@@ -952,7 +955,7 @@ static int multipath_run (mddev_t *mddev) ...@@ -952,7 +955,7 @@ static int multipath_run (mddev_t *mddev)
sb->spare_disks = num_rdevs - 1; sb->spare_disks = num_rdevs - 1;
mddev->sb_dirty = 1; mddev->sb_dirty = 1;
conf->mddev = mddev; conf->mddev = mddev;
conf->device_lock = MD_SPIN_LOCK_UNLOCKED; conf->device_lock = SPIN_LOCK_UNLOCKED;
init_waitqueue_head(&conf->wait_buffer); init_waitqueue_head(&conf->wait_buffer);
...@@ -1018,6 +1021,9 @@ static int multipath_run (mddev_t *mddev) ...@@ -1018,6 +1021,9 @@ static int multipath_run (mddev_t *mddev)
out_free_conf: out_free_conf:
multipath_shrink_mpbh(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); kfree(conf);
mddev->private = NULL; mddev->private = NULL;
out: out:
...@@ -1040,9 +1046,13 @@ static int multipath_run (mddev_t *mddev) ...@@ -1040,9 +1046,13 @@ static int multipath_run (mddev_t *mddev)
static int multipath_stop (mddev_t *mddev) static int multipath_stop (mddev_t *mddev)
{ {
multipath_conf_t *conf = mddev_to_conf(mddev); multipath_conf_t *conf = mddev_to_conf(mddev);
int i;
md_unregister_thread(conf->thread); md_unregister_thread(conf->thread);
multipath_shrink_mpbh(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); kfree(conf);
mddev->private = NULL; mddev->private = NULL;
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
...@@ -1060,12 +1070,12 @@ static mdk_personality_t multipath_personality= ...@@ -1060,12 +1070,12 @@ static mdk_personality_t multipath_personality=
diskop: multipath_diskop, diskop: multipath_diskop,
}; };
static int md__init multipath_init (void) static int __init multipath_init (void)
{ {
return register_md_personality (MULTIPATH, &multipath_personality); return register_md_personality (MULTIPATH, &multipath_personality);
} }
static void multipath_exit (void) static void __exit multipath_exit (void)
{ {
unregister_md_personality (MULTIPATH); unregister_md_personality (MULTIPATH);
} }
......
...@@ -7,6 +7,7 @@ struct multipath_info { ...@@ -7,6 +7,7 @@ struct multipath_info {
int number; int number;
int raid_disk; int raid_disk;
kdev_t dev; kdev_t dev;
struct block_device *bdev;
/* /*
* State bits: * State bits:
...@@ -25,7 +26,7 @@ struct multipath_private_data { ...@@ -25,7 +26,7 @@ struct multipath_private_data {
int working_disks; int working_disks;
mdk_thread_t *thread; mdk_thread_t *thread;
struct multipath_info *spare; struct multipath_info *spare;
md_spinlock_t device_lock; spinlock_t device_lock;
/* buffer pool */ /* buffer pool */
/* buffer_heads that we have pre-allocated have b_pprev -> &freebh /* buffer_heads that we have pre-allocated have b_pprev -> &freebh
...@@ -36,7 +37,7 @@ struct multipath_private_data { ...@@ -36,7 +37,7 @@ struct multipath_private_data {
struct multipath_bh *freer1; struct multipath_bh *freer1;
int freer1_blocked; int freer1_blocked;
int freer1_cnt; int freer1_cnt;
md_wait_queue_head_t wait_buffer; wait_queue_head_t wait_buffer;
}; };
typedef struct multipath_private_data multipath_conf_t; typedef struct multipath_private_data multipath_conf_t;
...@@ -60,8 +61,8 @@ struct multipath_bh { ...@@ -60,8 +61,8 @@ struct multipath_bh {
int cmd; int cmd;
unsigned long state; unsigned long state;
mddev_t *mddev; mddev_t *mddev;
struct buffer_head *master_bh; struct bio *master_bio;
struct buffer_head bh_req; struct bio *bio;
struct multipath_bh *next_mp; /* next for retry or in free list */ struct multipath_bh *next_mp; /* next for retry or in free list */
}; };
/* bits for multipath_bh.state */ /* bits for multipath_bh.state */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment