Author: jh
Date: Fri Mar 18 08:48:06 2011
New Revision: 219728
URL: http://svn.freebsd.org/changeset/base/219728

Log:
  MFC r210371:
  
  Convert md(4) to use alloc_unr(9) and alloc_unr_specific(9) for unit
  number allocation. The old approach had some problems such as it allowed
  an overflow to occur in the unit number calculation.
  
  PR:           kern/122288

Modified:
  stable/8/sys/dev/md/md.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)

Modified: stable/8/sys/dev/md/md.c
==============================================================================
--- stable/8/sys/dev/md/md.c    Fri Mar 18 06:47:23 2011        (r219727)
+++ stable/8/sys/dev/md/md.c    Fri Mar 18 08:48:06 2011        (r219728)
@@ -132,6 +132,7 @@ static void g_md_dumpconf(struct sbuf *s
 static int     mdunits;
 static struct cdev *status_dev = 0;
 static struct sx md_sx;
+static struct unrhdr *md_uh;
 
 static d_ioctl_t mdctlioctl;
 
@@ -757,20 +758,20 @@ mdfind(int unit)
 static struct md_s *
 mdnew(int unit, int *errp, enum md_types type)
 {
-       struct md_s *sc, *sc2;
-       int error, max = -1;
+       struct md_s *sc;
+       int error;
 
        *errp = 0;
-       LIST_FOREACH(sc2, &md_softc_list, list) {
-               if (unit == sc2->unit) {
-                       *errp = EBUSY;
-                       return (NULL);
-               }
-               if (unit == -1 && sc2->unit > max) 
-                       max = sc2->unit;
-       }
        if (unit == -1)
-               unit = max + 1;
+               unit = alloc_unr(md_uh);
+       else
+               unit = alloc_unr_specific(md_uh, unit);
+
+       if (unit == -1) {
+               *errp = EBUSY;
+               return (NULL);
+       }
+
        sc = (struct md_s *)malloc(sizeof *sc, M_MD, M_WAITOK | M_ZERO);
        sc->type = type;
        bioq_init(&sc->bio_queue);
@@ -783,6 +784,7 @@ mdnew(int unit, int *errp, enum md_types
                return (sc);
        LIST_REMOVE(sc, list);
        mtx_destroy(&sc->queue_mtx);
+       free_unr(md_uh, sc->unit);
        free(sc, M_MD);
        *errp = error;
        return (NULL);
@@ -1022,6 +1024,7 @@ mddestroy(struct md_s *sc, struct thread
                uma_zdestroy(sc->uma);
 
        LIST_REMOVE(sc, list);
+       free_unr(md_uh, sc->unit);
        free(sc, M_MD);
        return (0);
 }
@@ -1107,8 +1110,11 @@ xmdctlioctl(struct cdev *dev, u_long cmd
                }
                if (mdio->md_options & MD_AUTOUNIT)
                        sc = mdnew(-1, &error, mdio->md_type);
-               else
+               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_options & MD_AUTOUNIT)
@@ -1236,6 +1242,7 @@ g_md_init(struct g_class *mp __unused)
        mod = NULL;
        sx_init(&md_sx, "MD config lock");
        g_topology_unlock();
+       md_uh = new_unrhdr(0, INT_MAX, NULL);
 #ifdef MD_ROOT_SIZE
        sx_xlock(&md_sx);
        md_preloaded(mfs_root.start, sizeof(mfs_root.start));
@@ -1332,4 +1339,5 @@ g_md_fini(struct g_class *mp __unused)
        sx_destroy(&md_sx);
        if (status_dev != NULL)
                destroy_dev(status_dev);
+       delete_unrhdr(md_uh);
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to