diff options
author | dillon <dillon@FreeBSD.org> | 2000-10-13 16:44:34 +0000 |
---|---|---|
committer | dillon <dillon@FreeBSD.org> | 2000-10-13 16:44:34 +0000 |
commit | b9b696f1abc7fcd1f327c7a003e2f19073711203 (patch) | |
tree | 1e09d9935e87e4fc9f96b2883b562a9a132bbdc1 /sys/vm/vm_swap.c | |
parent | 4c9cb1a066173e802e2de5bccdff3c594437e042 (diff) | |
download | FreeBSD-src-b9b696f1abc7fcd1f327c7a003e2f19073711203.zip FreeBSD-src-b9b696f1abc7fcd1f327c7a003e2f19073711203.tar.gz |
The swap bitmap allocator was not calculating the bitmap size properly
in the face of non-stripe-aligned swap areas. The bug could cause a
panic during boot.
Refuse to configure a swap area that is too large (67 GB or so)
Properly document the power-of-2 requirement for SWB_NPAGES.
The patch is slightly different then the one Tor enclosed in the P.R.,
but accomplishes the same thing.
PR: kern/20273
Submitted by: Tor.Egge@fast.no
Diffstat (limited to 'sys/vm/vm_swap.c')
-rw-r--r-- | sys/vm/vm_swap.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/sys/vm/vm_swap.c b/sys/vm/vm_swap.c index cf5cf4b..8691c22 100644 --- a/sys/vm/vm_swap.c +++ b/sys/vm/vm_swap.c @@ -237,6 +237,7 @@ swaponvp(p, vp, dev, nblks) register long blk; swblk_t dvbase; int error; + u_long aligned_nblks; if (!swapdev_vp) { error = getnewvnode(VT_NON, NULL, swapdev_vnodeop_p, @@ -271,6 +272,17 @@ swaponvp(p, vp, dev, nblks) (void) VOP_CLOSE(vp, FREAD | FWRITE, p->p_ucred, p); return (ENXIO); } + + /* + * If we go beyond this, we get overflows in the radix + * tree bitmap code. + */ + if (nblks > 0x40000000 / BLIST_META_RADIX / nswdev) { + printf("exceeded maximum of %d blocks per swap unit\n", + 0x40000000 / BLIST_META_RADIX / nswdev); + (void) VOP_CLOSE(vp, FREAD | FWRITE, p->p_ucred, p); + return (ENXIO); + } /* * nblks is in DEV_BSIZE'd chunks, convert to PAGE_SIZE'd chunks. * First chop nblks off to page-align it, then convert. @@ -288,11 +300,13 @@ swaponvp(p, vp, dev, nblks) /* * nblks, nswap, and dmmax are PAGE_SIZE'd parameters now, not - * DEV_BSIZE'd. + * DEV_BSIZE'd. aligned_nblks is used to calculate the + * size of the swap bitmap, taking into account the stripe size. */ + aligned_nblks = (nblks + (dmmax - 1)) & ~(u_long)(dmmax - 1); - if (nblks * nswdev > nswap) - nswap = (nblks+1) * nswdev; + if (aligned_nblks * nswdev > nswap) + nswap = aligned_nblks * nswdev; if (swapblist == NULL) swapblist = blist_create(nswap); |