From 6ef89052d85b8137b8a7100f761d896ae6f61001 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 7 Feb 2012 11:55:18 +1100 Subject: [PATCH] super1: make aread/awrite always use an aligned buffer. A recently change to write_bitmap1 meant awrite would sometimes write from a non-aligned buffer which of course break. So change awrite (and aread) to always use their own aligned buffer to ensure safety. Reported-by: Alexander Lyakas Signed-off-by: NeilBrown --- super1.c | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) --- mdadm-3.2.2.orig/super1.c +++ mdadm-3.2.2/super1.c @@ -144,17 +144,19 @@ static int aread(int fd, void *buf, int * the full sector and copy relevant bits into * the buffer */ - int bsize; + int bsize, iosize; char *b; int n; - if (ioctl(fd, BLKSSZGET, &bsize) != 0 || - bsize <= len) - return read(fd, buf, len); - if (bsize > 4096) + if (ioctl(fd, BLKSSZGET, &bsize) != 0) + bsize = 512; + + if (bsize > 4096 || len > 4096) return -1; b = (char*)(((long)(abuf+4096))&~4095UL); - n = read(fd, b, bsize); + for (iosize = 0; iosize < len; iosize += bsize) + ; + n = read(fd, b, iosize); if (n <= 0) return n; lseek(fd, len - n, 1); @@ -172,22 +174,27 @@ static int awrite(int fd, void *buf, int * than the write. * The address must be sector-aligned. */ - int bsize; + int bsize, iosize; char *b; int n; - if (ioctl(fd, BLKSSZGET, &bsize) != 0 || - bsize <= len) - return write(fd, buf, len); - if (bsize > 4096) + if (ioctl(fd, BLKSSZGET, &bsize) != 0) + bsize = 512; + if (bsize > 4096 || len > 4096) return -1; b = (char*)(((long)(abuf+4096))&~4095UL); - n = read(fd, b, bsize); - if (n <= 0) - return n; - lseek(fd, -n, 1); + for (iosize = 0; iosize < len ; iosize += bsize) + ; + + if (len != iosize) { + n = read(fd, b, iosize); + if (n <= 0) + return n; + lseek(fd, -n, 1); + } + memcpy(b, buf, len); - n = write(fd, b, bsize); + n = write(fd, b, iosize); if (n <= 0) return n; lseek(fd, len - n, 1);