svn commit: r316578 - in head: lib/libstand sys/boot/common
Toomas Soome
tsoome at FreeBSD.org
Thu Apr 6 15:57:54 UTC 2017
Author: tsoome
Date: Thu Apr 6 15:57:53 2017
New Revision: 316578
URL: https://svnweb.freebsd.org/changeset/base/316578
Log:
loader: want mechanism to avoid RA with bcache
While we have mechanisms in place to protect ourselves against the read
behind the disk end, there is still one corner case. As the GPT
partition table has backup table at the end of the disk, and we yet
do not know the size of the disk (if the wrong size is provided by the
firmware/bios), we need to limit the reads to avoid read ahead in such case.
Note: this update does add constant into stand.h, so the incremental build
will need to get local stand.h updated first.
Reviewed by: allanjude
Differential Revision: https://reviews.freebsd.org/D10187
Modified:
head/lib/libstand/stand.h
head/sys/boot/common/bcache.c
head/sys/boot/common/disk.c
Modified: head/lib/libstand/stand.h
==============================================================================
--- head/lib/libstand/stand.h Thu Apr 6 15:42:12 2017 (r316577)
+++ head/lib/libstand/stand.h Thu Apr 6 15:57:53 2017 (r316578)
@@ -194,6 +194,9 @@ extern struct open_file files[];
#define F_WRITE 0x0002 /* file opened for writing */
#define F_RAW 0x0004 /* raw device open - no file system */
#define F_NODEV 0x0008 /* network open - no device */
+#define F_MASK 0xFFFF
+/* Mode modifier for strategy() */
+#define F_NORA (0x01 << 16) /* Disable Read-Ahead */
#define isascii(c) (((c) & ~0x7F) == 0)
Modified: head/sys/boot/common/bcache.c
==============================================================================
--- head/sys/boot/common/bcache.c Thu Apr 6 15:42:12 2017 (r316577)
+++ head/sys/boot/common/bcache.c Thu Apr 6 15:57:53 2017 (r316578)
@@ -295,7 +295,11 @@ read_strategy(void *devdata, int rw, dad
* Our choice of 16 read ahead blocks will always fit inside the bcache.
*/
- ra = bc->bcache_nblks - BHASH(bc, p_blk + p_size);
+ if ((rw & F_NORA) == F_NORA)
+ ra = 0;
+ else
+ ra = bc->bcache_nblks - BHASH(bc, p_blk + p_size);
+
if (ra != 0 && ra != bc->bcache_nblks) { /* do we have RA space? */
ra = MIN(bc->ra, ra - 1);
ra = rounddown(ra, 16); /* multiple of 16 blocks */
@@ -316,6 +320,7 @@ read_strategy(void *devdata, int rw, dad
* in either case we should return the data in bcache and only
* return error if there is no data.
*/
+ rw &= F_MASK;
result = dd->dv_strategy(dd->dv_devdata, rw, p_blk,
p_size * bcache_blksize, p_buf, &r_size);
@@ -381,10 +386,11 @@ bcache_strategy(void *devdata, int rw, d
((size * 2 / bcache_blksize) > bcache_nblks)) {
DEBUG("bypass %zu from %qu", size / bcache_blksize, blk);
bcache_bypasses++;
+ rw &= F_MASK;
return (dd->dv_strategy(dd->dv_devdata, rw, blk, size, buf, rsize));
}
- switch (rw) {
+ switch (rw & F_MASK) {
case F_READ:
nblk = size / bcache_blksize;
if (size != 0 && nblk == 0)
@@ -423,7 +429,7 @@ bcache_strategy(void *devdata, int rw, d
return (ret);
case F_WRITE:
- return write_strategy(devdata, rw, blk, size, buf, rsize);
+ return write_strategy(devdata, F_WRITE, blk, size, buf, rsize);
}
return -1;
}
Modified: head/sys/boot/common/disk.c
==============================================================================
--- head/sys/boot/common/disk.c Thu Apr 6 15:42:12 2017 (r316577)
+++ head/sys/boot/common/disk.c Thu Apr 6 15:57:53 2017 (r316578)
@@ -87,7 +87,12 @@ ptblread(void *d, void *buf, size_t bloc
dev = (struct disk_devdesc *)d;
od = (struct open_disk *)dev->d_opendata;
- return (dev->d_dev->dv_strategy(dev, F_READ, offset,
+
+ /*
+ * As the GPT backup partition is located at the end of the disk,
+ * to avoid reading past disk end, flag bcache not to use RA.
+ */
+ return (dev->d_dev->dv_strategy(dev, F_READ | F_NORA, offset,
blocks * od->sectorsize, (char *)buf, NULL));
}
More information about the svn-src-head
mailing list