[dm-devel] Re: [PATCH-RFC] Bug in dm-raid1 as used by pvmove
Jonathan E Brassow
jbrassow at redhat.com
Fri May 19 04:45:09 UTC 2006
Sorry for not responding... earlier.
I didn't need the test case, because the more I looked at it, the more
obvious it became. I also quickly discovered the compile bug, and
mirror_map uses bio_ro_region now in newer kernels.
I've also check to make sure that it doesn't screw anything up when
fault tolerance is included (see http://www.brassow.com/mirroring). We
had to check to ensure that if bio_map was called (which alters the bio
and takes off the ti->begin) that a later function would not then call
the updated bio_to_region - effectively subtracting off ti->begin
twice.
thanks for the update though,
brassow
On May 18, 2006, at 8:17 PM, Neil Brown wrote:
> On Tuesday May 9, Jonathan E Brassow wrote:
>> It looks reasonable at first glance, but I have to think about it
>> more. Do you have a test case that I can reproduce with?
>
> Not really... The customer does, but I don't have precise details.
> I think is several drives, with several lvs across them, and active
> NFS activity on these.
> In this situation 'pvmove' everything off a device which contains a
> non-initial section of at least one of the lvs. The active traffic on
> the filesystem in an important part of the test case I think.
>
> I have since found that not only didn't the original patch compile,
> but it wasn't complete either.
>
> The mirror_map function sets map_context->ll to a value which is
> effectively the same as bio_to_region. As I changed bio_to_region, I
> need to change that assignment to.
>
> This is the current patch. Note that the declaration of two structures
> needed to be moved up for it to compile.
>
> NeilBrown
>
>
> Signed-off-by: Neil Brown <neilb at suse.de>
>
> ### Diffstat output
> ./drivers/md/dm-raid1.c | 63
> ++++++++++++++++++++++++------------------------
> 1 file changed, 32 insertions(+), 31 deletions(-)
>
> diff ./drivers/md/dm-raid1.c~current~ ./drivers/md/dm-raid1.c
> --- ./drivers/md/dm-raid1.c~current~ 2006-05-12 14:28:37.000000000
> +1000
> +++ ./drivers/md/dm-raid1.c 2006-05-19 11:15:58.000000000 +1000
> @@ -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 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.
> */
> @@ -1113,7 +1114,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);
>
> --
> dm-devel mailing list
> dm-devel at redhat.com
> https://www.redhat.com/mailman/listinfo/dm-devel
>
More information about the dm-devel
mailing list