From: Joe Thornber Subject: dm cache: add utility functions for hooking a bio's endio function [FIXME: not convinced these belong in DM, could/should be elevated to block layer. No benefit in dm-cache that I can see yet since it is only hooking/unhooking once] Signed-off-by: Joe Thornber Signed-off-by: Mike Snitzer --- drivers/md/dm-cache-target.c | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) Index: linux/drivers/md/dm-cache-target.c =================================================================== --- linux.orig/drivers/md/dm-cache-target.c +++ linux/drivers/md/dm-cache-target.c @@ -61,6 +61,34 @@ static void free_bitset(unsigned long *b /*----------------------------------------------------------------*/ +/* + * There are a couple of places where we let a bio run, but want to do some + * work before calling its endio function. We do this by temporarily + * changing the endio fn. + */ +struct hook_info { + bio_end_io_t *bi_end_io; + void *bi_private; +}; + +static void hook_bio(struct hook_info *h, struct bio *bio, + bio_end_io_t *bi_end_io, void *bi_private) +{ + h->bi_end_io = bio->bi_end_io; + h->bi_private = bio->bi_private; + + bio->bi_end_io = bi_end_io; + bio->bi_private = bi_private; +} + +static void unhook_bio(struct hook_info *h, struct bio *bio) +{ + bio->bi_end_io = h->bi_end_io; + bio->bi_private = h->bi_private; +} + +/*----------------------------------------------------------------*/ + #define PRISON_CELLS 1024 #define MIGRATION_POOL_SIZE 128 #define COMMIT_PERIOD HZ @@ -211,7 +239,7 @@ struct per_bio_data { */ struct cache *cache; dm_cblock_t cblock; - bio_end_io_t *saved_bi_end_io; + struct hook_info hook_info; struct dm_bio_details bio_details; }; @@ -662,7 +690,7 @@ static void defer_writethrough_bio(struc static void writethrough_endio(struct bio *bio, int err) { struct per_bio_data *pb = get_per_bio_data(bio, PB_DATA_SIZE_WT); - bio->bi_end_io = pb->saved_bi_end_io; + unhook_bio(&pb->hook_info, bio); if (err) { bio_endio(bio, err); @@ -693,9 +721,8 @@ static void remap_to_origin_then_cache(s pb->cache = cache; pb->cblock = cblock; - pb->saved_bi_end_io = bio->bi_end_io; + hook_bio(&pb->hook_info, bio, writethrough_endio, NULL); dm_bio_record(&pb->bio_details, bio); - bio->bi_end_io = writethrough_endio; remap_to_origin_clear_discard(pb->cache, bio, oblock); }