Author: dougm
Date: Thu Jul 11 20:52:39 2019
New Revision: 349923
URL: https://svnweb.freebsd.org/changeset/base/349923

Log:
  Address problems in blist_alloc introduced in r349777.  The swap block 
allocator could become corrupted
  if a retry to allocate swap space, after a larger allocation attempt failed, 
allocated a smaller set of free blocks
  that ended on a 32- or 64-block boundary.
  
  Add tests to detect this kind of failure-to-extend-at-boundary and prevent 
the associated accounting screwup.
  
  Reported by: pho
  Tested by: pho
  Reviewed by: alc
  Approved by: markj (mentor)
  Discussed with: kib
  Differential Revision: https://reviews.freebsd.org/D20893

Modified:
  head/sys/kern/subr_blist.c

Modified: head/sys/kern/subr_blist.c
==============================================================================
--- head/sys/kern/subr_blist.c  Thu Jul 11 20:29:50 2019        (r349922)
+++ head/sys/kern/subr_blist.c  Thu Jul 11 20:52:39 2019        (r349923)
@@ -639,15 +639,27 @@ blst_next_leaf_alloc(blmeta_t *scan, daddr_t start, in
                         * bitpos() returns zero here.
                         */
                        avail = blk - start + bitpos(~scan->bm_bitmap);
-                       if (avail < count) {
+                       if (avail < count || avail == 0) {
                                /*
                                 * There isn't a next leaf with enough free
-                                * blocks at its beginning to complete the
-                                * spanning allocation.
+                                * blocks at its beginning to bother
+                                * allocating.
                                 */
                                return (avail);
                        }
                        maxcount = imin(avail, maxcount);
+                       if (maxcount % BLIST_BMAP_RADIX == 0) {
+                               /*
+                                * There was no next leaf.  Back scan up to
+                                * last leaf.
+                                */
+                               --scan;
+                               while (radix != BLIST_BMAP_RADIX) {
+                                       radix /= BLIST_META_RADIX;
+                                       --scan;
+                               }
+                               blk -= BLIST_BMAP_RADIX;
+                       }
                }
        }
        
_______________________________________________
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