diff options
author | peter <peter@FreeBSD.org> | 2016-05-03 00:09:13 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2016-05-03 00:09:13 +0000 |
commit | adddf34a2a65bdd52810c5399e91f734f6b646af (patch) | |
tree | 06ecdd5acadf94c9c51ac9848008f9044c9d4552 | |
parent | c5258d5ab1b549018646815d7c88a07eaf08adc2 (diff) | |
download | FreeBSD-src-adddf34a2a65bdd52810c5399e91f734f6b646af.zip FreeBSD-src-adddf34a2a65bdd52810c5399e91f734f6b646af.tar.gz |
Change a rounding operation that had missing braces into a roundup2()
macro. Adjust the buffer clipping code to work as expected.
This prevented a number of machines in the FreeBSD.org cluster from
booting due to "ZFS: i/o error - all block copies unavailable"
after an unclean shutdown.
-rw-r--r-- | sys/boot/i386/zfsboot/zfsboot.c | 11 |
1 files changed, 4 insertions, 7 deletions
diff --git a/sys/boot/i386/zfsboot/zfsboot.c b/sys/boot/i386/zfsboot/zfsboot.c index 928e41a..2562aab 100644 --- a/sys/boot/i386/zfsboot/zfsboot.c +++ b/sys/boot/i386/zfsboot/zfsboot.c @@ -224,21 +224,18 @@ vdev_read(vdev_t *vdev, void *priv, off_t off, void *buf, size_t bytes) while (bytes > 0) { nb = bytes / DEV_BSIZE; - if (nb > READ_BUF_SIZE / DEV_BSIZE) - nb = READ_BUF_SIZE / DEV_BSIZE; /* * Ensure that the read size plus the leading offset does not * exceed the size of the read buffer. */ - if (nb * DEV_BSIZE + diff > READ_BUF_SIZE) - nb -= diff / DEV_BSIZE; + if (nb > (READ_BUF_SIZE - diff) / DEV_BSIZE) + nb = (READ_BUF_SIZE - diff) / DEV_BSIZE; /* * Round the number of blocks to read up to the nearest multiple * of DEV_GELIBOOT_BSIZE. */ - alignnb = nb + (diff / DEV_BSIZE) + - (DEV_GELIBOOT_BSIZE / DEV_BSIZE - 1) & ~ - (unsigned int)(DEV_GELIBOOT_BSIZE / DEV_BSIZE - 1); + alignnb = roundup2(nb * DEV_BSIZE + diff, DEV_GELIBOOT_BSIZE) + / DEV_BSIZE; if (drvread(dsk, dmadat->rdbuf, alignlba, alignnb)) return -1; |