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 <do...@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;
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to