There are lots of mutable fields in the bio struct. These get changed by the lower levels of the block layer. This led us to try and record these fields, and restore them before passing the bio into our endio target method. Mike Christie pointed out 2 problems with this: i) Although we record _after_ the bio has been mapped, there's a possible race if the target has decided to take over submission of the io (as snapshots do). ii) We do not re-record after the endio function has remapped, and even if we did, it would be susceptable to the same race as (i). So we're going to say that the targets themselves are responsible for this record/restore process. This particular patch strips out record/restore from dm.c --- diff/drivers/md/dm.c 2004-02-25 09:59:19.000000000 +0000 +++ source/drivers/md/dm.c 2004-02-25 10:00:13.000000000 +0000 @@ -39,11 +39,6 @@ struct target_io { struct dm_io *io; struct dm_target *ti; union map_info info; - - sector_t bi_sector; - struct block_device *bi_bdev; - unsigned int bi_size; - unsigned short bi_idx; }; /* @@ -282,12 +277,6 @@ static int clone_endio(struct bio *bio, return 1; if (endio) { - /* Restore bio fields. */ - bio->bi_sector = tio->bi_sector; - bio->bi_bdev = tio->bi_bdev; - bio->bi_size = tio->bi_size; - bio->bi_idx = tio->bi_idx; - r = endio(tio->ti, bio, error, &tio->info); if (r < 0) error = r; @@ -343,16 +332,9 @@ static void __map_bio(struct dm_target * */ atomic_inc(&tio->io->io_count); r = ti->type->map(ti, clone, &tio->info); - if (r > 0) { - /* Save the bio info so we can restore it during endio. */ - tio->bi_sector = clone->bi_sector; - tio->bi_bdev = clone->bi_bdev; - tio->bi_size = clone->bi_size; - tio->bi_idx = clone->bi_idx; - + if (r > 0) /* the bio has been remapped so dispatch it */ generic_make_request(clone); - } else if (r < 0) { /* error the io and bail out */