--- drivers/md/dm-thin.c | 54 ++++++++++++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 28 deletions(-) Index: linux-3.0-rc7/drivers/md/dm-thin.c =================================================================== --- linux-3.0-rc7.orig/drivers/md/dm-thin.c +++ linux-3.0-rc7/drivers/md/dm-thin.c @@ -508,9 +508,7 @@ struct thin_c { struct endio_hook { struct thin_c *tc; - bio_end_io_t *saved_bi_end_io; - struct deferred_entry *entry; }; @@ -535,17 +533,14 @@ struct new_mapping { bio_end_io_t *saved_bi_end_io; }; -#define save_and_set_bio_endio(m, bio, endio) \ -do { \ - (m)->saved_bi_end_io = (bio)->bi_end_io; \ - (bio)->bi_end_io = (endio); \ - dm_get_mapinfo((bio))->ptr = (m); \ -} while (0) - -#define restore_bio_endio(m, bio) \ -do { \ - (bio)->bi_end_io = (m)->saved_bi_end_io; \ -} while (0) +/*----------------------------------------------------------------*/ + +static void save_and_set_endio(struct bio *bio, bio_end_io_t **save, + bio_end_io_t *fn) +{ + *save = bio->bi_end_io; + bio->bi_end_io = fn; +} /*----------------------------------------------------------------*/ @@ -695,24 +690,25 @@ static void shared_read_endio(struct bio { struct list_head mappings; struct new_mapping *m, *tmp; - struct endio_hook *endio_hook = dm_get_mapinfo(bio)->ptr; + struct endio_hook *h = dm_get_mapinfo(bio)->ptr; unsigned long flags; + struct pool *pool = h->tc->pool; - restore_bio_endio(endio_hook, bio); + bio->bi_end_io = h->saved_bi_end_io; bio_endio(bio, err); INIT_LIST_HEAD(&mappings); - ds_dec(endio_hook->entry, &mappings); + ds_dec(h->entry, &mappings); - spin_lock_irqsave(&endio_hook->tc->pool->lock, flags); + spin_lock_irqsave(&pool->lock, flags); list_for_each_entry_safe(m, tmp, &mappings, list) { list_del(&m->list); INIT_LIST_HEAD(&m->list); __maybe_add_mapping(m); } - spin_unlock_irqrestore(&endio_hook->tc->pool->lock, flags); + spin_unlock_irqrestore(&pool->lock, flags); - mempool_free(endio_hook, endio_hook->tc->pool->endio_hook_pool); + mempool_free(h, pool->endio_hook_pool); } static int io_covers_block(struct pool *pool, struct bio *bio) @@ -746,7 +742,8 @@ static void schedule_copy(struct thin_c */ if (io_covers_block(pool, bio)) { m->bio = bio; - save_and_set_bio_endio(m, bio, overwrite_endio); + save_and_set_endio(bio, &m->saved_bi_end_io, overwrite_endio); + dm_get_mapinfo(bio)->ptr = m; remap_and_issue(tc, bio, data_dest); } else { struct dm_io_region from, to; @@ -793,7 +790,8 @@ static void schedule_zero(struct thin_c */ if (!pool->zero_new_blocks || io_covers_block(pool, bio)) { m->bio = bio; - save_and_set_bio_endio(m, bio, overwrite_endio); + save_and_set_endio(bio, &m->saved_bi_end_io, overwrite_endio); + dm_get_mapinfo(bio)->ptr = m; remap_and_issue(tc, bio, data_block); } else { int r; @@ -967,7 +965,6 @@ static void process_shared_bio(struct th struct cell *cell; struct cell_key key; struct pool *pool = tc->pool; - struct endio_hook *endio_hook; /* * If cell is already occupied, then sharing is already @@ -981,12 +978,13 @@ static void process_shared_bio(struct th if (bio_data_dir(bio) == WRITE) break_sharing(tc, bio, block, &key, lookup_result); else { - endio_hook = mempool_alloc(pool->endio_hook_pool, GFP_NOIO); - - endio_hook->tc = tc; - endio_hook->entry = ds_inc(&pool->ds); - save_and_set_bio_endio(endio_hook, bio, shared_read_endio); + struct endio_hook *h; + h = mempool_alloc(pool->endio_hook_pool, GFP_NOIO); + h->tc = tc; + h->entry = ds_inc(&pool->ds); + save_and_set_endio(bio, &h->saved_bi_end_io, shared_read_endio); + dm_get_mapinfo(bio)->ptr = h; remap_and_issue(tc, bio, lookup_result->block); } } @@ -1093,7 +1091,7 @@ static void process_prepared_mapping(str bio = m->bio; if (bio) - restore_bio_endio(m, bio); + bio->bi_end_io = m->saved_bi_end_io; r = dm_thin_metadata_insert(tc->td, m->virt_block, m->data_block); if (r) {