lkml.org 
[lkml]   [2006]   [May]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH 10/10] dm: mirror sector offset fix
From: Neil Brown <neilb@suse.de>

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.

Signed-off-by: Neil Brown <neilb@suse.de>
Signed-Off-By: Alasdair G Kergon <agk@redhat.com>

Index: linux-2.6.17-rc4/drivers/md/dm-raid1.c
===================================================================
--- linux-2.6.17-rc4.orig/drivers/md/dm-raid1.c 2006-05-23 17:05:30.000000000 +0100
+++ linux-2.6.17-rc4/drivers/md/dm-raid1.c 2006-05-23 21:53:42.000000000 +0100
@@ -106,12 +106,42 @@ struct region {
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
*/
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)
@@ -541,35 +571,6 @@ static void rh_start_recovery(struct reg
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.
*/
@@ -1115,7 +1116,7 @@ static int mirror_map(struct dm_target *
struct mirror *m;
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) {
queue_bio(ms, bio, rw);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
\
 
 \ /
  Last update: 2006-05-25 21:32    [W:0.029 / U:1.808 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site