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 */ -- dm-devel mailing list dm-devel@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/dm-devel