diff options
author | Mikulas Patocka <mpatocka@redhat.com> | 2012-12-21 20:23:41 +0000 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2012-12-21 20:23:41 +0000 |
commit | ee18026ac69efba804144541171299efd41747d2 (patch) | |
tree | 8e6e9e85114a6b6568b8325aca750428150d4b95 | |
parent | 59c3d2c6a12ff580b2c19c3925af4f4552639f8a (diff) |
dm snapshot: do not use map_context
Eliminate struct map_info from dm-snap.
map_info->ptr was used in dm-snap to indicate if the bio was tracked.
If map_info->ptr was non-NULL, the bio was linked in tracked_chunk_hash.
This patch removes the use of map_info->ptr. We determine if the bio was
tracked based on hlist_unhashed(&c->node). If hlist_unhashed is true,
the bio is not tracked, if it is false, the bio is tracked.
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
-rw-r--r-- | drivers/md/dm-snap.c | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index b7e179cdc5a..e1ecacf2456 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -190,9 +190,19 @@ struct dm_snap_tracked_chunk { chunk_t chunk; }; -static struct dm_snap_tracked_chunk *track_chunk(struct dm_snapshot *s, - struct bio *bio, - chunk_t chunk) +static void init_tracked_chunk(struct bio *bio) +{ + struct dm_snap_tracked_chunk *c = dm_per_bio_data(bio, sizeof(struct dm_snap_tracked_chunk)); + INIT_HLIST_NODE(&c->node); +} + +static bool is_bio_tracked(struct bio *bio) +{ + struct dm_snap_tracked_chunk *c = dm_per_bio_data(bio, sizeof(struct dm_snap_tracked_chunk)); + return !hlist_unhashed(&c->node); +} + +static void track_chunk(struct dm_snapshot *s, struct bio *bio, chunk_t chunk) { struct dm_snap_tracked_chunk *c = dm_per_bio_data(bio, sizeof(struct dm_snap_tracked_chunk)); @@ -202,13 +212,11 @@ static struct dm_snap_tracked_chunk *track_chunk(struct dm_snapshot *s, hlist_add_head(&c->node, &s->tracked_chunk_hash[DM_TRACKED_CHUNK_HASH(chunk)]); spin_unlock_irq(&s->tracked_chunk_lock); - - return c; } -static void stop_tracking_chunk(struct dm_snapshot *s, - struct dm_snap_tracked_chunk *c) +static void stop_tracking_chunk(struct dm_snapshot *s, struct bio *bio) { + struct dm_snap_tracked_chunk *c = dm_per_bio_data(bio, sizeof(struct dm_snap_tracked_chunk)); unsigned long flags; spin_lock_irqsave(&s->tracked_chunk_lock, flags); @@ -1568,6 +1576,8 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio, chunk_t chunk; struct dm_snap_pending_exception *pe = NULL; + init_tracked_chunk(bio); + if (bio->bi_rw & REQ_FLUSH) { bio->bi_bdev = s->cow->bdev; return DM_MAPIO_REMAPPED; @@ -1652,7 +1662,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio, } } else { bio->bi_bdev = s->origin->bdev; - map_context->ptr = track_chunk(s, bio, chunk); + track_chunk(s, bio, chunk); } out_unlock: @@ -1681,12 +1691,13 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio, int r = DM_MAPIO_REMAPPED; chunk_t chunk; + init_tracked_chunk(bio); + if (bio->bi_rw & REQ_FLUSH) { if (!dm_bio_get_target_request_nr(bio)) bio->bi_bdev = s->origin->bdev; else bio->bi_bdev = s->cow->bdev; - map_context->ptr = NULL; return DM_MAPIO_REMAPPED; } @@ -1715,7 +1726,7 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio, remap_exception(s, e, bio, chunk); if (bio_rw(bio) == WRITE) - map_context->ptr = track_chunk(s, bio, chunk); + track_chunk(s, bio, chunk); goto out_unlock; } @@ -1737,10 +1748,9 @@ static int snapshot_end_io(struct dm_target *ti, struct bio *bio, int error, union map_info *map_context) { struct dm_snapshot *s = ti->private; - struct dm_snap_tracked_chunk *c = map_context->ptr; - if (c) - stop_tracking_chunk(s, c); + if (is_bio_tracked(bio)) + stop_tracking_chunk(s, bio); return 0; } |