From 8157b0be5f1645ed42887bae3a4d05bff7e5660bd41c1927f5bbb8111ca99d3c Mon Sep 17 00:00:00 2001 From: OBS User unknown Date: Tue, 17 Mar 2009 19:08:56 +0000 Subject: [PATCH] OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/mdadm?expand=0&rev=30 --- mdadm.changes | 8 + mdadm.spec | 10 +- ...-metadata-IO-with-4096byte-alignment.patch | 86 +++++++++++ ...-do-metadata-IO-in-sector_size-units.patch | 137 ++++++++++++++++++ 4 files changed, 240 insertions(+), 1 deletion(-) create mode 100644 super0-Do-all-metadata-IO-with-4096byte-alignment.patch create mode 100644 super1-do-metadata-IO-in-sector_size-units.patch diff --git a/mdadm.changes b/mdadm.changes index 4af4caf..e7f70a7 100644 --- a/mdadm.changes +++ b/mdadm.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Tue Mar 3 10:36:11 CET 2009 - mmarek@suse.cz + +- super0: Do all metadata IO with 4096byte alignment +- super1 - do metadata IO in sector_size units. + (bnc#466172) + + ------------------------------------------------------------------- Sat Feb 21 15:37:55 CET 2009 - mmarek@suse.cz diff --git a/mdadm.spec b/mdadm.spec index 03db28b..0b1cd00 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -20,7 +20,7 @@ Name: mdadm Version: 3.0 -Release: 19 +Release: 20 %define ver 3.0-devel2 BuildRequires: sgmltool PreReq: %fillup_prereq %insserv_prereq @@ -43,6 +43,8 @@ Patch8: name.fixes.patch Patch9: mdmon-pass-symbolic-name-to-mdmon-instead-of-device.patch Patch10: don-t-auto-assemble-if-any-arrays-are-list.patch Patch11: manage-rebuild-map-for-kpartx +Patch12: super0-Do-all-metadata-IO-with-4096byte-alignment.patch +Patch13: super1-do-metadata-IO-in-sector_size-units.patch Source1: Software-RAID.HOWTO.tar.bz2 Source2: sysconfig.mdadm Source3: mdadmd @@ -74,6 +76,8 @@ Authors: %patch9 -p1 %patch10 -p1 %patch11 -p1 +%patch12 -p1 +%patch13 -p1 %build %{suse_update_config -f} @@ -162,6 +166,10 @@ rm -rf $RPM_BUILD_ROOT /lib/mkinitrd/scripts/boot-md.sh %changelog +* Tue Mar 03 2009 mmarek@suse.cz +- super0: Do all metadata IO with 4096byte alignment +- super1 - do metadata IO in sector_size units. + (bnc#466172) * Sat Feb 21 2009 mmarek@suse.cz - mkinitrd-setup.sh: filter out duplicate devices (bnc#461673, patch by Xin Wei Hu) diff --git a/super0-Do-all-metadata-IO-with-4096byte-alignment.patch b/super0-Do-all-metadata-IO-with-4096byte-alignment.patch new file mode 100644 index 0000000..bebc318 --- /dev/null +++ b/super0-Do-all-metadata-IO-with-4096byte-alignment.patch @@ -0,0 +1,86 @@ +From 24303a80dfff51654595b3605fa8b1b9b1c4b578 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Tue, 3 Mar 2009 14:25:59 +1100 +Subject: [PATCH 1/2] super0: Do all metadata IO with 4096byte alignment + +.. because some devices (dasd) has 4096 byte sector size. + +As the superblock is 4096 bytes and the bitmap is in a +60K region, this is safe from any possible corruption. + +Signed-off-by: NeilBrown +--- + super0.c | 25 ++++++++++++++----------- + 1 files changed, 14 insertions(+), 11 deletions(-) + +Index: mdadm-3.0-devel2/super0.c +=================================================================== +--- mdadm-3.0-devel2.orig/super0.c ++++ mdadm-3.0-devel2/super0.c +@@ -545,7 +545,8 @@ static int init_super0(struct supertype + mdp_super_t *sb; + int spares; + +- if (posix_memalign((void**)&sb, 512, MD_SB_BYTES + sizeof(bitmap_super_t)) != 0) { ++ if (posix_memalign((void**)&sb, 4096, ++ MD_SB_BYTES + ROUND_UP(sizeof(bitmap_super_t), 4096)) != 0) { + fprintf(stderr, Name ": %s could not allocate superblock\n", __func__); + return 0; + } +@@ -680,8 +681,8 @@ static int store_super0(struct supertype + if (super->state & (1<magic) == BITMAP_MAGIC) +- if (write(fd, bm, ROUND_UP(sizeof(*bm),512)) != +- ROUND_UP(sizeof(*bm),512)) ++ if (write(fd, bm, ROUND_UP(sizeof(*bm),4096)) != ++ ROUND_UP(sizeof(*bm),4096)) + return 5; + } + +@@ -741,8 +742,9 @@ static int compare_super0(struct superty + if (second->md_magic != MD_SB_MAGIC) + return 1; + if (!first) { +- if (posix_memalign((void**)&first, 512, +- MD_SB_BYTES + sizeof(struct bitmap_super_s)) != 0) { ++ if (posix_memalign((void**)&first, 4096, ++ MD_SB_BYTES + ++ ROUND_UP(sizeof(struct bitmap_super_s), 4096)) != 0) { + fprintf(stderr, Name + ": %s could not allocate superblock\n", __func__); + return 1; +@@ -815,8 +817,9 @@ static int load_super0(struct supertype + return 1; + } + +- if (posix_memalign((void**)&super, 512, +- MD_SB_BYTES + sizeof(bitmap_super_t)+512) != 0) { ++ if (posix_memalign((void**)&super, 4096, ++ MD_SB_BYTES + ++ ROUND_UP(sizeof(bitmap_super_t), 4096)) != 0) { + fprintf(stderr, Name + ": %s could not allocate superblock\n", __func__); + return 1; +@@ -864,8 +867,8 @@ static int load_super0(struct supertype + * valid. If it doesn't clear the bit. An --assemble --force + * should get that written out. + */ +- if (read(fd, super+1, ROUND_UP(sizeof(struct bitmap_super_s),512)) +- != ROUND_UP(sizeof(struct bitmap_super_s),512)) ++ if (read(fd, super+1, ROUND_UP(sizeof(struct bitmap_super_s),4096)) ++ != ROUND_UP(sizeof(struct bitmap_super_s),4096)) + goto no_bitmap; + + uuid_from_super0(st, uuid); +@@ -996,8 +999,8 @@ static int write_bitmap0(struct supertyp + int rv = 0; + + int towrite, n; +- char abuf[4096+512]; +- char *buf = (char*)(((long)(abuf+512))&~511UL); ++ char abuf[4096+4096]; ++ char *buf = (char*)(((long)(abuf+4096))&~4095L); + + if (!get_dev_size(fd, NULL, &dsize)) + return 1; diff --git a/super1-do-metadata-IO-in-sector_size-units.patch b/super1-do-metadata-IO-in-sector_size-units.patch new file mode 100644 index 0000000..c7d7163 --- /dev/null +++ b/super1-do-metadata-IO-in-sector_size-units.patch @@ -0,0 +1,137 @@ +From ae8b146d524dd162f159f27938ed14df037e3ff8 Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Tue, 3 Mar 2009 15:44:26 +1100 +Subject: [PATCH 2/2] super1 - do metadata IO in sector_size units. + +If the sector size is > 512, we need to be more careful about +alignment. +The largest known sector size is 4096 and (fortunately) both the +superblock and (in many cases) the bitmap are 4096-byte aligned. +So there should be no data-overlap problems. + +The exception is when the bitmap is squeezed into the 3K after the +superblock. This arrangement cannot currently be supported on +4K sector-size devices. + +Signed-off-by: NeilBrown +--- + super1.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------ + 1 files changed, 64 insertions(+), 7 deletions(-) + +Index: mdadm-3.0-devel2/super1.c +=================================================================== +--- mdadm-3.0-devel2.orig/super1.c ++++ mdadm-3.0-devel2/super1.c +@@ -141,6 +141,64 @@ static unsigned int calc_sb_1_csum(struc + return __cpu_to_le32(csum); + } + ++static char abuf[4096+4096]; ++static int aread(int fd, void *buf, int len) ++{ ++ /* aligned read. ++ * On devices with a 4K sector size, we need to read ++ * the full sector and copy relevant bits into ++ * the buffer ++ */ ++ int bsize; ++ char *b; ++ int n; ++ if (ioctl(fd, BLKSSZGET, &bsize) != 0 || ++ bsize <= len) ++ return read(fd, buf, len); ++ if (bsize > 4096) ++ return -1; ++ b = (char*)(((long)(abuf+4096))&~4095UL); ++ ++ n = read(fd, b, bsize); ++ if (n <= 0) ++ return n; ++ lseek(fd, len - n, 1); ++ if (n > len) ++ n = len; ++ memcpy(buf, b, n); ++ return n; ++} ++ ++static int awrite(int fd, void *buf, int len) ++{ ++ /* aligned write. ++ * On devices with a 4K sector size, we need to write ++ * the full sector. We pre-read if the sector is larger ++ * than the write. ++ * The address must be sector-aligned. ++ */ ++ int bsize; ++ char *b; ++ int n; ++ if (ioctl(fd, BLKSSZGET, &bsize) != 0 || ++ bsize <= len) ++ return write(fd, buf, len); ++ if (bsize > 4096) ++ return -1; ++ b = (char*)(((long)(abuf+4096))&~4095UL); ++ ++ n = read(fd, b, bsize); ++ if (n <= 0) ++ return n; ++ lseek(fd, -n, 1); ++ memcpy(b, buf, len); ++ n = write(fd, b, bsize); ++ if (n <= 0) ++ return n; ++ lseek(fd, len - n, 1); ++ return len; ++} ++ + #ifndef MDASSEMBLE + static void examine_super1(struct supertype *st, char *homehost) + { +@@ -881,7 +939,7 @@ static int store_super1(struct supertype + sbsize = sizeof(*sb) + 2 * __le32_to_cpu(sb->max_dev); + sbsize = (sbsize+511)&(~511UL); + +- if (write(fd, sb, sbsize) != sbsize) ++ if (awrite(fd, sb, sbsize) != sbsize) + return 4; + + if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) { +@@ -889,8 +947,8 @@ static int store_super1(struct supertype + (((char*)sb)+1024); + if (__le32_to_cpu(bm->magic) == BITMAP_MAGIC) { + locate_bitmap1(st, fd); +- if (write(fd, bm, ROUND_UP(sizeof(*bm),512)) != +- ROUND_UP(sizeof(*bm),512)) ++ if (awrite(fd, bm, sizeof(*bm)) != ++ sizeof(*bm)) + return 5; + } + } +@@ -1187,7 +1245,7 @@ static int load_super1(struct supertype + return 1; + } + +- if (read(fd, super, 1024) != 1024) { ++ if (aread(fd, super, 1024) != 1024) { + if (devname) + fprintf(stderr, Name ": Cannot read superblock on %s\n", + devname); +@@ -1232,7 +1290,7 @@ static int load_super1(struct supertype + * should get that written out. + */ + locate_bitmap1(st, fd); +- if (read(fd, ((char*)super)+1024, 512) ++ if (aread(fd, ((char*)super)+1024, 512) + != 512) + goto no_bitmap; + +@@ -1470,8 +1528,7 @@ static int write_bitmap1(struct supertyp + int rv = 0; + + int towrite, n; +- char abuf[4096+512]; +- char *buf = (char*)(((long)(abuf+512))&~511UL); ++ char *buf = (char*)(((long)(abuf+4096))&~4095UL); + + locate_bitmap1(st, fd); +