Commit 8135c5c1 authored by Neil Brown's avatar Neil Brown Committed by Greg Kroah-Hartman

dm: mirror sector offset fix

The device-mapper core does not perform any remapping of bios before passing
them to the targets.  If a particular mapping begins part-way into a device,
targets obtain the sector relative to the start of the mapping by subtracting
ti->begin.

The dm-raid1 target didn't do this everywhere: this patch fixes it, taking
care to subtract ti->begin exactly once for each bio.

[akpm: too late for 2.6.17 - suitable for 2.6.17.x after it has settled]
Signed-off-by: default avatarNeil Brown <neilb@suse.de>
Signed-off-by: default avatarAlasdair G Kergon <agk@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 16470822
...@@ -106,12 +106,42 @@ struct region { ...@@ -106,12 +106,42 @@ struct region {
struct bio_list delayed_bios; struct bio_list delayed_bios;
}; };
/*-----------------------------------------------------------------
* Mirror set structures.
*---------------------------------------------------------------*/
struct mirror {
atomic_t error_count;
struct dm_dev *dev;
sector_t offset;
};
struct mirror_set {
struct dm_target *ti;
struct list_head list;
struct region_hash rh;
struct kcopyd_client *kcopyd_client;
spinlock_t lock; /* protects the next two lists */
struct bio_list reads;
struct bio_list writes;
/* recovery */
region_t nr_regions;
int in_sync;
struct mirror *default_mirror; /* Default mirror */
unsigned int nr_mirrors;
struct mirror mirror[0];
};
/* /*
* Conversion fns * Conversion fns
*/ */
static inline region_t bio_to_region(struct region_hash *rh, struct bio *bio) static inline region_t bio_to_region(struct region_hash *rh, struct bio *bio)
{ {
return bio->bi_sector >> rh->region_shift; return (bio->bi_sector - rh->ms->ti->begin) >> rh->region_shift;
} }
static inline sector_t region_to_sector(struct region_hash *rh, region_t region) static inline sector_t region_to_sector(struct region_hash *rh, region_t region)
...@@ -541,35 +571,6 @@ static void rh_start_recovery(struct region_hash *rh) ...@@ -541,35 +571,6 @@ static void rh_start_recovery(struct region_hash *rh)
wake(); wake();
} }
/*-----------------------------------------------------------------
* Mirror set structures.
*---------------------------------------------------------------*/
struct mirror {
atomic_t error_count;
struct dm_dev *dev;
sector_t offset;
};
struct mirror_set {
struct dm_target *ti;
struct list_head list;
struct region_hash rh;
struct kcopyd_client *kcopyd_client;
spinlock_t lock; /* protects the next two lists */
struct bio_list reads;
struct bio_list writes;
/* recovery */
region_t nr_regions;
int in_sync;
struct mirror *default_mirror; /* Default mirror */
unsigned int nr_mirrors;
struct mirror mirror[0];
};
/* /*
* Every mirror should look like this one. * Every mirror should look like this one.
*/ */
...@@ -1115,7 +1116,7 @@ static int mirror_map(struct dm_target *ti, struct bio *bio, ...@@ -1115,7 +1116,7 @@ static int mirror_map(struct dm_target *ti, struct bio *bio,
struct mirror *m; struct mirror *m;
struct mirror_set *ms = ti->private; struct mirror_set *ms = ti->private;
map_context->ll = bio->bi_sector >> ms->rh.region_shift; map_context->ll = bio_to_region(&ms->rh, bio);
if (rw == WRITE) { if (rw == WRITE) {
queue_bio(ms, bio, rw); queue_bio(ms, bio, rw);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment