svn commit: r338472 - head/sys/kern

Mark Johnston markj at FreeBSD.org
Wed Sep 5 19:05:31 UTC 2018


Author: markj
Date: Wed Sep  5 19:05:30 2018
New Revision: 338472
URL: https://svnweb.freebsd.org/changeset/base/338472

Log:
  Correct the condition under which we allocate a terminator node.
  
  We will have last_block < blocks if the block count is divisible
  by BLIST_BMAP_RADIX, but a terminator node is still needed if the
  tree isn't balanced.  In this case we were overruning the blist
  array by 16 bytes during initialization.
  
  While here, add a check for the invalid blocks == 0 case.
  
  PR:		231116
  Reviewed by:	alc, kib (previous version), Doug Moore <dougm at rice.edu>
  Approved by:	re (gjb)
  MFC after:	1 week
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D17020

Modified:
  head/sys/kern/subr_blist.c

Modified: head/sys/kern/subr_blist.c
==============================================================================
--- head/sys/kern/subr_blist.c	Wed Sep  5 15:25:23 2018	(r338471)
+++ head/sys/kern/subr_blist.c	Wed Sep  5 19:05:30 2018	(r338472)
@@ -224,17 +224,19 @@ blist_create(daddr_t blocks, int flags)
 	u_daddr_t nodes, radix, skip;
 	int digit;
 
+	if (blocks == 0)
+		panic("invalid block count");
+
 	/*
-	 * Calculate the radix and node count used for scanning.  Find the last
-	 * block that is followed by a terminator.
+	 * Calculate the radix and node count used for scanning.
 	 */
 	last_block = blocks - 1;
 	radix = BLIST_BMAP_RADIX;
 	while (radix < blocks) {
 		if (((last_block / radix + 1) & BLIST_META_MASK) != 0)
 			/*
-			 * A terminator will be added.  Update last_block to the
-			 * position just before that terminator.
+			 * We must widen the blist to avoid partially
+			 * filled nodes.
 			 */
 			last_block |= radix - 1;
 		radix *= BLIST_META_RADIX;
@@ -244,7 +246,9 @@ blist_create(daddr_t blocks, int flags)
 	 * Count the meta-nodes in the expanded tree, including the final
 	 * terminator, from the bottom level up to the root.
 	 */
-	nodes = (last_block >= blocks) ? 2 : 1;
+	nodes = 1;
+	if (radix - blocks >= BLIST_BMAP_RADIX)
+		nodes++;
 	last_block /= BLIST_BMAP_RADIX;
 	while (last_block > 0) {
 		nodes += last_block + 1;


More information about the svn-src-head mailing list