From f6d75de8e0106a3789ed1a3aada306d197531e47 Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Mon, 12 Sep 2005 05:24:10 +0000 Subject: [PATCH] Fix remaining problems with hot-add bitmap to version-1 superblock Also some more tests - r5 and r6 bitmaps Signed-off-by: Neil Brown --- ChangeLog | 2 ++ bitmap.c | 2 +- mdadm.h | 2 +- super0.c | 2 +- super1.c | 15 ++++++++---- tests/00linear | 2 +- tests/00raid0 | 4 ++-- tests/00raid1 | 2 +- tests/00raid4 | 2 +- tests/00raid5 | 4 ++-- tests/00raid6 | 2 +- tests/05r5-bitmapfile | 48 +++++++++++++++++++++++++++++++++++++++ tests/05r5-internalbitmap | 46 +++++++++++++++++++++++++++++++++++++ tests/05r6-bitmapfile | 48 +++++++++++++++++++++++++++++++++++++++ 14 files changed, 165 insertions(+), 16 deletions(-) create mode 100644 tests/05r5-bitmapfile create mode 100644 tests/05r5-internalbitmap create mode 100644 tests/05r6-bitmapfile diff --git a/ChangeLog b/ChangeLog index b67e2a91..cb66fc48 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,8 @@ Changes Prior to this release - Fix assembling of arrays that use the version-1 superblock and have spares. Previously the spares would be ignored. - Fix bug so that multiple drives can be re-added at once. + - Fix problem with hot-adding a bitmap to version-1-superblock + arrays. Changes Prior to 2.0 - Support assembling from byte-swapped superblocks diff --git a/bitmap.c b/bitmap.c index 5252069b..82da00a1 100644 --- a/bitmap.c +++ b/bitmap.c @@ -198,7 +198,7 @@ bitmap_info_t *bitmap_file_read(char *filename, int brief, struct supertype **st /* just look at device... */ lseek(fd, 0, 0); } else { - st->ss->locate_bitmap(st, fd); + st->ss->locate_bitmap(st, fd, NULL); } ioctl(fd, BLKFLSBUF, 0); /* make sure we read current data */ *stp = st; diff --git a/mdadm.h b/mdadm.h index 65fa8240..3557c027 100644 --- a/mdadm.h +++ b/mdadm.h @@ -191,7 +191,7 @@ extern struct superswitch { struct supertype * (*match_metadata_desc)(char *arg); __u64 (*avail_size)(struct supertype *st, __u64 size); int (*add_internal_bitmap)(struct supertype *st, void *sbv, int chunk, int delay, int write_behind, int *sizep, int may_change); - void (*locate_bitmap)(struct supertype *st, int fd); + void (*locate_bitmap)(struct supertype *st, int fd, void *sbv); int (*write_bitmap)(struct supertype *st, int fd, void *sbv); int major; int swapuuid; /* true if uuid is bigending rather than hostendian */ diff --git a/super0.c b/super0.c index 916db542..95968d30 100644 --- a/super0.c +++ b/super0.c @@ -701,7 +701,7 @@ static int add_internal_bitmap0(struct supertype *st, void *sbv, int chunk, int } -void locate_bitmap0(struct supertype *st, int fd) +void locate_bitmap0(struct supertype *st, int fd, void *sbv) { unsigned long long dsize; unsigned long size; diff --git a/super1.c b/super1.c index 00da4975..43607ba6 100644 --- a/super1.c +++ b/super1.c @@ -892,16 +892,21 @@ add_internal_bitmap1(struct supertype *st, void *sbv, } -void locate_bitmap1(struct supertype *st, int fd) +void locate_bitmap1(struct supertype *st, int fd, void *sbv) { unsigned long long offset; struct mdp_superblock_1 *sb; - if (st->ss->load_super(st, fd, (void**)&sb, NULL)) - return; /* no error I hope... */ + if (sbv) + sb = sbv; + else { + if (st->ss->load_super(st, fd, (void**)&sb, NULL)) + return; /* no error I hope... */ + } offset = __le64_to_cpu(sb->super_offset); offset += (long) __le32_to_cpu(sb->bitmap_offset); - + if (!sbv) + free(sb); lseek64(fd, offset<<9, 0); } @@ -914,7 +919,7 @@ int write_bitmap1(struct supertype *st, int fd, void *sbv) int towrite, n; char buf[4096]; - locate_bitmap1(st, fd); + locate_bitmap1(st, fd, sbv); write(fd, ((char*)sb)+1024, sizeof(bitmap_super_t)); towrite = __le64_to_cpu(bms->sync_size) / (__le32_to_cpu(bms->chunksize)>>9); diff --git a/tests/00linear b/tests/00linear index 6f08ba0c..ec6a1667 100644 --- a/tests/00linear +++ b/tests/00linear @@ -6,7 +6,7 @@ check linear testdev $md0 3 $mdsize0 64 mdadm -S $md0 -# now with verion-1 superblock +# now with version-1 superblock mdadm -CR $md0 -e1 --level=linear -n4 $dev0 $dev1 $dev2 $dev3 check linear testdev $md0 4 $mdsize1 64 diff --git a/tests/00raid0 b/tests/00raid0 index 07437c08..f5122ec6 100644 --- a/tests/00raid0 +++ b/tests/00raid0 @@ -6,7 +6,7 @@ check raid0 testdev $md0 3 $mdsize0 64 mdadm -S $md0 -# now with verion-1 superblock +# now with version-1 superblock mdadm -CR $md0 -e1 -l0 -n4 $dev0 $dev1 $dev2 $dev3 check raid0 testdev $md0 4 $mdsize1 64 @@ -27,7 +27,7 @@ do testdev $md0 3 $mdsize0 $chunk mdadm -S $md0 - # now with verion-1 superblock + # now with version-1 superblock mdadm -CR $md0 -e1 -l0 -c $chunk -n4 $dev0 $dev1 $dev2 $dev3 check raid0 testdev $md0 4 $mdsize1 $chunk diff --git a/tests/00raid1 b/tests/00raid1 index af40da4c..b0dfa6a9 100644 --- a/tests/00raid1 +++ b/tests/00raid1 @@ -9,7 +9,7 @@ check raid1 testdev $md0 1 $mdsize0 1 mdadm -S $md0 -# now with verion-1 superblock, spare +# now with version-1 superblock, spare mdadm -CR $md0 -e1 --level=raid1 -n3 -x2 $dev0 missing missing $dev1 $dev2 check recovery check raid1 diff --git a/tests/00raid4 b/tests/00raid4 index a45668ab..46383873 100644 --- a/tests/00raid4 +++ b/tests/00raid4 @@ -6,7 +6,7 @@ check resync ; check raid5 testdev $md0 2 $mdsize0 64 mdadm -S $md0 -# now with verion-1 superblock +# now with version-1 superblock mdadm -CR $md0 -e1 --level=raid4 -n4 $dev0 $dev1 $dev2 $dev3 check resync; check raid5 testdev $md0 3 $mdsize1 64 diff --git a/tests/00raid5 b/tests/00raid5 index 7192ac53..71f36545 100644 --- a/tests/00raid5 +++ b/tests/00raid5 @@ -6,7 +6,7 @@ check resync testdev $md0 2 $mdsize0 64 mdadm -S $md0 -# now with verion-1 superblock +# now with version-1 superblock mdadm -CR $md0 -e1 --level=raid5 -n4 $dev0 $dev1 $dev2 $dev3 check recovery testdev $md0 3 $mdsize1 64 @@ -22,7 +22,7 @@ do testdev $md0 2 $mdsize0 64 mdadm -S $md0 - # now with verion-1 superblock + # now with version-1 superblock mdadm -CR $md0 -e1 --level=raid5 --layout $lo -n4 $dev0 $dev1 $dev2 $dev3 check recovery ; check raid5 testdev $md0 3 $mdsize1 64 diff --git a/tests/00raid6 b/tests/00raid6 index ba8c61cf..81834aae 100644 --- a/tests/00raid6 +++ b/tests/00raid6 @@ -6,7 +6,7 @@ check resync ; check raid6 testdev $md0 2 $mdsize0 64 mdadm -S $md0 -# now with verion-1 superblock +# now with version-1 superblock mdadm -CR $md0 -e1 --level=raid6 -n5 $dev0 $dev1 $dev2 $dev3 $dev4 check resync ; check raid6 testdev $md0 3 $mdsize1 64 diff --git a/tests/05r5-bitmapfile b/tests/05r5-bitmapfile new file mode 100644 index 00000000..25c12287 --- /dev/null +++ b/tests/05r5-bitmapfile @@ -0,0 +1,48 @@ + +# +# create a raid1 with a bitmap file +# +bmf=$targetdir/bitmap +rm -f $bmf +mdadm --create --run $md0 --level=5 -n3 --delay=1 --bitmap $bmf $dev1 $dev2 $dev3 +check wait +testdev $md0 2 $mdsize0 1 +mdadm -S $md0 + +mdadm --assemble $md0 --bitmap=$bmf $dev1 $dev2 $dev3 +testdev $md0 2 $mdsize0 1 +dirty1=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +sleep 4 +dirty2=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + +if [ $dirty1 -lt 400 -o $dirty2 -ne 0 ] +then echo >&2 "ERROR bad 'dirty' counts: $dirty1 and $dirty2" + exit 1 +fi +mdadm $md0 -f $dev1 +testdev $md0 2 $mdsize0 1 +sleep 4 +dirty3=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +if [ $dirty3 -lt 400 ] +then + echo >&2 "ERROR dirty count $dirty3 is too small" + exit 2 +fi + +mdadm -S $md0 + +mdadm --assemble -R $md0 --bitmap=$bmf $dev2 $dev3 +mdadm $md0 --add $dev1 +check recovery + +dirty4=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +check wait +sleep 4 +dirty5=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + +if [ $dirty4 -lt 400 -o $dirty5 -ne 0 ] +then echo echo >&2 "ERROR bad 'dirty' counts at end: $dirty4 $dirty5" + exit 1 +fi + +mdadm -S $md0 diff --git a/tests/05r5-internalbitmap b/tests/05r5-internalbitmap new file mode 100644 index 00000000..d79db909 --- /dev/null +++ b/tests/05r5-internalbitmap @@ -0,0 +1,46 @@ + +# +# create a raid1 with an internal bitmap +# +mdadm --create --run $md0 --level=5 -n3 --delay=1 --bitmap internal $dev1 $dev2 $dev3 +check wait +testdev $md0 2 $mdsize0 1 +mdadm -S $md0 + +mdadm --assemble $md0 $dev1 $dev2 $dev3 +testdev $md0 2 $mdsize0 1 +dirty1=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +sleep 4 +dirty2=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + +if [ $dirty1 -lt 400 -o $dirty2 -ne 0 ] +then echo >&2 "ERROR bad 'dirty' counts: $dirty1 and $dirty2" + exit 1 +fi +mdadm $md0 -f $dev1 +testdev $md0 2 $mdsize0 1 +sleep 4 +dirty3=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +if [ $dirty3 -lt 400 ] +then + echo >&2 "ERROR dirty count $dirty3 is too small" + exit 2 +fi + +mdadm -S $md0 + +mdadm --assemble -R $md0 $dev2 $dev3 +mdadm $md0 --add $dev1 +check recovery + +dirty4=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +check wait +sleep 4 +dirty5=`mdadm -X $dev2 | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + +if [ $dirty4 -lt 400 -o $dirty5 -ne 0 ] +then echo echo >&2 "ERROR bad 'dirty' counts at end: $dirty4 $dirty5" + exit 1 +fi + +mdadm -S $md0 diff --git a/tests/05r6-bitmapfile b/tests/05r6-bitmapfile new file mode 100644 index 00000000..865cedbb --- /dev/null +++ b/tests/05r6-bitmapfile @@ -0,0 +1,48 @@ + +# +# create a raid1 with a bitmap file +# +bmf=$targetdir/bitmap +rm -f $bmf +mdadm --create --run $md0 --level=6 -n4 --delay=1 --bitmap $bmf $dev1 $dev2 $dev3 $dev4 +check wait +testdev $md0 2 $mdsize0 1 +mdadm -S $md0 + +mdadm --assemble $md0 --bitmap=$bmf $dev1 $dev2 $dev3 $dev4 +testdev $md0 2 $mdsize0 1 +dirty1=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +sleep 4 +dirty2=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + +if [ $dirty1 -lt 400 -o $dirty2 -ne 0 ] +then echo >&2 "ERROR bad 'dirty' counts: $dirty1 and $dirty2" + exit 1 +fi +mdadm $md0 -f $dev3 +testdev $md0 2 $mdsize0 1 +sleep 4 +dirty3=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +if [ $dirty3 -lt 400 ] +then + echo >&2 "ERROR dirty count $dirty3 is too small" + exit 2 +fi + +mdadm -S $md0 + +mdadm --assemble -R $md0 --bitmap=$bmf $dev1 $dev2 $dev4 +mdadm $md0 --add $dev3 +check recovery + +dirty4=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` +check wait +sleep 4 +dirty5=`mdadm -X $bmf | sed -n -e 's/.*Bitmap.* \([0-9]*\) dirty.*/\1/p'` + +if [ $dirty4 -lt 400 -o $dirty5 -ne 0 ] +then echo echo >&2 "ERROR bad 'dirty' counts at end: $dirty4 $dirty5" + exit 1 +fi + +mdadm -S $md0 -- 2.39.2