summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_swap.c
diff options
context:
space:
mode:
authordillon <dillon@FreeBSD.org>2000-10-13 16:44:34 +0000
committerdillon <dillon@FreeBSD.org>2000-10-13 16:44:34 +0000
commitb9b696f1abc7fcd1f327c7a003e2f19073711203 (patch)
tree1e09d9935e87e4fc9f96b2883b562a9a132bbdc1 /sys/vm/vm_swap.c
parent4c9cb1a066173e802e2de5bccdff3c594437e042 (diff)
downloadFreeBSD-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.c20
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);
OpenPOWER on IntegriCloud