Date: Sat, 7 Jul 2012 20:32:21 +0000 (UTC) From: Edward Tomasz Napierala <trasz@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r238215 - in head: sbin/mdconfig sys/dev/md sys/sys Message-ID: <201207072032.q67KWLt8084775@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: trasz Date: Sat Jul 7 20:32:21 2012 New Revision: 238215 URL: http://svn.freebsd.org/changeset/base/238215 Log: Make it possible to resize md(4) devices. Reviewed by: kib Sponsored by: FreeBSD Foundation Modified: head/sbin/mdconfig/mdconfig.8 head/sbin/mdconfig/mdconfig.c head/sys/dev/md/md.c head/sys/sys/mdioctl.h Modified: head/sbin/mdconfig/mdconfig.8 ============================================================================== --- head/sbin/mdconfig/mdconfig.8 Sat Jul 7 20:21:05 2012 (r238214) +++ head/sbin/mdconfig/mdconfig.8 Sat Jul 7 20:32:21 2012 (r238215) @@ -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 @@ This will configure and attach a memory 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 "malloc" Modified: head/sbin/mdconfig/mdconfig.c ============================================================================== --- head/sbin/mdconfig/mdconfig.c Sat Jul 7 20:21:05 2012 (r238214) +++ head/sbin/mdconfig/mdconfig.c Sat Jul 7 20:32:21 2012 (r238215) @@ -54,7 +54,7 @@ #include <unistd.h> 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 @@ usage(void) " [-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"); @@ -96,7 +97,7 @@ main(int argc, char **argv) { int ch, fd, i, vflag; char *p; - char *fflag = NULL, *tflag = NULL, *uflag = NULL; + char *fflag = NULL, *sflag = NULL, *tflag = NULL, *uflag = NULL; bzero(&mdio, sizeof(mdio)); mdio.md_file = malloc(PATH_MAX); @@ -108,25 +109,32 @@ main(int argc, char **argv) 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; @@ -188,6 +196,9 @@ main(int argc, char **argv) mdio.md_sectorsize = strtoul(optarg, &p, 0); break; case 's': + if (sflag != NULL) + errx(1, "-s can be passed only once"); + sflag = optarg; mdio.md_mediasize = (off_t)strtoumax(optarg, &p, 0); if (p == NULL || *p == '\0') mdio.md_mediasize *= DEV_BSIZE; @@ -242,7 +253,7 @@ main(int argc, char **argv) mdio.md_type = MD_VNODE; mdio.md_options |= MD_CLUSTER | MD_AUTOUNIT | MD_COMPRESS; - } else if (mdio.md_mediasize != 0) { + } else if (sflag != NULL) { /* Imply ``-t swap'' */ mdio.md_type = MD_SWAP; mdio.md_options |= MD_CLUSTER | MD_AUTOUNIT | @@ -276,15 +287,15 @@ main(int argc, char **argv) } if ((mdio.md_type == MD_MALLOC || mdio.md_type == MD_SWAP) && - mdio.md_mediasize == 0) + sflag == NULL) errx(1, "must specify -s for -t malloc or -t swap"); if (mdio.md_type == MD_VNODE && mdio.md_file[0] == '\0') errx(1, "must specify -f for -t vnode"); } 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 && sflag != NULL) + 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 +306,20 @@ main(int argc, char **argv) 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 && sflag == NULL) + errx(1, "must specify -s for -r"); + if (action != LIST && vflag == OPT_VERBOSE) errx(1, "-v can only be used with -l"); @@ -333,6 +351,12 @@ main(int argc, char **argv) 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 +366,6 @@ main(int argc, char **argv) md_list(NULL, OPT_LIST | vflag); } else return (md_query(uflag)); - } else usage(); close(fd); Modified: head/sys/dev/md/md.c ============================================================================== --- head/sys/dev/md/md.c Sat Jul 7 20:21:05 2012 (r238214) +++ head/sys/dev/md/md.c Sat Jul 7 20:32:21 2012 (r238215) @@ -1081,6 +1081,64 @@ mddestroy(struct md_s *sc, struct thread } 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: + if (mdio->md_mediasize == 0 || + (mdio->md_mediasize % PAGE_SIZE) != 0) + return (EDOM); + oldpages = OFF_TO_IDX(round_page(sc->mediasize)); + newpages = OFF_TO_IDX(round_page(mdio->md_mediasize)); + if (newpages < oldpages) { + VM_OBJECT_LOCK(sc->object); + vm_object_page_remove(sc->object, newpages, 0, 0); + swap_pager_freespace(sc->object, newpages, + oldpages - newpages); + swap_release_by_cred(IDX_TO_OFF(oldpages - + newpages), sc->cred); + sc->object->charge = IDX_TO_OFF(newpages); + sc->object->size = newpages; + VM_OBJECT_UNLOCK(sc->object); + } else if (newpages > oldpages) { + res = swap_reserve_by_cred(IDX_TO_OFF(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( + IDX_TO_OFF(newpages - oldpages), + sc->cred); + return (EDOM); + } + } + VM_OBJECT_LOCK(sc->object); + sc->object->charge = IDX_TO_OFF(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 +1166,7 @@ mdcreate_swap(struct md_s *sc, struct md 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 +1275,18 @@ xmdctlioctl(struct cdev *dev, u_long cmd !(mdio->md_options & MD_FORCE)) return (EBUSY); return (mddestroy(sc, td)); + case MDIOCRESIZE: + if ((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) Modified: head/sys/sys/mdioctl.h ============================================================================== --- head/sys/sys/mdioctl.h Sat Jul 7 20:21:05 2012 (r238214) +++ head/sys/sys/mdioctl.h Sat Jul 7 20:32:21 2012 (r238215) @@ -79,6 +79,7 @@ struct md_ioctl { #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 */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201207072032.q67KWLt8084775>