mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 08:44:41 +00:00 
			
		
		
		
	[PATCH] 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: Neil Brown <neilb@suse.de> Signed-off-by: Alasdair G Kergon <agk@redhat.com> Cc: <stable@kernel.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
		
							parent
							
								
									f0b0411536
								
							
						
					
					
						commit
						e4c8b3ba34
					
				
					 1 changed files with 32 additions and 31 deletions
				
			
		|  | @ -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) | ||||
|  | @ -539,35 +569,6 @@ static void rh_start_recovery(struct region_hash *rh) | |||
| 	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. | ||||
|  */ | ||||
|  | @ -1113,7 +1114,7 @@ static int mirror_map(struct dm_target *ti, struct bio *bio, | |||
| 	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); | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Neil Brown
						Neil Brown