diff --git a/mdadm-2.6.4-519561f7.patch b/mdadm-2.6.4-519561f7.patch new file mode 100644 index 0000000..40abc2d --- /dev/null +++ b/mdadm-2.6.4-519561f7.patch @@ -0,0 +1,36 @@ +based on + + commit 519561f73f7ba987affde8b174d2691bb098439d + Author: Neil Brown + Date: Tue Apr 29 17:13:53 2008 +1000 + + Fix possible bug with bitmap space allocation with v1.0 metadata + + When adding a device to an array, make sure we don't reserve + so much space for the bitmap that there isn't room for the data. + +(minus the roff comments change) +--- + super1.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- super1.c.orig ++++ super1.c +@@ -903,7 +903,7 @@ static int write_init_super1(struct supe + * for a bitmap. + */ + array_size = __le64_to_cpu(sb->size); +- /* work out how much space we left of a bitmap */ ++ /* work out how much space we left for a bitmap */ + bm_space = choose_bm_space(array_size); + + switch(st->minor_version) { +@@ -913,6 +913,8 @@ static int write_init_super1(struct supe + sb_offset &= ~(4*2-1); + sb->super_offset = __cpu_to_le64(sb_offset); + sb->data_offset = __cpu_to_le64(0); ++ if (sb_offset - bm_space < array_size) ++ bm_space = sb_offset - array_size; + sb->data_size = __cpu_to_le64(sb_offset - bm_space); + break; + case 1: diff --git a/mdadm-2.6.4-6fb79233.patch b/mdadm-2.6.4-6fb79233.patch new file mode 100644 index 0000000..4ad2a98 --- /dev/null +++ b/mdadm-2.6.4-6fb79233.patch @@ -0,0 +1,70 @@ +based on + commit 6fb79233b050b4a3575f0e466ab04b5d301ac1de + Author: Neil Brown + Date: Mon Apr 28 16:30:09 2008 +1000 + + Allow creation of a RAID6 with a single missing device. + + This did not work before as we couldn't mark it clean as there would + be some parity blocks out of sync, and raid6 will not assemble a + dirty degraded array. + So make such arrays doubly degraded (the last device becomes a spare) + and clean. + +--- + Create.c | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +--- Create.c.orig ++++ Create.c +@@ -63,6 +63,7 @@ int Create(struct supertype *st, char *m + int fail=0, warn=0; + struct stat stb; + int first_missing = subdevs * 2; ++ int second_missing = subdevs * 2; + int missing_disks = 0; + int insert_point = subdevs * 2; /* where to insert a missing drive */ + void *super; +@@ -203,6 +204,8 @@ int Create(struct supertype *st, char *m + if (strcasecmp(dname, "missing")==0) { + if (first_missing > dnum) + first_missing = dnum; ++ if (second_missing > dnum && dnum > first_missing) ++ second_missing = dnum; + missing_disks ++; + continue; + } +@@ -341,6 +344,18 @@ int Create(struct supertype *st, char *m + break; + } + } ++ /* For raid6, if creating with 1 missing drive, make a good drive ++ * into a spare, else the create will fail ++ */ ++ if (assume_clean == 0 && force == 0 && first_missing < raiddisks && ++ second_missing >= raiddisks && level == 6) { ++ insert_point = raiddisks - 1; ++ if (insert_point == first_missing) ++ insert_point--; ++ sparedisks ++; ++ array.active_disks--; ++ missing_disks++; ++ } + + if (level <= 0 && first_missing != subdevs * 2) { + fprintf(stderr, +@@ -360,11 +375,12 @@ int Create(struct supertype *st, char *m + if (fstat(mdfd, &stb)==0) + array.md_minor = minor(stb.st_rdev); + array.not_persistent = 0; +- /*** FIX: Need to do something about RAID-6 here ***/ ++ + if ( ( (level == 4 || level == 5) && + (insert_point < raiddisks || first_missing < raiddisks) ) + || +- ( level == 6 && missing_disks == 2) ++ ( level == 6 && (insert_point < raiddisks ++ || second_missing < raiddisks)) + || + assume_clean + ) diff --git a/mdadm-2.6.4-7a3be72f.patch b/mdadm-2.6.4-7a3be72f.patch new file mode 100644 index 0000000..e4d21b1 --- /dev/null +++ b/mdadm-2.6.4-7a3be72f.patch @@ -0,0 +1,76 @@ +Based on + commit 7a3be72fc621b4a7589e923cf0652c51493f831a + Author: Neil Brown + Date: Mon Apr 28 16:29:37 2008 +1000 + + Fix problems with array.size overflowing on large arrays. + + array.size is 32bits and counts K. So for arrays with + more than 4Terrabytes, it can overflow. + The correct number can be read from sysfs, but there are still + a few places that use array.size and risk truncation. What is worse. + they compare a number of kilobytes with a number of sectors !! + + So use get_component_size() to read the sysfs information, and be + more consistent about units. + +--- + Detail.c | 2 +- + Manage.c | 14 ++++++++++++-- + 2 files changed, 13 insertions(+), 3 deletions(-) + +--- Detail.c.orig ++++ Detail.c +@@ -174,7 +174,7 @@ int Detail(char *dev, int brief, int exp + if (dsize > 0) + printf(" Used Dev Size : %llu%s\n", + dsize, +- human_size((long long)array.size<<10)); ++ human_size((long long)dsize<<10)); + else + printf(" Used Dev Size : unknown\n"); + } else +--- Manage.c.orig ++++ Manage.c +@@ -188,6 +188,7 @@ int Manage_subdevs(char *devname, int fd + */ + mdu_array_info_t array; + mdu_disk_info_t disc; ++ unsigned long long array_size; + mddev_dev_t dv, next = NULL; + struct stat stb; + int j, jnext = 0; +@@ -203,6 +204,15 @@ int Manage_subdevs(char *devname, int fd + devname); + return 1; + } ++ ++ /* array.size is only 32 bit and may be truncated. ++ * So read from sysfs if possible, and record number of sectors ++ */ ++ ++ array_size = get_component_size(fd); ++ if (array_size <= 0) ++ array_size = array.size * 2; ++ + for (dv = devlist, j=0 ; dv; dv = next, j = jnext) { + unsigned long long ldsize; + char dvname[20]; +@@ -335,7 +345,7 @@ int Manage_subdevs(char *devname, int fd + + /* Make sure device is large enough */ + if (st->ss->avail_size(st, ldsize/512) < +- array.size) { ++ array_size) { + fprintf(stderr, Name ": %s not large enough to join array\n", + dv->devname); + return 1; +@@ -409,7 +419,7 @@ int Manage_subdevs(char *devname, int fd + /* non-persistent. Must ensure that new drive + * is at least array.size big. + */ +- if (ldsize/512 < array.size) { ++ if (ldsize/512 < array_size) { + fprintf(stderr, Name ": %s not large enough to join array\n", + dv->devname); + return 1; diff --git a/mdadm.changes b/mdadm.changes index c72f71d..3c4c3ed 100644 --- a/mdadm.changes +++ b/mdadm.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Wed Apr 30 15:57:14 CEST 2008 - mmarek@suse.cz + +- added some fixes from Neil's git repo, fixing bnc#368704 among + others + ------------------------------------------------------------------- Mon Feb 4 19:24:54 CET 2008 - mmarek@suse.cz diff --git a/mdadm.spec b/mdadm.spec index f4ad773..23c9795 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -10,9 +10,10 @@ # norootforbuild + Name: mdadm Version: 2.6.4 -Release: 23 +Release: 37 BuildRequires: sgmltool PreReq: %fillup_prereq %insserv_prereq Obsoletes: raidtools @@ -27,6 +28,9 @@ Source1: Software-RAID.HOWTO.tar.bz2 Source2: sysconfig.mdadm Source3: mdadmd Source4: boot.md +Patch1: mdadm-2.6.4-7a3be72f.patch +Patch2: mdadm-2.6.4-6fb79233.patch +Patch3: mdadm-2.6.4-519561f7.patch %description Mdadm is a program that can be used to control Linux md devices. It is @@ -41,6 +45,9 @@ Authors: %prep %setup -q -a1 +%patch1 +%patch2 +%patch3 %build %{suse_update_config -f} @@ -115,6 +122,9 @@ rm -rf $RPM_BUILD_ROOT %{_var}/adm/fillup-templates/sysconfig.mdadm %changelog +* Wed Apr 30 2008 mmarek@suse.cz +- added some fixes from Neil's git repo, fixing bnc#368704 among + others * Mon Feb 04 2008 mmarek@suse.cz - correctly display rc_status in boot.md * Wed Jan 23 2008 mmarek@suse.cz