[dm-devel] [PATCH] 1/9: Save and restore bio fields
Kevin Corry
kevcorry at us.ibm.com
Tue Jan 13 16:55:02 UTC 2004
When a bio is submitted to the block-layer, several of the fields in that bio
will have changed by the time it completes. In particular, the bi_sector
field will be different, the bi_size field will be zero, and the bi_bdev and
bi_idx fields may have changed as well. This creates a problem for some
of the Device-Mapper modules (like dm-multipath) that may want to redrive a
bio.
Save the necessary bio fields in the target_io structure just before calling
generic_make_request(), and restore those bio fields just before calling the
target's end_io() routine. This ensures that the target module sees the bio
exactly as it was following the map() routine.
--- diff/drivers/md/dm.c 2004-01-13 15:05:54.000000000 -0600
+++ source/drivers/md/dm.c 2004-01-13 15:07:32.000000000 -0600
@@ -42,6 +42,11 @@
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;
};
/*
@@ -276,13 +281,19 @@
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;
else if (r > 0)
/* the target wants another shot at the io */
- return 1; /* FIXME: do we need to reset bio at all ? */
+ return 1;
}
free_tio(io->md, tio);
@@ -331,9 +342,16 @@
*/
atomic_inc(&tio->io->io_count);
r = ti->type->map(ti, clone, &tio->info);
- if (r > 0)
+ 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;
+
/* the bio has been remapped so dispatch it */
generic_make_request(clone);
+ }
else if (r < 0) {
/* error the io and bail out */
More information about the dm-devel
mailing list