diff options
author | Toomas Soome <tsoome@FreeBSD.org> | 2017-04-06 15:57:53 +0000 |
---|---|---|
committer | Toomas Soome <tsoome@FreeBSD.org> | 2017-04-06 15:57:53 +0000 |
commit | ffd08eb06464513152db6cac7310438aed1f4499 (patch) | |
tree | 0d9da997ca60d67f240b306f64115d7f7b81aebd | |
parent | 6ee43aee80f5b8c322973dc2b251d05be4a6321a (diff) |
Notes
-rw-r--r-- | lib/libstand/stand.h | 3 | ||||
-rw-r--r-- | sys/boot/common/bcache.c | 12 | ||||
-rw-r--r-- | sys/boot/common/disk.c | 7 |
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)); } |