Index: head/lib/libstand/stand.h =================================================================== --- head/lib/libstand/stand.h +++ head/lib/libstand/stand.h @@ -194,6 +194,9 @@ #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) Index: head/sys/boot/common/bcache.c =================================================================== --- head/sys/boot/common/bcache.c +++ head/sys/boot/common/bcache.c @@ -295,7 +295,11 @@ * 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 @@ * 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 @@ ((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 @@ 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; } Index: head/sys/boot/common/disk.c =================================================================== --- head/sys/boot/common/disk.c +++ head/sys/boot/common/disk.c @@ -87,7 +87,12 @@ 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)); }