From 504f5e294e173f06aeb0ccd873d73df115542cc9 Mon Sep 17 00:00:00 2001 From: Doug Moore Date: Thu, 15 Aug 2019 02:30:44 +0000 Subject: [PATCH] swap_pager.c reserves 2 blocks for a bsd label. Change that 2 to the expression howmany(BBSIZE, PAGE_SIZE), where BBSIZE is the size of the boot block area. That can be less than 2 if PAGE_SIZE is big. swapon(8) has an option to trim (delete) all the blocks of a device at startup. However, if the first of those blocks is a bsd label, then trimming those blocks is destructive. Change swapon to leave the first BBSIZE bytes untrimmed. Update manual pages to reflect changes in how swapon and how it may be used, espeically in association with savecore. Reviewed by: alc Approved by: markj (mentor) MFC after: 3 days Differential Revision: https://reviews.freebsd.org/D21191 --- sbin/swapon/swapon.8 | 12 +++++++++++- sbin/swapon/swapon.c | 5 +++-- share/man/man5/fstab.5 | 13 +++++++++++-- sys/vm/swap_pager.c | 8 +++++--- 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/sbin/swapon/swapon.8 b/sbin/swapon/swapon.8 index f69dd484a93b..9f4e14852b17 100644 --- a/sbin/swapon/swapon.8 +++ b/sbin/swapon/swapon.8 @@ -90,7 +90,17 @@ The .Fl E option causes each of following devices to receive a .Dv BIO_DELETE -command to mark all blocks as unused. +command. +This command marks the device's blocks as unused, except those that +might store a disk label. +This marking can erase a crash dump. +To delay +.Nm swapon +for a device until after +.Nm savecore +has copied the crash dump to another location, use the +.Dq late +option. .Pp The .Nm swapoff diff --git a/sbin/swapon/swapon.c b/sbin/swapon/swapon.c index 67f330733cb0..7eaa642ffb3c 100644 --- a/sbin/swapon/swapon.c +++ b/sbin/swapon/swapon.c @@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -761,8 +762,8 @@ swapon_trim(const char *name) } else errx(1, "%s has an invalid file type", name); /* Trim the device. */ - ioarg[0] = 0; - ioarg[1] = sz; + ioarg[0] = BBSIZE; + ioarg[1] = sz - BBSIZE; if (ioctl(fd, DIOCGDELETE, ioarg) != 0) warn("ioctl(DIOCGDELETE)"); diff --git a/share/man/man5/fstab.5 b/share/man/man5/fstab.5 index 1b2d99daa25e..934d1ecf7194 100644 --- a/share/man/man5/fstab.5 +++ b/share/man/man5/fstab.5 @@ -246,8 +246,17 @@ For swap devices, the keyword .Dq trimonce triggers the delivery of a .Dv BIO_DELETE -command to the device to mark -all blocks as unused. +command to the device. +This command marks the device's blocks as unused, except those that +might store a disk label. +This marking can erase a crash dump. +To delay +.Nm swapon +for a device until after +.Nm savecore +has copied the crash dump to another location, use the +.Dq late +option. For vnode-backed swap spaces, .Dq file is supported in the diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c index ab5f716ac14e..5bdedd8ea147 100644 --- a/sys/vm/swap_pager.c +++ b/sys/vm/swap_pager.c @@ -79,6 +79,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -2298,10 +2299,11 @@ swaponsomething(struct vnode *vp, void *id, u_long nblks, sp->sw_blist = blist_create(nblks, M_WAITOK); /* - * Do not free the first two block in order to avoid overwriting + * Do not free the first blocks in order to avoid overwriting * any bsd label at the front of the partition */ - blist_free(sp->sw_blist, 2, nblks - 2); + blist_free(sp->sw_blist, howmany(BBSIZE, PAGE_SIZE), + nblks - howmany(BBSIZE, PAGE_SIZE)); dvbase = 0; mtx_lock(&sw_dev_mtx); @@ -2319,7 +2321,7 @@ swaponsomething(struct vnode *vp, void *id, u_long nblks, sp->sw_end = dvbase + nblks; TAILQ_INSERT_TAIL(&swtailq, sp, sw_list); nswapdev++; - swap_pager_avail += nblks - 2; + swap_pager_avail += nblks - howmany(BBSIZE, PAGE_SIZE); swap_total += nblks; swapon_check_swzone(); swp_sizecheck();