[RFC][PATCH 7/10] I/O context inheritance

From: Hirokazu Takahashi
Date: Tue Apr 22 2008 - 09:57:32 EST



The raid5 module makes use of temporary bios to issue several I/O requests
in the same stripe, whenever it gets a write I/O request. In this case,
the temporary bios should inherit the iocontext from the source bio.

And the module also makes use of temporary bios to sync physical disks
under the same md device. In this case, these bios point the iocontext of
one of the kernel threads in the module.

Signed-off-by: Hirokazu Takahashi <taka@xxxxxxxxxxxxx>


--- linux-2.6.25.bio0/include/linux/raid/raid5.h 2008-04-22 15:48:32.000000000 +0900
+++ linux-2.6.25/include/linux/raid/raid5.h 2008-04-22 15:53:09.000000000 +0900
@@ -169,6 +169,7 @@ struct stripe_head {
spinlock_t lock;
int bm_seq; /* sequence number for bitmap flushes */
int disks; /* disks in stripe */
+ struct io_context *io_context;
/* stripe_operations
* @pending - pending ops flags (set for request->issue->complete)
* @ack - submitted ops flags (set for issue->complete)
--- linux-2.6.25.bio0/drivers/md/raid5.c 2008-04-22 15:48:32.000000000 +0900
+++ linux-2.6.25/drivers/md/raid5.c 2008-04-22 18:51:13.000000000 +0900
@@ -148,6 +148,8 @@ static void __release_stripe(raid5_conf_
}
atomic_dec(&conf->active_stripes);
if (!test_bit(STRIPE_EXPANDING, &sh->state)) {
+ put_io_context(sh->io_context);
+ sh->io_context = NULL;
list_add_tail(&sh->lru, &conf->inactive_list);
wake_up(&conf->wait_for_stripe);
if (conf->retry_read_aligned)
@@ -235,7 +237,7 @@ static int grow_buffers(struct stripe_he

static void raid5_build_block (struct stripe_head *sh, int i);

-static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int disks)
+static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int disks, struct bio *bi)
{
raid5_conf_t *conf = sh->raid_conf;
int i;
@@ -253,6 +255,10 @@ static void init_stripe(struct stripe_he
sh->sector = sector;
sh->pd_idx = pd_idx;
sh->state = 0;
+ if (bi)
+ sh->io_context = ioc_object_link(bi->bi_io_context);
+ else
+ sh->io_context = ioc_object_link(current->io_context);

sh->disks = disks;

@@ -291,7 +297,7 @@ static void unplug_slaves(mddev_t *mddev
static void raid5_unplug_device(struct request_queue *q);

static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector, int disks,
- int pd_idx, int noblock)
+ int pd_idx, int noblock, struct bio *bi)
{
struct stripe_head *sh;

@@ -321,7 +327,7 @@ static struct stripe_head *get_active_st
);
conf->inactive_blocked = 0;
} else
- init_stripe(sh, sector, pd_idx, disks);
+ init_stripe(sh, sector, pd_idx, disks, bi);
} else {
if (atomic_read(&sh->count)) {
BUG_ON(!list_empty(&sh->lru));
@@ -412,10 +418,19 @@ static void ops_run_io(struct stripe_hea
bi = &sh->dev[i].req;

bi->bi_rw = rw;
- if (rw == WRITE)
+ if (rw == WRITE) {
bi->bi_end_io = raid5_end_write_request;
- else
+ if (sh->dev[i].towrite) {
+ bi->bi_io_context = sh->dev[i].towrite->bi_io_context;
+ }
+ } else {
bi->bi_end_io = raid5_end_read_request;
+ if (sh->dev[i].toread) {
+ bi->bi_io_context = sh->dev[i].toread->bi_io_context;
+ }
+ }
+ if (!bi->bi_io_context)
+ bi->bi_io_context = sh->io_context;

rcu_read_lock();
rdev = rcu_dereference(conf->disks[i].rdev);
@@ -2551,7 +2566,7 @@ static void handle_stripe_expansion(raid
conf->max_degraded, &dd_idx,
&pd_idx, conf);
sh2 = get_active_stripe(conf, s, conf->raid_disks,
- pd_idx, 1);
+ pd_idx, 1, NULL);
if (sh2 == NULL)
/* so far only the early blocks of this stripe
* have been requested. When later blocks
@@ -3512,7 +3527,7 @@ static int make_request(struct request_q
(unsigned long long)new_sector,
(unsigned long long)logical_sector);

- sh = get_active_stripe(conf, new_sector, disks, pd_idx, (bi->bi_rw&RWA_MASK));
+ sh = get_active_stripe(conf, new_sector, disks, pd_idx, (bi->bi_rw&RWA_MASK), bi);
if (sh) {
if (unlikely(conf->expand_progress != MaxSector)) {
/* expansion might have moved on while waiting for a
@@ -3650,7 +3665,7 @@ static sector_t reshape_request(mddev_t
int skipped = 0;
pd_idx = stripe_to_pdidx(sector_nr+i, conf, conf->raid_disks);
sh = get_active_stripe(conf, sector_nr+i,
- conf->raid_disks, pd_idx, 0);
+ conf->raid_disks, pd_idx, 0, NULL);
set_bit(STRIPE_EXPANDING, &sh->state);
atomic_inc(&conf->reshape_stripes);
/* If any of this stripe is beyond the end of the old
@@ -3701,7 +3716,7 @@ static sector_t reshape_request(mddev_t
pd_idx = stripe_to_pdidx(first_sector, conf,
conf->previous_raid_disks);
sh = get_active_stripe(conf, first_sector,
- conf->previous_raid_disks, pd_idx, 0);
+ conf->previous_raid_disks, pd_idx, 0, NULL);
set_bit(STRIPE_EXPAND_SOURCE, &sh->state);
set_bit(STRIPE_HANDLE, &sh->state);
release_stripe(sh);
@@ -3791,9 +3806,9 @@ static inline sector_t sync_request(mdde
bitmap_cond_end_sync(mddev->bitmap, sector_nr);

pd_idx = stripe_to_pdidx(sector_nr, conf, raid_disks);
- sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 1);
+ sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 1, NULL);
if (sh == NULL) {
- sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 0);
+ sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 0, NULL);
/* make sure we don't swamp the stripe cache if someone else
* is trying to get access
*/
@@ -3857,7 +3872,7 @@ static int retry_aligned_read(raid5_con
/* already done this stripe */
continue;

- sh = get_active_stripe(conf, sector, conf->raid_disks, pd_idx, 1);
+ sh = get_active_stripe(conf, sector, conf->raid_disks, pd_idx, 1, raid_bio);

if (!sh) {
/* failed to get a stripe - must wait */
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/