From: NeilBrown Date: Tue, 7 Feb 2012 00:55:18 +0000 (+1100) Subject: super1: make aread/awrite always use an aligned buffer. X-Git-Tag: mdadm-3.2.4~93 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6ef89052d85b8137b8a7100f761d896ae6f61001;p=thirdparty%2Fmdadm.git 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 --- diff --git a/super1.c b/super1.c index d23d6e8e..cfa237a0 100644 --- a/super1.c +++ b/super1.c @@ -143,17 +143,19 @@ static int aread(int fd, void *buf, int len) * 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); @@ -171,22 +173,27 @@ static int awrite(int fd, void *buf, int len) * 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);