From owner-svn-src-head@freebsd.org Thu Apr 6 15:57:54 2017 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id CAAA7D32B00; Thu, 6 Apr 2017 15:57:54 +0000 (UTC) (envelope-from tsoome@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id A5ECDEEA; Thu, 6 Apr 2017 15:57:54 +0000 (UTC) (envelope-from tsoome@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v36FvrbV032160; Thu, 6 Apr 2017 15:57:53 GMT (envelope-from tsoome@FreeBSD.org) Received: (from tsoome@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v36FvrKo032157; Thu, 6 Apr 2017 15:57:53 GMT (envelope-from tsoome@FreeBSD.org) Message-Id: <201704061557.v36FvrKo032157@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: tsoome set sender to tsoome@FreeBSD.org using -f From: Toomas Soome Date: Thu, 6 Apr 2017 15:57:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r316578 - in head: lib/libstand sys/boot/common X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 06 Apr 2017 15:57:54 -0000 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)); }