summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToomas Soome <tsoome@FreeBSD.org>2017-04-06 15:57:53 +0000
committerToomas Soome <tsoome@FreeBSD.org>2017-04-06 15:57:53 +0000
commitffd08eb06464513152db6cac7310438aed1f4499 (patch)
tree0d9da997ca60d67f240b306f64115d7f7b81aebd
parent6ee43aee80f5b8c322973dc2b251d05be4a6321a (diff)
Notes
-rw-r--r--lib/libstand/stand.h3
-rw-r--r--sys/boot/common/bcache.c12
-rw-r--r--sys/boot/common/disk.c7
3 files changed, 18 insertions, 4 deletions
diff --git a/lib/libstand/stand.h b/lib/libstand/stand.h
index bedb286657bc..8973a32d0bc9 100644
--- a/lib/libstand/stand.h
+++ b/lib/libstand/stand.h
@@ -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)
diff --git a/sys/boot/common/bcache.c b/sys/boot/common/bcache.c
index 3c1ee64792ad..198dd5f3b7ae 100644
--- a/sys/boot/common/bcache.c
+++ b/sys/boot/common/bcache.c
@@ -295,7 +295,11 @@ read_strategy(void *devdata, int rw, daddr_t blk, size_t size,
* 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, daddr_t blk, size_t size,
* 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, daddr_t blk, size_t size,
((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, daddr_t blk, size_t size,
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;
}
diff --git a/sys/boot/common/disk.c b/sys/boot/common/disk.c
index e441df16a6be..e9496b2b9c0d 100644
--- a/sys/boot/common/disk.c
+++ b/sys/boot/common/disk.c
@@ -87,7 +87,12 @@ ptblread(void *d, void *buf, size_t blocks, uint64_t offset)
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));
}