svn commit: r331014 - head/sys/dev/md

Brooks Davis brooks at FreeBSD.org
Thu Mar 15 18:12:57 UTC 2018


Author: brooks
Date: Thu Mar 15 18:12:55 2018
New Revision: 331014
URL: https://svnweb.freebsd.org/changeset/base/331014

Log:
  Move implementation of ioctls into kern_*() functions.
  
  Move locks from outside ioctl to the individual implementations.
  
  This is the first step of changing the implementations to act on a
  kernel-internal request struct rather than on struct md_ioctl and to
  removing the use of kern_ioctl in mountroot.
  
  Reviewed by:	cem, kib, markj (prior version)
  Obtained from:	CheriBSD
  Sponsored by:	DARPA, AFRL
  Differential Revision:	https://reviews.freebsd.org/D14700

Modified:
  head/sys/dev/md/md.c

Modified: head/sys/dev/md/md.c
==============================================================================
--- head/sys/dev/md/md.c	Thu Mar 15 17:36:13 2018	(r331013)
+++ head/sys/dev/md/md.c	Thu Mar 15 18:12:55 2018	(r331014)
@@ -1607,13 +1607,253 @@ mdcreate_null(struct md_s *sc, struct md_ioctl *mdio, 
 }
 
 static int
-xmdctlioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
+kern_mdattach_locked(struct thread *td, struct md_ioctl *mdio)
 {
-	struct md_ioctl *mdio;
 	struct md_s *sc;
-	int error, i;
 	unsigned sectsize;
+	int error, i;
 
+	sx_assert(&md_sx, SA_XLOCKED);
+
+	switch (mdio->md_type) {
+	case MD_MALLOC:
+	case MD_PRELOAD:
+	case MD_VNODE:
+	case MD_SWAP:
+	case MD_NULL:
+		break;
+	default:
+		return (EINVAL);
+	}
+	if (mdio->md_sectorsize == 0)
+		sectsize = DEV_BSIZE;
+	else
+		sectsize = mdio->md_sectorsize;
+	if (sectsize > MAXPHYS || mdio->md_mediasize < sectsize)
+		return (EINVAL);
+	if (mdio->md_options & MD_AUTOUNIT)
+		sc = mdnew(-1, &error, mdio->md_type);
+	else {
+		if (mdio->md_unit > INT_MAX)
+			return (EINVAL);
+		sc = mdnew(mdio->md_unit, &error, mdio->md_type);
+	}
+	if (sc == NULL)
+		return (error);
+	if (mdio->md_label != NULL)
+		error = copyinstr(mdio->md_label, sc->label,
+		    sizeof(sc->label), NULL);
+	if (error != 0)
+		goto err_after_new;
+	if (mdio->md_options & MD_AUTOUNIT)
+		mdio->md_unit = sc->unit;
+	sc->mediasize = mdio->md_mediasize;
+	sc->sectorsize = sectsize;
+	error = EDOOFUS;
+	switch (sc->type) {
+	case MD_MALLOC:
+		sc->start = mdstart_malloc;
+		error = mdcreate_malloc(sc, mdio);
+		break;
+	case MD_PRELOAD:
+		/*
+		 * We disallow attaching preloaded memory disks via
+		 * ioctl. Preloaded memory disks are automatically
+		 * attached in g_md_init().
+		 */
+		error = EOPNOTSUPP;
+		break;
+	case MD_VNODE:
+		sc->start = mdstart_vnode;
+		error = mdcreate_vnode(sc, mdio, td);
+		break;
+	case MD_SWAP:
+		sc->start = mdstart_swap;
+		error = mdcreate_swap(sc, mdio, td);
+		break;
+	case MD_NULL:
+		sc->start = mdstart_null;
+		error = mdcreate_null(sc, mdio, td);
+		break;
+	}
+err_after_new:
+	if (error != 0) {
+		mddestroy(sc, td);
+		return (error);
+	}
+
+	/* Prune off any residual fractional sector */
+	i = sc->mediasize % sc->sectorsize;
+	sc->mediasize -= i;
+
+	mdinit(sc);
+	return (0);
+}
+
+static int
+kern_mdattach(struct thread *td, struct md_ioctl *mdio)
+{
+	int error;
+
+	sx_xlock(&md_sx);
+	error = kern_mdattach_locked(td, mdio);
+	sx_xunlock(&md_sx);
+	return (error);
+}
+
+static int
+kern_mddetach_locked(struct thread *td, struct md_ioctl *mdio)
+{
+	struct md_s *sc;
+
+	sx_assert(&md_sx, SA_XLOCKED);
+
+	if (mdio->md_mediasize != 0 ||
+	    (mdio->md_options & ~MD_FORCE) != 0)
+		return (EINVAL);
+
+	sc = mdfind(mdio->md_unit);
+	if (sc == NULL)
+		return (ENOENT);
+	if (sc->opencount != 0 && !(sc->flags & MD_FORCE) &&
+	    !(mdio->md_options & MD_FORCE))
+		return (EBUSY);
+	return (mddestroy(sc, td));
+}
+
+static int
+kern_mddetach(struct thread *td, struct md_ioctl *mdio)
+{
+	int error;
+
+	sx_xlock(&md_sx);
+	error = kern_mddetach_locked(td, mdio);
+	sx_xunlock(&md_sx);
+	return (error);
+}
+
+static int
+kern_mdresize_locked(struct md_ioctl *mdio)
+{
+	struct md_s *sc;
+
+	sx_assert(&md_sx, SA_XLOCKED);
+
+	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->sectorsize)
+		return (EINVAL);
+	if (mdio->md_mediasize < sc->mediasize &&
+	    !(sc->flags & MD_FORCE) &&
+	    !(mdio->md_options & MD_FORCE))
+		return (EBUSY);
+	return (mdresize(sc, mdio));
+}
+
+static int
+kern_mdresize(struct md_ioctl *mdio)
+{
+	int error;
+
+	sx_xlock(&md_sx);
+	error = kern_mdresize_locked(mdio);
+	sx_xunlock(&md_sx);
+	return (error);
+}
+
+static int
+kern_mdquery_locked(struct md_ioctl *mdio)
+{
+	struct md_s *sc;
+	int error;
+
+	sx_assert(&md_sx, SA_XLOCKED);
+
+	sc = mdfind(mdio->md_unit);
+	if (sc == NULL)
+		return (ENOENT);
+	mdio->md_type = sc->type;
+	mdio->md_options = sc->flags;
+	mdio->md_mediasize = sc->mediasize;
+	mdio->md_sectorsize = sc->sectorsize;
+	error = 0;
+	if (mdio->md_label != NULL) {
+		error = copyout(sc->label, mdio->md_label,
+		    strlen(sc->label) + 1);
+		if (error != 0)
+			return (error);
+	}
+	if (sc->type == MD_VNODE ||
+	    (sc->type == MD_PRELOAD && mdio->md_file != NULL))
+		error = copyout(sc->file, mdio->md_file,
+		    strlen(sc->file) + 1);
+	return (error);
+}
+
+static int
+kern_mdquery(struct md_ioctl *mdio)
+{
+	int error;
+
+	sx_xlock(&md_sx);
+	error = kern_mdquery_locked(mdio);
+	sx_xunlock(&md_sx);
+	return (error);
+}
+
+static int
+kern_mdlist_locked(struct md_ioctl *mdio)
+{
+	struct md_s *sc;
+	int i;
+
+	sx_assert(&md_sx, SA_XLOCKED);
+
+	/*
+	 * Write the number of md devices to mdio->md_pad[0].
+	 * Write the unit number of the first (MDNPAD - 2) units
+	 * to mdio->md_pad[1::(MDNPAD - 2)] and terminate the
+	 * list with -1.
+	 *
+	 * XXX: There is currently no mechanism to retrieve unit
+	 * numbers for more than (MDNPAD - 2) units.
+	 *
+	 * XXX: Due to the use of LIST_INSERT_HEAD in mdnew(), the
+	 * list of visible unit numbers not stable.
+	 */
+	i = 1;
+	LIST_FOREACH(sc, &md_softc_list, list) {
+		if (i < MDNPAD - 1)
+			mdio->md_pad[i] = sc->unit;
+		i++;
+	}
+	mdio->md_pad[MIN(i, MDNPAD - 1)] = -1;
+	mdio->md_pad[0] = i - 1;
+	return (0);
+}
+
+static int
+kern_mdlist(struct md_ioctl *mdio)
+{
+	int error;
+
+	sx_xlock(&md_sx);
+	error = kern_mdlist_locked(mdio);
+	sx_xunlock(&md_sx);
+	return (error);
+}
+
+static int
+mdctlioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags,
+    struct thread *td)
+{
+	struct md_ioctl *mdio;
+	int error;
+
 	if (md_debug)
 		printf("mdctlioctl(%s %lx %p %x %p)\n",
 			devtoname(dev), cmd, addr, flags, td);
@@ -1632,158 +1872,24 @@ xmdctlioctl(struct cdev *dev, u_long cmd, caddr_t addr
 	error = 0;
 	switch (cmd) {
 	case MDIOCATTACH:
-		switch (mdio->md_type) {
-		case MD_MALLOC:
-		case MD_PRELOAD:
-		case MD_VNODE:
-		case MD_SWAP:
-		case MD_NULL:
-			break;
-		default:
-			return (EINVAL);
-		}
-		if (mdio->md_sectorsize == 0)
-			sectsize = DEV_BSIZE;
-		else
-			sectsize = mdio->md_sectorsize;
-		if (sectsize > MAXPHYS || mdio->md_mediasize < sectsize)
-			return (EINVAL);
-		if (mdio->md_options & MD_AUTOUNIT)
-			sc = mdnew(-1, &error, mdio->md_type);
-		else {
-			if (mdio->md_unit > INT_MAX)
-				return (EINVAL);
-			sc = mdnew(mdio->md_unit, &error, mdio->md_type);
-		}
-		if (sc == NULL)
-			return (error);
-		if (mdio->md_label != NULL)
-			error = copyinstr(mdio->md_label, sc->label,
-			    sizeof(sc->label), NULL);
-		if (error != 0)
-			goto err_after_new;
-		if (mdio->md_options & MD_AUTOUNIT)
-			mdio->md_unit = sc->unit;
-		sc->mediasize = mdio->md_mediasize;
-		sc->sectorsize = sectsize;
-		error = EDOOFUS;
-		switch (sc->type) {
-		case MD_MALLOC:
-			sc->start = mdstart_malloc;
-			error = mdcreate_malloc(sc, mdio);
-			break;
-		case MD_PRELOAD:
-			/*
-			 * We disallow attaching preloaded memory disks via
-			 * ioctl. Preloaded memory disks are automatically
-			 * attached in g_md_init().
-			 */
-			error = EOPNOTSUPP;
-			break;
-		case MD_VNODE:
-			sc->start = mdstart_vnode;
-			error = mdcreate_vnode(sc, mdio, td);
-			break;
-		case MD_SWAP:
-			sc->start = mdstart_swap;
-			error = mdcreate_swap(sc, mdio, td);
-			break;
-		case MD_NULL:
-			sc->start = mdstart_null;
-			error = mdcreate_null(sc, mdio, td);
-			break;
-		}
-err_after_new:
-		if (error != 0) {
-			mddestroy(sc, td);
-			return (error);
-		}
-
-		/* Prune off any residual fractional sector */
-		i = sc->mediasize % sc->sectorsize;
-		sc->mediasize -= i;
-
-		mdinit(sc);
-		return (0);
+		error = kern_mdattach(td, mdio);
+		break;
 	case MDIOCDETACH:
-		if (mdio->md_mediasize != 0 ||
-		    (mdio->md_options & ~MD_FORCE) != 0)
-			return (EINVAL);
-
-		sc = mdfind(mdio->md_unit);
-		if (sc == NULL)
-			return (ENOENT);
-		if (sc->opencount != 0 && !(sc->flags & MD_FORCE) &&
-		    !(mdio->md_options & MD_FORCE))
-			return (EBUSY);
-		return (mddestroy(sc, td));
+		error = kern_mddetach(td, mdio);
+		break;
 	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->sectorsize)
-			return (EINVAL);
-		if (mdio->md_mediasize < sc->mediasize &&
-		    !(sc->flags & MD_FORCE) &&
-		    !(mdio->md_options & MD_FORCE))
-			return (EBUSY);
-		return (mdresize(sc, mdio));
+		error = kern_mdresize(mdio);
+		break;
 	case MDIOCQUERY:
-		sc = mdfind(mdio->md_unit);
-		if (sc == NULL)
-			return (ENOENT);
-		mdio->md_type = sc->type;
-		mdio->md_options = sc->flags;
-		mdio->md_mediasize = sc->mediasize;
-		mdio->md_sectorsize = sc->sectorsize;
-		error = 0;
-		if (mdio->md_label != NULL) {
-			error = copyout(sc->label, mdio->md_label,
-			    strlen(sc->label) + 1);
-		}
-		if (sc->type == MD_VNODE ||
-		    (sc->type == MD_PRELOAD && mdio->md_file != NULL))
-			error = copyout(sc->file, mdio->md_file,
-			    strlen(sc->file) + 1);
-		return (error);
+		error = kern_mdquery(mdio);
+		break;
 	case MDIOCLIST:
-		/*
-		 * Write the number of md devices to mdio->md_pad[0].
-		 * Write the unit number of the first (MDNPAD - 2) units
-		 * to mdio->md_pad[1::(MDNPAD - 2)] and terminate the
-		 * list with -1.
-		 *
-		 * XXX: There is currently no mechanism to retrieve unit
-		 * numbers for more than (MDNPAD - 2) units.
-		 *
-		 * XXX: Due to the use of LIST_INSERT_HEAD in mdnew(), the
-		 * list of visible unit numbers not stable.
-		 */
-		i = 1;
-		LIST_FOREACH(sc, &md_softc_list, list) {
-			if (i < MDNPAD - 1)
-				mdio->md_pad[i] = sc->unit;
-			i++;
-		}
-		mdio->md_pad[MIN(i, MDNPAD - 1)] = -1;
-		mdio->md_pad[0] = i - 1;
-		return (0);
+		error = kern_mdlist(mdio);
+		break;
 	default:
-		return (ENOIOCTL);
+		error = ENOIOCTL;
 	};
-}
 
-static int
-mdctlioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flags, struct thread *td)
-{
-	int error;
-
-	sx_xlock(&md_sx);
-	error = xmdctlioctl(dev, cmd, addr, flags, td);
-	sx_xunlock(&md_sx);
 	return (error);
 }
 


More information about the svn-src-head mailing list