dm-raid1: don't use map_info Don't use map_info. map_info was used for writes to hold the region number (for this purpose we add a new field dm_bio_details to dm_raid1_bio_record). map_info was used for reads to hold a pointer to dm_raid1_bio_record (if the pointer was non-NULL, bio details were saved; if the pointer was NULL, bio details were not saved). We use dm_raid1_bio_record.details->bi_bdev for this purpose. If bi_bdev is NULL, details were not saved, if bi_bdev is non-NULL, details were saved. Signed-off-by: Mikulas Patocka Index: linux-3.6.6-fast/drivers/md/dm-raid1.c =================================================================== --- linux-3.6.6-fast.orig/drivers/md/dm-raid1.c 2012-11-15 01:09:36.000000000 +0100 +++ linux-3.6.6-fast/drivers/md/dm-raid1.c 2012-11-15 01:09:38.000000000 +0100 @@ -143,7 +143,9 @@ static void dispatch_bios(void *context, struct dm_raid1_bio_record { struct mirror *m; + /* if details->bi_bdev == NULL, details were not saved */ struct dm_bio_details details; + region_t write_region; }; /* @@ -1143,18 +1145,21 @@ static void mirror_dtr(struct dm_target /* * Mirror mapping function */ -static int mirror_map(struct dm_target *ti, struct bio *bio, - union map_info *map_context) +static int mirror_map(struct dm_target *ti, struct bio *bio, + union map_info *map_context) { int r, rw = bio_rw(bio); struct mirror *m; struct mirror_set *ms = ti->private; - struct dm_raid1_bio_record *bio_record; struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh); + struct dm_raid1_bio_record *bio_record = + dm_bio_get_per_request_data(bio, sizeof(struct dm_raid1_bio_record)); + + bio_record->details.bi_bdev = NULL; if (rw == WRITE) { /* Save region for mirror_end_io() handler */ - map_context->ll = dm_rh_bio_to_region(ms->rh, bio); + bio_record->write_region = dm_rh_bio_to_region(ms->rh, bio); queue_bio(ms, bio, rw); return DM_MAPIO_SUBMITTED; } @@ -1182,9 +1186,7 @@ static int mirror_map(struct dm_target * if (unlikely(!m)) return -EIO; - bio_record = dm_bio_get_per_request_data(bio, sizeof(struct dm_raid1_bio_record)); dm_bio_record(&bio_record->details, bio); - map_context->ptr = bio_record; bio_record->m = m; map_bio(m, bio); @@ -1192,21 +1194,22 @@ static int mirror_map(struct dm_target * return DM_MAPIO_REMAPPED; } -static int mirror_end_io(struct dm_target *ti, struct bio *bio, - int error, union map_info *map_context) +static int mirror_end_io(struct dm_target *ti, struct bio *bio, + int error, union map_info *map_context) { int rw = bio_rw(bio); struct mirror_set *ms = (struct mirror_set *) ti->private; struct mirror *m = NULL; struct dm_bio_details *bd = NULL; - struct dm_raid1_bio_record *bio_record = map_context->ptr; + struct dm_raid1_bio_record *bio_record = + dm_bio_get_per_request_data(bio, sizeof(struct dm_raid1_bio_record)); /* * We need to dec pending if this was a write. */ if (rw == WRITE) { if (!(bio->bi_rw & (REQ_FLUSH | REQ_DISCARD))) - dm_rh_dec(ms->rh, map_context->ll); + dm_rh_dec(ms->rh, bio_record->write_region); return error; } @@ -1217,7 +1219,7 @@ static int mirror_end_io(struct dm_targe goto out; if (unlikely(error)) { - if (!bio_record) { + if (!bio_record->details.bi_bdev) { /* * There wasn't enough memory to record necessary * information for a retry or there was no other @@ -1242,7 +1244,7 @@ static int mirror_end_io(struct dm_targe bd = &bio_record->details; dm_bio_restore(bd, bio); - map_context->ptr = NULL; + bio_record->details.bi_bdev = NULL; queue_bio(ms, bio, rw); return DM_ENDIO_INCOMPLETE; } @@ -1250,7 +1252,7 @@ static int mirror_end_io(struct dm_targe } out: - map_context->ptr = NULL; + bio_record->details.bi_bdev = NULL; return error; }