diff -urN p4/freebsd/src/sbin/mdconfig/mdconfig.8 p4/growfs/sbin/mdconfig/mdconfig.8 --- p4/freebsd/src/sbin/mdconfig/mdconfig.8 2012-03-07 03:22:07.000000000 +0100 +++ p4/growfs/sbin/mdconfig/mdconfig.8 2012-03-07 02:00:47.000000000 +0100 @@ -39,7 +39,7 @@ .\" @(#)vnconfig.8 8.1 (Berkeley) 6/5/93 .\" from: src/usr.sbin/vnconfig/vnconfig.8,v 1.19 2000/12/27 15:30:29 .\" -.\" $FreeBSD: src/sbin/mdconfig/mdconfig.8,v 1.46 2011/04/29 22:40:11 des Exp $ +.\" $FreeBSD: head/sbin/mdconfig/mdconfig.8 221232 2011-04-29 22:40:11Z des $ .\" .Dd June 21, 2008 .Dt MDCONFIG 8 @@ -64,6 +64,11 @@ .Fl u Ar unit .Op Fl o Oo Cm no Oc Ns Ar force .Nm +.Fl r +.Fl u Ar unit +.Fl s Ar size +.Op Fl o Oo Cm no Oc Ns Ar force +.Nm .Fl l .Op Fl n .Op Fl v @@ -85,6 +90,8 @@ parameters specified and attach it to the system. .It Fl d Detach a memory disk from the system and release all resources. +.It Fl r +Resize a memory disk. .It Fl t Ar type Select the type of the memory disk. .Bl -tag -width "preload" diff -urN p4/freebsd/src/sbin/mdconfig/mdconfig.c p4/growfs/sbin/mdconfig/mdconfig.c --- p4/freebsd/src/sbin/mdconfig/mdconfig.c 2012-03-07 03:22:08.000000000 +0100 +++ p4/growfs/sbin/mdconfig/mdconfig.c 2012-03-07 02:00:47.000000000 +0100 @@ -27,7 +27,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/sbin/mdconfig/mdconfig.c,v 1.67 2012/01/27 11:48:44 trasz Exp $ + * $FreeBSD: head/sbin/mdconfig/mdconfig.c 230612 2012-01-27 11:48:44Z trasz $ */ #include @@ -54,7 +54,7 @@ #include static struct md_ioctl mdio; -static enum {UNSET, ATTACH, DETACH, LIST} action = UNSET; +static enum {UNSET, ATTACH, DETACH, RESIZE, LIST} action = UNSET; static int nflag; static void usage(void); @@ -81,6 +81,7 @@ " [-s size] [-S sectorsize] [-u unit]\n" " [-x sectors/track] [-y heads/cylinder]\n" " mdconfig -d -u unit [-o [no]force]\n" +" mdconfig -r -u unit -s size [-o [no]force]\n" " mdconfig -l [-v] [-n] [-u unit]\n" " mdconfig file\n"); fprintf(stderr, "\t\ttype = {malloc, preload, vnode, swap}\n"); @@ -108,25 +109,32 @@ if (argc == 1) usage(); - while ((ch = getopt(argc, argv, "ab:df:lno:s:S:t:u:vx:y:")) != -1) { + while ((ch = getopt(argc, argv, "ab:df:lno:rs:S:t:u:vx:y:")) != -1) { switch (ch) { case 'a': if (action != UNSET && action != ATTACH) - errx(1, - "-a is mutually exclusive with -d and -l"); + errx(1, "-a is mutually exclusive " + "with -d, -r, and -l"); action = ATTACH; break; case 'd': if (action != UNSET && action != DETACH) - errx(1, - "-d is mutually exclusive with -a and -l"); + errx(1, "-d is mutually exclusive " + "with -a, -r, and -l"); action = DETACH; mdio.md_options |= MD_AUTOUNIT; break; + case 'r': + if (action != UNSET && action != RESIZE) + errx(1, "-r is mutually exclusive " + "with -a, -d, and -l"); + action = RESIZE; + mdio.md_options |= MD_AUTOUNIT; + break; case 'l': if (action != UNSET && action != LIST) - errx(1, - "-l is mutually exclusive with -a and -d"); + errx(1, "-l is mutually exclusive " + "with -a, -r, and -d"); action = LIST; mdio.md_options |= MD_AUTOUNIT; break; @@ -283,8 +291,8 @@ } else { if (mdio.md_sectorsize != 0) errx(1, "-S can only be used with -a"); - if (mdio.md_mediasize != 0) - errx(1, "-s can only be used with -a"); + if (action != RESIZE && mdio.md_mediasize != 0) + errx(1, "-s can only be used with -a and -r"); if (mdio.md_fwsectors != 0) errx(1, "-x can only be used with -a"); if (mdio.md_fwheads != 0) @@ -295,13 +303,20 @@ errx(1, "-t can only be used with -a"); if (argc > 0) errx(1, "file can only be used with -a"); - if (action != DETACH && (mdio.md_options & ~MD_AUTOUNIT) != 0) - errx(1, "-o can only be used with -a and -d"); + if ((action != DETACH && action != RESIZE) && + (mdio.md_options & ~MD_AUTOUNIT) != 0) + errx(1, "-o can only be used with -a, -d, and -r"); if (action == DETACH && (mdio.md_options & ~(MD_FORCE | MD_AUTOUNIT)) != 0) errx(1, "only -o [no]force can be used with -d"); + if (action == RESIZE && + (mdio.md_options & ~(MD_FORCE | MD_RESERVE | MD_AUTOUNIT)) != 0) + errx(1, "only -o [no]force and -o [no]reserve can be used with -r"); } + if (action == RESIZE && mdio.md_mediasize == 0) + errx(1, "must specify -s for -r"); + if (action != LIST && vflag == OPT_VERBOSE) errx(1, "-v can only be used with -l"); @@ -333,6 +348,12 @@ i = ioctl(fd, MDIOCDETACH, &mdio); if (i < 0) err(1, "ioctl(/dev/%s)", MDCTL_NAME); + } else if (action == RESIZE) { + if (mdio.md_options & MD_AUTOUNIT) + errx(1, "-r requires -u"); + i = ioctl(fd, MDIOCRESIZE, &mdio); + if (i < 0) + err(1, "ioctl(/dev/%s)", MDCTL_NAME); } else if (action == LIST) { if (mdio.md_options & MD_AUTOUNIT) { /* @@ -342,7 +363,6 @@ md_list(NULL, OPT_LIST | vflag); } else return (md_query(uflag)); - } else usage(); close(fd); diff -urN p4/freebsd/src/sys/dev/md/md.c p4/growfs/sys/dev/md/md.c --- p4/freebsd/src/sys/dev/md/md.c 2012-03-07 03:43:49.000000000 +0100 +++ p4/growfs/sys/dev/md/md.c 2012-03-07 02:09:45.000000000 +0100 @@ -6,7 +6,7 @@ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- * - * $FreeBSD: src/sys/dev/md/md.c,v 1.203 2011/12/13 00:38:50 eadler Exp $ + * $FreeBSD: head/sys/dev/md/md.c 228449 2011-12-13 00:38:50Z eadler $ * */ @@ -1081,6 +1081,61 @@ } static int +mdresize(struct md_s *sc, struct md_ioctl *mdio) +{ + int error, res; + vm_pindex_t oldpages, newpages; + + switch (sc->type) { + case MD_VNODE: + break; + case MD_SWAP: + oldpages = OFF_TO_IDX(sc->mediasize + PAGE_MASK); + newpages = OFF_TO_IDX(mdio->md_mediasize + PAGE_MASK); + + if (newpages < oldpages) { + VM_OBJECT_LOCK(sc->object); + swap_pager_freespace(sc->object, newpages, + oldpages - newpages); + swap_release_by_cred(PAGE_SIZE * + (oldpages - newpages), sc->cred); + vm_object_page_remove(sc->object, newpages, 0, 0); + sc->object->charge = PAGE_SIZE * newpages; + sc->object->size = newpages; + VM_OBJECT_UNLOCK(sc->object); + } else if (newpages > oldpages) { + res = swap_reserve_by_cred(PAGE_SIZE * + (newpages - oldpages), sc->cred); + if (!res) + return (ENOMEM); + if ((mdio->md_options & MD_RESERVE) || + (sc->flags & MD_RESERVE)) { + error = swap_pager_reserve(sc->object, + oldpages, newpages - oldpages); + if (error < 0) { + swap_release_by_cred(PAGE_SIZE * + (newpages - oldpages), sc->cred); + return (EDOM); + } + } + VM_OBJECT_LOCK(sc->object); + sc->object->charge = PAGE_SIZE * newpages; + sc->object->size = newpages; + VM_OBJECT_UNLOCK(sc->object); + } + break; + default: + return (EOPNOTSUPP); + } + + sc->mediasize = mdio->md_mediasize; + g_topology_lock(); + g_resize_provider(sc->pp, sc->mediasize); + g_topology_unlock(); + return (0); +} + +static int mdcreate_swap(struct md_s *sc, struct md_ioctl *mdio, struct thread *td) { vm_ooffset_t npage; @@ -1108,7 +1163,7 @@ VM_PROT_DEFAULT, 0, td->td_ucred); if (sc->object == NULL) return (ENOMEM); - sc->flags = mdio->md_options & MD_FORCE; + sc->flags = mdio->md_options & (MD_FORCE | MD_RESERVE); if (mdio->md_options & MD_RESERVE) { if (swap_pager_reserve(sc->object, 0, npage) < 0) { error = EDOM; @@ -1217,6 +1272,19 @@ !(mdio->md_options & MD_FORCE)) return (EBUSY); return (mddestroy(sc, td)); + case MDIOCRESIZE: + if (mdio->md_mediasize == 0 || + (mdio->md_options & ~(MD_FORCE | MD_RESERVE)) != 0) + return (EINVAL); + + sc = mdfind(mdio->md_unit); + if (sc == NULL) + return (ENOENT); + if (mdio->md_mediasize < sc->mediasize && + !(sc->flags & MD_FORCE) && + !(mdio->md_options & MD_FORCE)) + return (EBUSY); + return (mdresize(sc, mdio)); case MDIOCQUERY: sc = mdfind(mdio->md_unit); if (sc == NULL) diff -urN p4/freebsd/src/sys/sys/mdioctl.h p4/growfs/sys/sys/mdioctl.h --- p4/freebsd/src/sys/sys/mdioctl.h 2012-03-07 03:57:20.000000000 +0100 +++ p4/growfs/sys/sys/mdioctl.h 2012-03-07 02:14:22.000000000 +0100 @@ -37,7 +37,7 @@ * * From: src/sys/sys/vnioctl.h,v 1.4 * - * $FreeBSD: src/sys/sys/mdioctl.h,v 1.22 2012/01/25 11:28:18 trasz Exp $ + * $FreeBSD: head/sys/sys/mdioctl.h 230536 2012-01-25 11:28:18Z trasz $ */ #ifndef _SYS_MDIOCTL_H_ @@ -79,6 +79,7 @@ #define MDIOCDETACH _IOWR('m', 1, struct md_ioctl) /* detach disk */ #define MDIOCQUERY _IOWR('m', 2, struct md_ioctl) /* query status */ #define MDIOCLIST _IOWR('m', 3, struct md_ioctl) /* query status */ +#define MDIOCRESIZE _IOWR('m', 4, struct md_ioctl) /* resize disk */ #define MD_CLUSTER 0x01 /* Don't cluster */ #define MD_RESERVE 0x02 /* Pre-reserve swap */