Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 6 Apr 2017 15:57:53 +0000 (UTC)
From:      Toomas Soome <tsoome@FreeBSD.org>
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
Message-ID:  <201704061557.v36FvrKo032157@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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));
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201704061557.v36FvrKo032157>