The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/geom/geom_subr.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-3-Clause
    3  *
    4  * Copyright (c) 2002 Poul-Henning Kamp
    5  * Copyright (c) 2002 Networks Associates Technology, Inc.
    6  * All rights reserved.
    7  *
    8  * This software was developed for the FreeBSD Project by Poul-Henning Kamp
    9  * and NAI Labs, the Security Research Division of Network Associates, Inc.
   10  * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
   11  * DARPA CHATS research program.
   12  *
   13  * Redistribution and use in source and binary forms, with or without
   14  * modification, are permitted provided that the following conditions
   15  * are met:
   16  * 1. Redistributions of source code must retain the above copyright
   17  *    notice, this list of conditions and the following disclaimer.
   18  * 2. Redistributions in binary form must reproduce the above copyright
   19  *    notice, this list of conditions and the following disclaimer in the
   20  *    documentation and/or other materials provided with the distribution.
   21  * 3. The names of the authors may not be used to endorse or promote
   22  *    products derived from this software without specific prior written
   23  *    permission.
   24  *
   25  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   35  * SUCH DAMAGE.
   36  */
   37 
   38 #include <sys/cdefs.h>
   39 __FBSDID("$FreeBSD$");
   40 
   41 #include "opt_ddb.h"
   42 
   43 #include <sys/param.h>
   44 #include <sys/systm.h>
   45 #include <sys/devicestat.h>
   46 #include <sys/kernel.h>
   47 #include <sys/malloc.h>
   48 #include <sys/bio.h>
   49 #include <sys/sysctl.h>
   50 #include <sys/proc.h>
   51 #include <sys/kthread.h>
   52 #include <sys/lock.h>
   53 #include <sys/mutex.h>
   54 #include <sys/errno.h>
   55 #include <sys/sbuf.h>
   56 #include <sys/sdt.h>
   57 #include <geom/geom.h>
   58 #include <geom/geom_int.h>
   59 #include <machine/stdarg.h>
   60 
   61 #ifdef DDB
   62 #include <ddb/ddb.h>
   63 #endif
   64 
   65 #ifdef KDB
   66 #include <sys/kdb.h>
   67 #endif
   68 
   69 SDT_PROVIDER_DEFINE(geom);
   70 
   71 struct class_list_head g_classes = LIST_HEAD_INITIALIZER(g_classes);
   72 static struct g_tailq_head geoms = TAILQ_HEAD_INITIALIZER(geoms);
   73 char *g_wait_event, *g_wait_up, *g_wait_down, *g_wait_sim;
   74 
   75 struct g_hh00 {
   76         struct g_class          *mp;
   77         struct g_provider       *pp;
   78         off_t                   size;
   79         int                     error;
   80         int                     post;
   81 };
   82 
   83 /*
   84  * This event offers a new class a chance to taste all preexisting providers.
   85  */
   86 static void
   87 g_load_class(void *arg, int flag)
   88 {
   89         struct g_hh00 *hh;
   90         struct g_class *mp2, *mp;
   91         struct g_geom *gp;
   92         struct g_provider *pp;
   93 
   94         g_topology_assert();
   95         if (flag == EV_CANCEL)  /* XXX: can't happen ? */
   96                 return;
   97         if (g_shutdown)
   98                 return;
   99 
  100         hh = arg;
  101         mp = hh->mp;
  102         hh->error = 0;
  103         if (hh->post) {
  104                 g_free(hh);
  105                 hh = NULL;
  106         }
  107         g_trace(G_T_TOPOLOGY, "g_load_class(%s)", mp->name);
  108         KASSERT(mp->name != NULL && *mp->name != '\0',
  109             ("GEOM class has no name"));
  110         LIST_FOREACH(mp2, &g_classes, class) {
  111                 if (mp2 == mp) {
  112                         printf("The GEOM class %s is already loaded.\n",
  113                             mp2->name);
  114                         if (hh != NULL)
  115                                 hh->error = EEXIST;
  116                         return;
  117                 } else if (strcmp(mp2->name, mp->name) == 0) {
  118                         printf("A GEOM class %s is already loaded.\n",
  119                             mp2->name);
  120                         if (hh != NULL)
  121                                 hh->error = EEXIST;
  122                         return;
  123                 }
  124         }
  125 
  126         LIST_INIT(&mp->geom);
  127         LIST_INSERT_HEAD(&g_classes, mp, class);
  128         if (mp->init != NULL)
  129                 mp->init(mp);
  130         if (mp->taste == NULL)
  131                 return;
  132         LIST_FOREACH(mp2, &g_classes, class) {
  133                 if (mp == mp2)
  134                         continue;
  135                 LIST_FOREACH(gp, &mp2->geom, geom) {
  136                         LIST_FOREACH(pp, &gp->provider, provider) {
  137                                 mp->taste(mp, pp, 0);
  138                                 g_topology_assert();
  139                         }
  140                 }
  141         }
  142 }
  143 
  144 static int
  145 g_unload_class(struct g_class *mp)
  146 {
  147         struct g_geom *gp;
  148         struct g_provider *pp;
  149         struct g_consumer *cp;
  150         int error;
  151 
  152         g_topology_lock();
  153         g_trace(G_T_TOPOLOGY, "g_unload_class(%s)", mp->name);
  154 retry:
  155         G_VALID_CLASS(mp);
  156         LIST_FOREACH(gp, &mp->geom, geom) {
  157                 /* We refuse to unload if anything is open */
  158                 LIST_FOREACH(pp, &gp->provider, provider)
  159                         if (pp->acr || pp->acw || pp->ace) {
  160                                 g_topology_unlock();
  161                                 return (EBUSY);
  162                         }
  163                 LIST_FOREACH(cp, &gp->consumer, consumer)
  164                         if (cp->acr || cp->acw || cp->ace) {
  165                                 g_topology_unlock();
  166                                 return (EBUSY);
  167                         }
  168                 /* If the geom is withering, wait for it to finish. */
  169                 if (gp->flags & G_GEOM_WITHER) {
  170                         g_topology_sleep(mp, 1);
  171                         goto retry;
  172                 }
  173         }
  174 
  175         /*
  176          * We allow unloading if we have no geoms, or a class
  177          * method we can use to get rid of them.
  178          */
  179         if (!LIST_EMPTY(&mp->geom) && mp->destroy_geom == NULL) {
  180                 g_topology_unlock();
  181                 return (EOPNOTSUPP);
  182         }
  183 
  184         /* Bar new entries */
  185         mp->taste = NULL;
  186         mp->config = NULL;
  187 
  188         LIST_FOREACH(gp, &mp->geom, geom) {
  189                 error = mp->destroy_geom(NULL, mp, gp);
  190                 if (error != 0) {
  191                         g_topology_unlock();
  192                         return (error);
  193                 }
  194         }
  195         /* Wait for withering to finish. */
  196         for (;;) {
  197                 gp = LIST_FIRST(&mp->geom);
  198                 if (gp == NULL)
  199                         break;
  200                 KASSERT(gp->flags & G_GEOM_WITHER,
  201                    ("Non-withering geom in class %s", mp->name));
  202                 g_topology_sleep(mp, 1);
  203         }
  204         G_VALID_CLASS(mp);
  205         if (mp->fini != NULL)
  206                 mp->fini(mp);
  207         LIST_REMOVE(mp, class);
  208         g_topology_unlock();
  209 
  210         return (0);
  211 }
  212 
  213 int
  214 g_modevent(module_t mod, int type, void *data)
  215 {
  216         struct g_hh00 *hh;
  217         int error;
  218         static int g_ignition;
  219         struct g_class *mp;
  220 
  221         mp = data;
  222         if (mp->version != G_VERSION) {
  223                 printf("GEOM class %s has Wrong version %x\n",
  224                     mp->name, mp->version);
  225                 return (EINVAL);
  226         }
  227         if (!g_ignition) {
  228                 g_ignition++;
  229                 g_init();
  230         }
  231         error = EOPNOTSUPP;
  232         switch (type) {
  233         case MOD_LOAD:
  234                 g_trace(G_T_TOPOLOGY, "g_modevent(%s, LOAD)", mp->name);
  235                 hh = g_malloc(sizeof *hh, M_WAITOK | M_ZERO);
  236                 hh->mp = mp;
  237                 /*
  238                  * Once the system is not cold, MOD_LOAD calls will be
  239                  * from the userland and the g_event thread will be able
  240                  * to acknowledge their completion.
  241                  */
  242                 if (cold) {
  243                         hh->post = 1;
  244                         error = g_post_event(g_load_class, hh, M_WAITOK, NULL);
  245                 } else {
  246                         error = g_waitfor_event(g_load_class, hh, M_WAITOK,
  247                             NULL);
  248                         if (error == 0)
  249                                 error = hh->error;
  250                         g_free(hh);
  251                 }
  252                 break;
  253         case MOD_UNLOAD:
  254                 g_trace(G_T_TOPOLOGY, "g_modevent(%s, UNLOAD)", mp->name);
  255                 error = g_unload_class(mp);
  256                 if (error == 0) {
  257                         KASSERT(LIST_EMPTY(&mp->geom),
  258                             ("Unloaded class (%s) still has geom", mp->name));
  259                 }
  260                 break;
  261         }
  262         return (error);
  263 }
  264 
  265 static void
  266 g_retaste_event(void *arg, int flag)
  267 {
  268         struct g_class *mp, *mp2;
  269         struct g_geom *gp;
  270         struct g_hh00 *hh;
  271         struct g_provider *pp;
  272         struct g_consumer *cp;
  273 
  274         g_topology_assert();
  275         if (flag == EV_CANCEL)  /* XXX: can't happen ? */
  276                 return;
  277         if (g_shutdown || g_notaste)
  278                 return;
  279 
  280         hh = arg;
  281         mp = hh->mp;
  282         hh->error = 0;
  283         if (hh->post) {
  284                 g_free(hh);
  285                 hh = NULL;
  286         }
  287         g_trace(G_T_TOPOLOGY, "g_retaste(%s)", mp->name);
  288 
  289         LIST_FOREACH(mp2, &g_classes, class) {
  290                 LIST_FOREACH(gp, &mp2->geom, geom) {
  291                         LIST_FOREACH(pp, &gp->provider, provider) {
  292                                 if (pp->acr || pp->acw || pp->ace)
  293                                         continue;
  294                                 LIST_FOREACH(cp, &pp->consumers, consumers) {
  295                                         if (cp->geom->class == mp &&
  296                                             (cp->flags & G_CF_ORPHAN) == 0)
  297                                                 break;
  298                                 }
  299                                 if (cp != NULL) {
  300                                         cp->flags |= G_CF_ORPHAN;
  301                                         g_wither_geom(cp->geom, ENXIO);
  302                                 }
  303                                 mp->taste(mp, pp, 0);
  304                                 g_topology_assert();
  305                         }
  306                 }
  307         }
  308 }
  309 
  310 int
  311 g_retaste(struct g_class *mp)
  312 {
  313         struct g_hh00 *hh;
  314         int error;
  315 
  316         if (mp->taste == NULL)
  317                 return (EINVAL);
  318 
  319         hh = g_malloc(sizeof *hh, M_WAITOK | M_ZERO);
  320         hh->mp = mp;
  321 
  322         if (cold) {
  323                 hh->post = 1;
  324                 error = g_post_event(g_retaste_event, hh, M_WAITOK, NULL);
  325         } else {
  326                 error = g_waitfor_event(g_retaste_event, hh, M_WAITOK, NULL);
  327                 if (error == 0)
  328                         error = hh->error;
  329                 g_free(hh);
  330         }
  331 
  332         return (error);
  333 }
  334 
  335 struct g_geom *
  336 g_new_geomf(struct g_class *mp, const char *fmt, ...)
  337 {
  338         struct g_geom *gp;
  339         va_list ap;
  340         struct sbuf *sb;
  341 
  342         g_topology_assert();
  343         G_VALID_CLASS(mp);
  344         sb = sbuf_new_auto();
  345         va_start(ap, fmt);
  346         sbuf_vprintf(sb, fmt, ap);
  347         va_end(ap);
  348         sbuf_finish(sb);
  349         gp = g_malloc(sizeof *gp, M_WAITOK | M_ZERO);
  350         gp->name = g_malloc(sbuf_len(sb) + 1, M_WAITOK | M_ZERO);
  351         gp->class = mp;
  352         gp->rank = 1;
  353         LIST_INIT(&gp->consumer);
  354         LIST_INIT(&gp->provider);
  355         LIST_INIT(&gp->aliases);
  356         LIST_INSERT_HEAD(&mp->geom, gp, geom);
  357         TAILQ_INSERT_HEAD(&geoms, gp, geoms);
  358         strcpy(gp->name, sbuf_data(sb));
  359         sbuf_delete(sb);
  360         /* Fill in defaults from class */
  361         gp->start = mp->start;
  362         gp->spoiled = mp->spoiled;
  363         gp->attrchanged = mp->attrchanged;
  364         gp->providergone = mp->providergone;
  365         gp->dumpconf = mp->dumpconf;
  366         gp->access = mp->access;
  367         gp->orphan = mp->orphan;
  368         gp->ioctl = mp->ioctl;
  369         gp->resize = mp->resize;
  370         return (gp);
  371 }
  372 
  373 void
  374 g_destroy_geom(struct g_geom *gp)
  375 {
  376         struct g_geom_alias *gap, *gaptmp;
  377 
  378         g_topology_assert();
  379         G_VALID_GEOM(gp);
  380         g_trace(G_T_TOPOLOGY, "g_destroy_geom(%p(%s))", gp, gp->name);
  381         KASSERT(LIST_EMPTY(&gp->consumer),
  382             ("g_destroy_geom(%s) with consumer(s) [%p]",
  383             gp->name, LIST_FIRST(&gp->consumer)));
  384         KASSERT(LIST_EMPTY(&gp->provider),
  385             ("g_destroy_geom(%s) with provider(s) [%p]",
  386             gp->name, LIST_FIRST(&gp->provider)));
  387         g_cancel_event(gp);
  388         LIST_REMOVE(gp, geom);
  389         TAILQ_REMOVE(&geoms, gp, geoms);
  390         LIST_FOREACH_SAFE(gap, &gp->aliases, ga_next, gaptmp)
  391                 g_free(gap);
  392         g_free(gp->name);
  393         g_free(gp);
  394 }
  395 
  396 /*
  397  * This function is called (repeatedly) until the geom has withered away.
  398  */
  399 void
  400 g_wither_geom(struct g_geom *gp, int error)
  401 {
  402         struct g_provider *pp;
  403 
  404         g_topology_assert();
  405         G_VALID_GEOM(gp);
  406         g_trace(G_T_TOPOLOGY, "g_wither_geom(%p(%s))", gp, gp->name);
  407         if (!(gp->flags & G_GEOM_WITHER)) {
  408                 gp->flags |= G_GEOM_WITHER;
  409                 LIST_FOREACH(pp, &gp->provider, provider)
  410                         if (!(pp->flags & G_PF_ORPHAN))
  411                                 g_orphan_provider(pp, error);
  412         }
  413         g_do_wither();
  414 }
  415 
  416 /*
  417  * Convenience function to destroy a particular provider.
  418  */
  419 void
  420 g_wither_provider(struct g_provider *pp, int error)
  421 {
  422 
  423         pp->flags |= G_PF_WITHER;
  424         if (!(pp->flags & G_PF_ORPHAN))
  425                 g_orphan_provider(pp, error);
  426 }
  427 
  428 /*
  429  * This function is called (repeatedly) until the has withered away.
  430  */
  431 void
  432 g_wither_geom_close(struct g_geom *gp, int error)
  433 {
  434         struct g_consumer *cp;
  435 
  436         g_topology_assert();
  437         G_VALID_GEOM(gp);
  438         g_trace(G_T_TOPOLOGY, "g_wither_geom_close(%p(%s))", gp, gp->name);
  439         LIST_FOREACH(cp, &gp->consumer, consumer)
  440                 if (cp->acr || cp->acw || cp->ace)
  441                         g_access(cp, -cp->acr, -cp->acw, -cp->ace);
  442         g_wither_geom(gp, error);
  443 }
  444 
  445 /*
  446  * This function is called (repeatedly) until we cant wash away more
  447  * withered bits at present.
  448  */
  449 void
  450 g_wither_washer(void)
  451 {
  452         struct g_class *mp;
  453         struct g_geom *gp, *gp2;
  454         struct g_provider *pp, *pp2;
  455         struct g_consumer *cp, *cp2;
  456 
  457         g_topology_assert();
  458         LIST_FOREACH(mp, &g_classes, class) {
  459                 LIST_FOREACH_SAFE(gp, &mp->geom, geom, gp2) {
  460                         LIST_FOREACH_SAFE(pp, &gp->provider, provider, pp2) {
  461                                 if (!(pp->flags & G_PF_WITHER))
  462                                         continue;
  463                                 if (LIST_EMPTY(&pp->consumers))
  464                                         g_destroy_provider(pp);
  465                         }
  466                         if (!(gp->flags & G_GEOM_WITHER))
  467                                 continue;
  468                         LIST_FOREACH_SAFE(pp, &gp->provider, provider, pp2) {
  469                                 if (LIST_EMPTY(&pp->consumers))
  470                                         g_destroy_provider(pp);
  471                         }
  472                         LIST_FOREACH_SAFE(cp, &gp->consumer, consumer, cp2) {
  473                                 if (cp->acr || cp->acw || cp->ace)
  474                                         continue;
  475                                 if (cp->provider != NULL)
  476                                         g_detach(cp);
  477                                 g_destroy_consumer(cp);
  478                         }
  479                         if (LIST_EMPTY(&gp->provider) &&
  480                             LIST_EMPTY(&gp->consumer))
  481                                 g_destroy_geom(gp);
  482                 }
  483         }
  484 }
  485 
  486 struct g_consumer *
  487 g_new_consumer(struct g_geom *gp)
  488 {
  489         struct g_consumer *cp;
  490 
  491         g_topology_assert();
  492         G_VALID_GEOM(gp);
  493         KASSERT(!(gp->flags & G_GEOM_WITHER),
  494             ("g_new_consumer on WITHERing geom(%s) (class %s)",
  495             gp->name, gp->class->name));
  496         KASSERT(gp->orphan != NULL,
  497             ("g_new_consumer on geom(%s) (class %s) without orphan",
  498             gp->name, gp->class->name));
  499 
  500         cp = g_malloc(sizeof *cp, M_WAITOK | M_ZERO);
  501         cp->geom = gp;
  502         cp->stat = devstat_new_entry(cp, -1, 0, DEVSTAT_ALL_SUPPORTED,
  503             DEVSTAT_TYPE_DIRECT, DEVSTAT_PRIORITY_MAX);
  504         LIST_INSERT_HEAD(&gp->consumer, cp, consumer);
  505         return(cp);
  506 }
  507 
  508 void
  509 g_destroy_consumer(struct g_consumer *cp)
  510 {
  511         struct g_geom *gp;
  512 
  513         g_topology_assert();
  514         G_VALID_CONSUMER(cp);
  515         g_trace(G_T_TOPOLOGY, "g_destroy_consumer(%p)", cp);
  516         KASSERT (cp->provider == NULL, ("g_destroy_consumer but attached"));
  517         KASSERT (cp->acr == 0, ("g_destroy_consumer with acr"));
  518         KASSERT (cp->acw == 0, ("g_destroy_consumer with acw"));
  519         KASSERT (cp->ace == 0, ("g_destroy_consumer with ace"));
  520         g_cancel_event(cp);
  521         gp = cp->geom;
  522         LIST_REMOVE(cp, consumer);
  523         devstat_remove_entry(cp->stat);
  524         g_free(cp);
  525         if (gp->flags & G_GEOM_WITHER)
  526                 g_do_wither();
  527 }
  528 
  529 static void
  530 g_new_provider_event(void *arg, int flag)
  531 {
  532         struct g_class *mp;
  533         struct g_provider *pp;
  534         struct g_consumer *cp, *next_cp;
  535 
  536         g_topology_assert();
  537         if (flag == EV_CANCEL)
  538                 return;
  539         if (g_shutdown)
  540                 return;
  541         pp = arg;
  542         G_VALID_PROVIDER(pp);
  543         KASSERT(!(pp->flags & G_PF_WITHER),
  544             ("g_new_provider_event but withered"));
  545         LIST_FOREACH_SAFE(cp, &pp->consumers, consumers, next_cp) {
  546                 if ((cp->flags & G_CF_ORPHAN) == 0 &&
  547                     cp->geom->attrchanged != NULL)
  548                         cp->geom->attrchanged(cp, "GEOM::media");
  549         }
  550         if (g_notaste)
  551                 return;
  552         LIST_FOREACH(mp, &g_classes, class) {
  553                 if (mp->taste == NULL)
  554                         continue;
  555                 LIST_FOREACH(cp, &pp->consumers, consumers)
  556                         if (cp->geom->class == mp &&
  557                             (cp->flags & G_CF_ORPHAN) == 0)
  558                                 break;
  559                 if (cp != NULL)
  560                         continue;
  561                 mp->taste(mp, pp, 0);
  562                 g_topology_assert();
  563         }
  564 }
  565 
  566 
  567 struct g_provider *
  568 g_new_providerf(struct g_geom *gp, const char *fmt, ...)
  569 {
  570         struct g_provider *pp;
  571         struct sbuf *sb;
  572         va_list ap;
  573 
  574         g_topology_assert();
  575         G_VALID_GEOM(gp);
  576         KASSERT(gp->access != NULL,
  577             ("new provider on geom(%s) without ->access (class %s)",
  578             gp->name, gp->class->name));
  579         KASSERT(gp->start != NULL,
  580             ("new provider on geom(%s) without ->start (class %s)",
  581             gp->name, gp->class->name));
  582         KASSERT(!(gp->flags & G_GEOM_WITHER),
  583             ("new provider on WITHERing geom(%s) (class %s)",
  584             gp->name, gp->class->name));
  585         sb = sbuf_new_auto();
  586         va_start(ap, fmt);
  587         sbuf_vprintf(sb, fmt, ap);
  588         va_end(ap);
  589         sbuf_finish(sb);
  590         pp = g_malloc(sizeof *pp + sbuf_len(sb) + 1, M_WAITOK | M_ZERO);
  591         pp->name = (char *)(pp + 1);
  592         strcpy(pp->name, sbuf_data(sb));
  593         sbuf_delete(sb);
  594         LIST_INIT(&pp->consumers);
  595         pp->error = ENXIO;
  596         pp->geom = gp;
  597         pp->stat = devstat_new_entry(pp, -1, 0, DEVSTAT_ALL_SUPPORTED,
  598             DEVSTAT_TYPE_DIRECT, DEVSTAT_PRIORITY_MAX);
  599         LIST_INSERT_HEAD(&gp->provider, pp, provider);
  600         g_post_event(g_new_provider_event, pp, M_WAITOK, pp, gp, NULL);
  601         return (pp);
  602 }
  603 
  604 void
  605 g_error_provider(struct g_provider *pp, int error)
  606 {
  607 
  608         /* G_VALID_PROVIDER(pp);  We may not have g_topology */
  609         pp->error = error;
  610 }
  611 
  612 static void
  613 g_resize_provider_event(void *arg, int flag)
  614 {
  615         struct g_hh00 *hh;
  616         struct g_class *mp;
  617         struct g_geom *gp;
  618         struct g_provider *pp;
  619         struct g_consumer *cp, *cp2;
  620         off_t size;
  621 
  622         g_topology_assert();
  623         if (g_shutdown)
  624                 return;
  625 
  626         hh = arg;
  627         pp = hh->pp;
  628         size = hh->size;
  629         g_free(hh);
  630 
  631         G_VALID_PROVIDER(pp);
  632         KASSERT(!(pp->flags & G_PF_WITHER),
  633             ("g_resize_provider_event but withered"));
  634         g_trace(G_T_TOPOLOGY, "g_resize_provider_event(%p)", pp);
  635 
  636         LIST_FOREACH_SAFE(cp, &pp->consumers, consumers, cp2) {
  637                 gp = cp->geom;
  638                 if (gp->resize == NULL && size < pp->mediasize) {
  639                         /*
  640                          * XXX: g_dev_orphan method does deferred destroying
  641                          * and it is possible, that other event could already
  642                          * call the orphan method. Check consumer's flags to
  643                          * do not schedule it twice.
  644                          */
  645                         if (cp->flags & G_CF_ORPHAN)
  646                                 continue;
  647                         cp->flags |= G_CF_ORPHAN;
  648                         cp->geom->orphan(cp);
  649                 }
  650         }
  651 
  652         pp->mediasize = size;
  653         
  654         LIST_FOREACH_SAFE(cp, &pp->consumers, consumers, cp2) {
  655                 gp = cp->geom;
  656                 if ((gp->flags & G_GEOM_WITHER) == 0 && gp->resize != NULL)
  657                         gp->resize(cp);
  658         }
  659 
  660         /*
  661          * After resizing, the previously invalid GEOM class metadata
  662          * might become valid.  This means we should retaste.
  663          */
  664         LIST_FOREACH(mp, &g_classes, class) {
  665                 if (mp->taste == NULL)
  666                         continue;
  667                 LIST_FOREACH(cp, &pp->consumers, consumers)
  668                         if (cp->geom->class == mp &&
  669                             (cp->flags & G_CF_ORPHAN) == 0)
  670                                 break;
  671                 if (cp != NULL)
  672                         continue;
  673                 mp->taste(mp, pp, 0);
  674                 g_topology_assert();
  675         }
  676 }
  677 
  678 void
  679 g_resize_provider(struct g_provider *pp, off_t size)
  680 {
  681         struct g_hh00 *hh;
  682 
  683         G_VALID_PROVIDER(pp);
  684         if (pp->flags & G_PF_WITHER)
  685                 return;
  686 
  687         if (size == pp->mediasize)
  688                 return;
  689 
  690         hh = g_malloc(sizeof *hh, M_WAITOK | M_ZERO);
  691         hh->pp = pp;
  692         hh->size = size;
  693         g_post_event(g_resize_provider_event, hh, M_WAITOK, NULL);
  694 }
  695 
  696 #ifndef _PATH_DEV
  697 #define _PATH_DEV       "/dev/"
  698 #endif
  699 
  700 struct g_provider *
  701 g_provider_by_name(char const *arg)
  702 {
  703         struct g_class *cp;
  704         struct g_geom *gp;
  705         struct g_provider *pp, *wpp;
  706 
  707         if (strncmp(arg, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
  708                 arg += sizeof(_PATH_DEV) - 1;
  709 
  710         wpp = NULL;
  711         LIST_FOREACH(cp, &g_classes, class) {
  712                 LIST_FOREACH(gp, &cp->geom, geom) {
  713                         LIST_FOREACH(pp, &gp->provider, provider) {
  714                                 if (strcmp(arg, pp->name) != 0)
  715                                         continue;
  716                                 if ((gp->flags & G_GEOM_WITHER) == 0 &&
  717                                     (pp->flags & G_PF_WITHER) == 0)
  718                                         return (pp);
  719                                 else
  720                                         wpp = pp;
  721                         }
  722                 }
  723         }
  724 
  725         return (wpp);
  726 }
  727 
  728 void
  729 g_destroy_provider(struct g_provider *pp)
  730 {
  731         struct g_geom *gp;
  732 
  733         g_topology_assert();
  734         G_VALID_PROVIDER(pp);
  735         KASSERT(LIST_EMPTY(&pp->consumers),
  736             ("g_destroy_provider but attached"));
  737         KASSERT (pp->acr == 0, ("g_destroy_provider with acr"));
  738         KASSERT (pp->acw == 0, ("g_destroy_provider with acw"));
  739         KASSERT (pp->ace == 0, ("g_destroy_provider with ace"));
  740         g_cancel_event(pp);
  741         LIST_REMOVE(pp, provider);
  742         gp = pp->geom;
  743         devstat_remove_entry(pp->stat);
  744         /*
  745          * If a callback was provided, send notification that the provider
  746          * is now gone.
  747          */
  748         if (gp->providergone != NULL)
  749                 gp->providergone(pp);
  750 
  751         g_free(pp);
  752         if ((gp->flags & G_GEOM_WITHER))
  753                 g_do_wither();
  754 }
  755 
  756 /*
  757  * We keep the "geoms" list sorted by topological order (== increasing
  758  * numerical rank) at all times.
  759  * When an attach is done, the attaching geoms rank is invalidated
  760  * and it is moved to the tail of the list.
  761  * All geoms later in the sequence has their ranks reevaluated in
  762  * sequence.  If we cannot assign rank to a geom because it's
  763  * prerequisites do not have rank, we move that element to the tail
  764  * of the sequence with invalid rank as well.
  765  * At some point we encounter our original geom and if we stil fail
  766  * to assign it a rank, there must be a loop and we fail back to
  767  * g_attach() which detach again and calls redo_rank again
  768  * to fix up the damage.
  769  * It would be much simpler code wise to do it recursively, but we
  770  * can't risk that on the kernel stack.
  771  */
  772 
  773 static int
  774 redo_rank(struct g_geom *gp)
  775 {
  776         struct g_consumer *cp;
  777         struct g_geom *gp1, *gp2;
  778         int n, m;
  779 
  780         g_topology_assert();
  781         G_VALID_GEOM(gp);
  782 
  783         /* Invalidate this geoms rank and move it to the tail */
  784         gp1 = TAILQ_NEXT(gp, geoms);
  785         if (gp1 != NULL) {
  786                 gp->rank = 0;
  787                 TAILQ_REMOVE(&geoms, gp, geoms);
  788                 TAILQ_INSERT_TAIL(&geoms, gp, geoms);
  789         } else {
  790                 gp1 = gp;
  791         }
  792 
  793         /* re-rank the rest of the sequence */
  794         for (; gp1 != NULL; gp1 = gp2) {
  795                 gp1->rank = 0;
  796                 m = 1;
  797                 LIST_FOREACH(cp, &gp1->consumer, consumer) {
  798                         if (cp->provider == NULL)
  799                                 continue;
  800                         n = cp->provider->geom->rank;
  801                         if (n == 0) {
  802                                 m = 0;
  803                                 break;
  804                         } else if (n >= m)
  805                                 m = n + 1;
  806                 }
  807                 gp1->rank = m;
  808                 gp2 = TAILQ_NEXT(gp1, geoms);
  809 
  810                 /* got a rank, moving on */
  811                 if (m != 0)
  812                         continue;
  813 
  814                 /* no rank to original geom means loop */
  815                 if (gp == gp1) 
  816                         return (ELOOP);
  817 
  818                 /* no rank, put it at the end move on */
  819                 TAILQ_REMOVE(&geoms, gp1, geoms);
  820                 TAILQ_INSERT_TAIL(&geoms, gp1, geoms);
  821         }
  822         return (0);
  823 }
  824 
  825 int
  826 g_attach(struct g_consumer *cp, struct g_provider *pp)
  827 {
  828         int error;
  829 
  830         g_topology_assert();
  831         G_VALID_CONSUMER(cp);
  832         G_VALID_PROVIDER(pp);
  833         g_trace(G_T_TOPOLOGY, "g_attach(%p, %p)", cp, pp);
  834         KASSERT(cp->provider == NULL, ("attach but attached"));
  835         cp->provider = pp;
  836         cp->flags &= ~G_CF_ORPHAN;
  837         LIST_INSERT_HEAD(&pp->consumers, cp, consumers);
  838         error = redo_rank(cp->geom);
  839         if (error) {
  840                 LIST_REMOVE(cp, consumers);
  841                 cp->provider = NULL;
  842                 redo_rank(cp->geom);
  843         }
  844         return (error);
  845 }
  846 
  847 void
  848 g_detach(struct g_consumer *cp)
  849 {
  850         struct g_provider *pp;
  851 
  852         g_topology_assert();
  853         G_VALID_CONSUMER(cp);
  854         g_trace(G_T_TOPOLOGY, "g_detach(%p)", cp);
  855         KASSERT(cp->provider != NULL, ("detach but not attached"));
  856         KASSERT(cp->acr == 0, ("detach but nonzero acr"));
  857         KASSERT(cp->acw == 0, ("detach but nonzero acw"));
  858         KASSERT(cp->ace == 0, ("detach but nonzero ace"));
  859         KASSERT(cp->nstart == cp->nend,
  860             ("detach with active requests"));
  861         pp = cp->provider;
  862         LIST_REMOVE(cp, consumers);
  863         cp->provider = NULL;
  864         if ((cp->geom->flags & G_GEOM_WITHER) ||
  865             (pp->geom->flags & G_GEOM_WITHER) ||
  866             (pp->flags & G_PF_WITHER))
  867                 g_do_wither();
  868         redo_rank(cp->geom);
  869 }
  870 
  871 /*
  872  * g_access()
  873  *
  874  * Access-check with delta values.  The question asked is "can provider
  875  * "cp" change the access counters by the relative amounts dc[rwe] ?"
  876  */
  877 
  878 int
  879 g_access(struct g_consumer *cp, int dcr, int dcw, int dce)
  880 {
  881         struct g_provider *pp;
  882         struct g_geom *gp;
  883         int pw, pe;
  884 #ifdef INVARIANTS
  885         int sr, sw, se;
  886 #endif
  887         int error;
  888 
  889         g_topology_assert();
  890         G_VALID_CONSUMER(cp);
  891         pp = cp->provider;
  892         KASSERT(pp != NULL, ("access but not attached"));
  893         G_VALID_PROVIDER(pp);
  894         gp = pp->geom;
  895 
  896         g_trace(G_T_ACCESS, "g_access(%p(%s), %d, %d, %d)",
  897             cp, pp->name, dcr, dcw, dce);
  898 
  899         KASSERT(cp->acr + dcr >= 0, ("access resulting in negative acr"));
  900         KASSERT(cp->acw + dcw >= 0, ("access resulting in negative acw"));
  901         KASSERT(cp->ace + dce >= 0, ("access resulting in negative ace"));
  902         KASSERT(dcr != 0 || dcw != 0 || dce != 0, ("NOP access request"));
  903         KASSERT(gp->access != NULL, ("NULL geom->access"));
  904 
  905         /*
  906          * If our class cares about being spoiled, and we have been, we
  907          * are probably just ahead of the event telling us that.  Fail
  908          * now rather than having to unravel this later.
  909          */
  910         if (cp->geom->spoiled != NULL && (cp->flags & G_CF_SPOILED) &&
  911             (dcr > 0 || dcw > 0 || dce > 0))
  912                 return (ENXIO);
  913 
  914         /*
  915          * A number of GEOM classes either need to perform an I/O on the first
  916          * open or to acquire a different subsystem's lock.  To do that they
  917          * may have to drop the topology lock.
  918          * Other GEOM classes perform special actions when opening a lower rank
  919          * geom for the first time.  As a result, more than one thread may
  920          * end up performing the special actions.
  921          * So, we prevent concurrent "first" opens by marking the consumer with
  922          * special flag.
  923          *
  924          * Note that if the geom's access method never drops the topology lock,
  925          * then we will never see G_GEOM_IN_ACCESS here.
  926          */
  927         while ((gp->flags & G_GEOM_IN_ACCESS) != 0) {
  928                 g_trace(G_T_ACCESS,
  929                     "%s: race on geom %s via provider %s and consumer of %s",
  930                     __func__, gp->name, pp->name, cp->geom->name);
  931                 gp->flags |= G_GEOM_ACCESS_WAIT;
  932                 g_topology_sleep(gp, 0);
  933         }
  934 
  935         /*
  936          * Figure out what counts the provider would have had, if this
  937          * consumer had (r0w0e0) at this time.
  938          */
  939         pw = pp->acw - cp->acw;
  940         pe = pp->ace - cp->ace;
  941 
  942         g_trace(G_T_ACCESS,
  943     "open delta:[r%dw%de%d] old:[r%dw%de%d] provider:[r%dw%de%d] %p(%s)",
  944             dcr, dcw, dce,
  945             cp->acr, cp->acw, cp->ace,
  946             pp->acr, pp->acw, pp->ace,
  947             pp, pp->name);
  948 
  949         /* If foot-shooting is enabled, any open on rank#1 is OK */
  950         if ((g_debugflags & G_F_FOOTSHOOTING) && gp->rank == 1)
  951                 ;
  952         /* If we try exclusive but already write: fail */
  953         else if (dce > 0 && pw > 0)
  954                 return (EPERM);
  955         /* If we try write but already exclusive: fail */
  956         else if (dcw > 0 && pe > 0)
  957                 return (EPERM);
  958         /* If we try to open more but provider is error'ed: fail */
  959         else if ((dcr > 0 || dcw > 0 || dce > 0) && pp->error != 0) {
  960                 printf("%s(%d): provider %s has error %d set\n",
  961                     __func__, __LINE__, pp->name, pp->error);
  962                 return (pp->error);
  963         }
  964 
  965         /* Ok then... */
  966 
  967 #ifdef INVARIANTS
  968         sr = cp->acr;
  969         sw = cp->acw;
  970         se = cp->ace;
  971 #endif
  972         gp->flags |= G_GEOM_IN_ACCESS;
  973         error = gp->access(pp, dcr, dcw, dce);
  974         KASSERT(dcr > 0 || dcw > 0 || dce > 0 || error == 0,
  975             ("Geom provider %s::%s dcr=%d dcw=%d dce=%d error=%d failed "
  976             "closing ->access()", gp->class->name, pp->name, dcr, dcw,
  977             dce, error));
  978 
  979         g_topology_assert();
  980         gp->flags &= ~G_GEOM_IN_ACCESS;
  981         KASSERT(cp->acr == sr && cp->acw == sw && cp->ace == se,
  982             ("Access counts changed during geom->access"));
  983         if ((gp->flags & G_GEOM_ACCESS_WAIT) != 0) {
  984                 gp->flags &= ~G_GEOM_ACCESS_WAIT;
  985                 wakeup(gp);
  986         }
  987 
  988         if (!error) {
  989                 /*
  990                  * If we open first write, spoil any partner consumers.
  991                  * If we close last write and provider is not errored,
  992                  * trigger re-taste.
  993                  */
  994                 if (pp->acw == 0 && dcw != 0)
  995                         g_spoil(pp, cp);
  996                 else if (pp->acw != 0 && pp->acw == -dcw && pp->error == 0 &&
  997                     !(gp->flags & G_GEOM_WITHER))
  998                         g_post_event(g_new_provider_event, pp, M_WAITOK, 
  999                             pp, NULL);
 1000 
 1001                 pp->acr += dcr;
 1002                 pp->acw += dcw;
 1003                 pp->ace += dce;
 1004                 cp->acr += dcr;
 1005                 cp->acw += dcw;
 1006                 cp->ace += dce;
 1007                 if (pp->acr != 0 || pp->acw != 0 || pp->ace != 0)
 1008                         KASSERT(pp->sectorsize > 0,
 1009                             ("Provider %s lacks sectorsize", pp->name));
 1010                 if ((cp->geom->flags & G_GEOM_WITHER) &&
 1011                     cp->acr == 0 && cp->acw == 0 && cp->ace == 0)
 1012                         g_do_wither();
 1013         }
 1014         return (error);
 1015 }
 1016 
 1017 int
 1018 g_handleattr_int(struct bio *bp, const char *attribute, int val)
 1019 {
 1020 
 1021         return (g_handleattr(bp, attribute, &val, sizeof val));
 1022 }
 1023 
 1024 int
 1025 g_handleattr_uint16_t(struct bio *bp, const char *attribute, uint16_t val)
 1026 {
 1027 
 1028         return (g_handleattr(bp, attribute, &val, sizeof val));
 1029 }
 1030 
 1031 int
 1032 g_handleattr_off_t(struct bio *bp, const char *attribute, off_t val)
 1033 {
 1034 
 1035         return (g_handleattr(bp, attribute, &val, sizeof val));
 1036 }
 1037 
 1038 int
 1039 g_handleattr_str(struct bio *bp, const char *attribute, const char *str)
 1040 {
 1041 
 1042         return (g_handleattr(bp, attribute, str, 0));
 1043 }
 1044 
 1045 int
 1046 g_handleattr(struct bio *bp, const char *attribute, const void *val, int len)
 1047 {
 1048         int error = 0;
 1049 
 1050         if (strcmp(bp->bio_attribute, attribute))
 1051                 return (0);
 1052         if (len == 0) {
 1053                 bzero(bp->bio_data, bp->bio_length);
 1054                 if (strlcpy(bp->bio_data, val, bp->bio_length) >=
 1055                     bp->bio_length) {
 1056                         printf("%s: %s %s bio_length %jd strlen %zu -> EFAULT\n",
 1057                             __func__, bp->bio_to->name, attribute,
 1058                             (intmax_t)bp->bio_length, strlen(val));
 1059                         error = EFAULT;
 1060                 }
 1061         } else if (bp->bio_length == len) {
 1062                 bcopy(val, bp->bio_data, len);
 1063         } else {
 1064                 printf("%s: %s %s bio_length %jd len %d -> EFAULT\n", __func__,
 1065                     bp->bio_to->name, attribute, (intmax_t)bp->bio_length, len);
 1066                 error = EFAULT;
 1067         }
 1068         if (error == 0)
 1069                 bp->bio_completed = bp->bio_length;
 1070         g_io_deliver(bp, error);
 1071         return (1);
 1072 }
 1073 
 1074 int
 1075 g_std_access(struct g_provider *pp,
 1076         int dr __unused, int dw __unused, int de __unused)
 1077 {
 1078 
 1079         g_topology_assert();
 1080         G_VALID_PROVIDER(pp);
 1081         return (0);
 1082 }
 1083 
 1084 void
 1085 g_std_done(struct bio *bp)
 1086 {
 1087         struct bio *bp2;
 1088 
 1089         bp2 = bp->bio_parent;
 1090         if (bp2->bio_error == 0)
 1091                 bp2->bio_error = bp->bio_error;
 1092         bp2->bio_completed += bp->bio_completed;
 1093         g_destroy_bio(bp);
 1094         bp2->bio_inbed++;
 1095         if (bp2->bio_children == bp2->bio_inbed)
 1096                 g_io_deliver(bp2, bp2->bio_error);
 1097 }
 1098 
 1099 /* XXX: maybe this is only g_slice_spoiled */
 1100 
 1101 void
 1102 g_std_spoiled(struct g_consumer *cp)
 1103 {
 1104         struct g_geom *gp;
 1105         struct g_provider *pp;
 1106 
 1107         g_topology_assert();
 1108         G_VALID_CONSUMER(cp);
 1109         g_trace(G_T_TOPOLOGY, "g_std_spoiled(%p)", cp);
 1110         cp->flags |= G_CF_ORPHAN;
 1111         g_detach(cp);
 1112         gp = cp->geom;
 1113         LIST_FOREACH(pp, &gp->provider, provider)
 1114                 g_orphan_provider(pp, ENXIO);
 1115         g_destroy_consumer(cp);
 1116         if (LIST_EMPTY(&gp->provider) && LIST_EMPTY(&gp->consumer))
 1117                 g_destroy_geom(gp);
 1118         else
 1119                 gp->flags |= G_GEOM_WITHER;
 1120 }
 1121 
 1122 /*
 1123  * Spoiling happens when a provider is opened for writing, but consumers
 1124  * which are configured by in-band data are attached (slicers for instance).
 1125  * Since the write might potentially change the in-band data, such consumers
 1126  * need to re-evaluate their existence after the writing session closes.
 1127  * We do this by (offering to) tear them down when the open for write happens
 1128  * in return for a re-taste when it closes again.
 1129  * Together with the fact that such consumers grab an 'e' bit whenever they
 1130  * are open, regardless of mode, this ends up DTRT.
 1131  */
 1132 
 1133 static void
 1134 g_spoil_event(void *arg, int flag)
 1135 {
 1136         struct g_provider *pp;
 1137         struct g_consumer *cp, *cp2;
 1138 
 1139         g_topology_assert();
 1140         if (flag == EV_CANCEL)
 1141                 return;
 1142         pp = arg;
 1143         G_VALID_PROVIDER(pp);
 1144         g_trace(G_T_TOPOLOGY, "%s %p(%s:%s:%s)", __func__, pp,
 1145             pp->geom->class->name, pp->geom->name, pp->name);
 1146         for (cp = LIST_FIRST(&pp->consumers); cp != NULL; cp = cp2) {
 1147                 cp2 = LIST_NEXT(cp, consumers);
 1148                 if ((cp->flags & G_CF_SPOILED) == 0)
 1149                         continue;
 1150                 cp->flags &= ~G_CF_SPOILED;
 1151                 if (cp->geom->spoiled == NULL)
 1152                         continue;
 1153                 cp->geom->spoiled(cp);
 1154                 g_topology_assert();
 1155         }
 1156 }
 1157 
 1158 void
 1159 g_spoil(struct g_provider *pp, struct g_consumer *cp)
 1160 {
 1161         struct g_consumer *cp2;
 1162 
 1163         g_topology_assert();
 1164         G_VALID_PROVIDER(pp);
 1165         G_VALID_CONSUMER(cp);
 1166 
 1167         LIST_FOREACH(cp2, &pp->consumers, consumers) {
 1168                 if (cp2 == cp)
 1169                         continue;
 1170 /*
 1171                 KASSERT(cp2->acr == 0, ("spoiling cp->acr = %d", cp2->acr));
 1172                 KASSERT(cp2->acw == 0, ("spoiling cp->acw = %d", cp2->acw));
 1173 */
 1174                 KASSERT(cp2->ace == 0, ("spoiling cp->ace = %d", cp2->ace));
 1175                 cp2->flags |= G_CF_SPOILED;
 1176         }
 1177         g_post_event(g_spoil_event, pp, M_WAITOK, pp, NULL);
 1178 }
 1179 
 1180 static void
 1181 g_media_changed_event(void *arg, int flag)
 1182 {
 1183         struct g_provider *pp;
 1184         int retaste;
 1185 
 1186         g_topology_assert();
 1187         if (flag == EV_CANCEL)
 1188                 return;
 1189         pp = arg;
 1190         G_VALID_PROVIDER(pp);
 1191 
 1192         /*
 1193          * If provider was not open for writing, queue retaste after spoiling.
 1194          * If it was, retaste will happen automatically on close.
 1195          */
 1196         retaste = (pp->acw == 0 && pp->error == 0 &&
 1197             !(pp->geom->flags & G_GEOM_WITHER));
 1198         g_spoil_event(arg, flag);
 1199         if (retaste)
 1200                 g_post_event(g_new_provider_event, pp, M_WAITOK, pp, NULL);
 1201 }
 1202 
 1203 int
 1204 g_media_changed(struct g_provider *pp, int flag)
 1205 {
 1206         struct g_consumer *cp;
 1207 
 1208         LIST_FOREACH(cp, &pp->consumers, consumers)
 1209                 cp->flags |= G_CF_SPOILED;
 1210         return (g_post_event(g_media_changed_event, pp, flag, pp, NULL));
 1211 }
 1212 
 1213 int
 1214 g_media_gone(struct g_provider *pp, int flag)
 1215 {
 1216         struct g_consumer *cp;
 1217 
 1218         LIST_FOREACH(cp, &pp->consumers, consumers)
 1219                 cp->flags |= G_CF_SPOILED;
 1220         return (g_post_event(g_spoil_event, pp, flag, pp, NULL));
 1221 }
 1222 
 1223 int
 1224 g_getattr__(const char *attr, struct g_consumer *cp, void *var, int len)
 1225 {
 1226         int error, i;
 1227 
 1228         i = len;
 1229         error = g_io_getattr(attr, cp, &i, var);
 1230         if (error)
 1231                 return (error);
 1232         if (i != len)
 1233                 return (EINVAL);
 1234         return (0);
 1235 }
 1236 
 1237 static int
 1238 g_get_device_prefix_len(const char *name)
 1239 {
 1240         int len;
 1241 
 1242         if (strncmp(name, "ada", 3) == 0)
 1243                 len = 3;
 1244         else if (strncmp(name, "ad", 2) == 0)
 1245                 len = 2;
 1246         else
 1247                 return (0);
 1248         if (name[len] < '' || name[len] > '9')
 1249                 return (0);
 1250         do {
 1251                 len++;
 1252         } while (name[len] >= '' && name[len] <= '9');
 1253         return (len);
 1254 }
 1255 
 1256 int
 1257 g_compare_names(const char *namea, const char *nameb)
 1258 {
 1259         int deva, devb;
 1260 
 1261         if (strcmp(namea, nameb) == 0)
 1262                 return (1);
 1263         deva = g_get_device_prefix_len(namea);
 1264         if (deva == 0)
 1265                 return (0);
 1266         devb = g_get_device_prefix_len(nameb);
 1267         if (devb == 0)
 1268                 return (0);
 1269         if (strcmp(namea + deva, nameb + devb) == 0)
 1270                 return (1);
 1271         return (0);
 1272 }
 1273 
 1274 void
 1275 g_geom_add_alias(struct g_geom *gp, const char *alias)
 1276 {
 1277         struct g_geom_alias *gap;
 1278 
 1279         gap = (struct g_geom_alias *)g_malloc(
 1280                 sizeof(struct g_geom_alias) + strlen(alias) + 1, M_WAITOK);
 1281         strcpy((char *)(gap + 1), alias);
 1282         gap->ga_alias = (const char *)(gap + 1);
 1283         LIST_INSERT_HEAD(&gp->aliases, gap, ga_next);
 1284 }
 1285 
 1286 #if defined(DIAGNOSTIC) || defined(DDB)
 1287 /*
 1288  * This function walks the mesh and returns a non-zero integer if it
 1289  * finds the argument pointer is an object. The return value indicates
 1290  * which type of object it is believed to be. If topology is not locked,
 1291  * this function is potentially dangerous, but we don't assert that the
 1292  * topology lock is held when called from debugger.
 1293  */
 1294 int
 1295 g_valid_obj(void const *ptr)
 1296 {
 1297         struct g_class *mp;
 1298         struct g_geom *gp;
 1299         struct g_consumer *cp;
 1300         struct g_provider *pp;
 1301 
 1302 #ifdef KDB
 1303         if (kdb_active == 0)
 1304 #endif
 1305                 g_topology_assert();
 1306 
 1307         LIST_FOREACH(mp, &g_classes, class) {
 1308                 if (ptr == mp)
 1309                         return (1);
 1310                 LIST_FOREACH(gp, &mp->geom, geom) {
 1311                         if (ptr == gp)
 1312                                 return (2);
 1313                         LIST_FOREACH(cp, &gp->consumer, consumer)
 1314                                 if (ptr == cp)
 1315                                         return (3);
 1316                         LIST_FOREACH(pp, &gp->provider, provider)
 1317                                 if (ptr == pp)
 1318                                         return (4);
 1319                 }
 1320         }
 1321         return(0);
 1322 }
 1323 #endif
 1324 
 1325 #ifdef DDB
 1326 
 1327 #define gprintf(...)    do {                                            \
 1328         db_printf("%*s", indent, "");                                   \
 1329         db_printf(__VA_ARGS__);                                         \
 1330 } while (0)
 1331 #define gprintln(...)   do {                                            \
 1332         gprintf(__VA_ARGS__);                                           \
 1333         db_printf("\n");                                                \
 1334 } while (0)
 1335 
 1336 #define ADDFLAG(obj, flag, sflag)       do {                            \
 1337         if ((obj)->flags & (flag)) {                                    \
 1338                 if (comma)                                              \
 1339                         strlcat(str, ",", size);                        \
 1340                 strlcat(str, (sflag), size);                            \
 1341                 comma = 1;                                              \
 1342         }                                                               \
 1343 } while (0)
 1344 
 1345 static char *
 1346 provider_flags_to_string(struct g_provider *pp, char *str, size_t size)
 1347 {
 1348         int comma = 0;
 1349 
 1350         bzero(str, size);
 1351         if (pp->flags == 0) {
 1352                 strlcpy(str, "NONE", size);
 1353                 return (str);
 1354         }
 1355         ADDFLAG(pp, G_PF_WITHER, "G_PF_WITHER");
 1356         ADDFLAG(pp, G_PF_ORPHAN, "G_PF_ORPHAN");
 1357         return (str);
 1358 }
 1359 
 1360 static char *
 1361 geom_flags_to_string(struct g_geom *gp, char *str, size_t size)
 1362 {
 1363         int comma = 0;
 1364 
 1365         bzero(str, size);
 1366         if (gp->flags == 0) {
 1367                 strlcpy(str, "NONE", size);
 1368                 return (str);
 1369         }
 1370         ADDFLAG(gp, G_GEOM_WITHER, "G_GEOM_WITHER");
 1371         return (str);
 1372 }
 1373 static void
 1374 db_show_geom_consumer(int indent, struct g_consumer *cp)
 1375 {
 1376 
 1377         if (indent == 0) {
 1378                 gprintln("consumer: %p", cp);
 1379                 gprintln("  class:    %s (%p)", cp->geom->class->name,
 1380                     cp->geom->class);
 1381                 gprintln("  geom:     %s (%p)", cp->geom->name, cp->geom);
 1382                 if (cp->provider == NULL)
 1383                         gprintln("  provider: none");
 1384                 else {
 1385                         gprintln("  provider: %s (%p)", cp->provider->name,
 1386                             cp->provider);
 1387                 }
 1388                 gprintln("  access:   r%dw%de%d", cp->acr, cp->acw, cp->ace);
 1389                 gprintln("  flags:    0x%04x", cp->flags);
 1390                 gprintln("  nstart:   %u", cp->nstart);
 1391                 gprintln("  nend:     %u", cp->nend);
 1392         } else {
 1393                 gprintf("consumer: %p (%s), access=r%dw%de%d", cp,
 1394                     cp->provider != NULL ? cp->provider->name : "none",
 1395                     cp->acr, cp->acw, cp->ace);
 1396                 if (cp->flags)
 1397                         db_printf(", flags=0x%04x", cp->flags);
 1398                 db_printf("\n");
 1399         }
 1400 }
 1401 
 1402 static void
 1403 db_show_geom_provider(int indent, struct g_provider *pp)
 1404 {
 1405         struct g_consumer *cp;
 1406         char flags[64];
 1407 
 1408         if (indent == 0) {
 1409                 gprintln("provider: %s (%p)", pp->name, pp);
 1410                 gprintln("  class:        %s (%p)", pp->geom->class->name,
 1411                     pp->geom->class);
 1412                 gprintln("  geom:         %s (%p)", pp->geom->name, pp->geom);
 1413                 gprintln("  mediasize:    %jd", (intmax_t)pp->mediasize);
 1414                 gprintln("  sectorsize:   %u", pp->sectorsize);
 1415                 gprintln("  stripesize:   %u", pp->stripesize);
 1416                 gprintln("  stripeoffset: %u", pp->stripeoffset);
 1417                 gprintln("  access:       r%dw%de%d", pp->acr, pp->acw,
 1418                     pp->ace);
 1419                 gprintln("  flags:        %s (0x%04x)",
 1420                     provider_flags_to_string(pp, flags, sizeof(flags)),
 1421                     pp->flags);
 1422                 gprintln("  error:        %d", pp->error);
 1423                 gprintln("  nstart:       %u", pp->nstart);
 1424                 gprintln("  nend:         %u", pp->nend);
 1425                 if (LIST_EMPTY(&pp->consumers))
 1426                         gprintln("  consumers:    none");
 1427         } else {
 1428                 gprintf("provider: %s (%p), access=r%dw%de%d",
 1429                     pp->name, pp, pp->acr, pp->acw, pp->ace);
 1430                 if (pp->flags != 0) {
 1431                         db_printf(", flags=%s (0x%04x)",
 1432                             provider_flags_to_string(pp, flags, sizeof(flags)),
 1433                             pp->flags);
 1434                 }
 1435                 db_printf("\n");
 1436         }
 1437         if (!LIST_EMPTY(&pp->consumers)) {
 1438                 LIST_FOREACH(cp, &pp->consumers, consumers) {
 1439                         db_show_geom_consumer(indent + 2, cp);
 1440                         if (db_pager_quit)
 1441                                 break;
 1442                 }
 1443         }
 1444 }
 1445 
 1446 static void
 1447 db_show_geom_geom(int indent, struct g_geom *gp)
 1448 {
 1449         struct g_provider *pp;
 1450         struct g_consumer *cp;
 1451         char flags[64];
 1452 
 1453         if (indent == 0) {
 1454                 gprintln("geom: %s (%p)", gp->name, gp);
 1455                 gprintln("  class:     %s (%p)", gp->class->name, gp->class);
 1456                 gprintln("  flags:     %s (0x%04x)",
 1457                     geom_flags_to_string(gp, flags, sizeof(flags)), gp->flags);
 1458                 gprintln("  rank:      %d", gp->rank);
 1459                 if (LIST_EMPTY(&gp->provider))
 1460                         gprintln("  providers: none");
 1461                 if (LIST_EMPTY(&gp->consumer))
 1462                         gprintln("  consumers: none");
 1463         } else {
 1464                 gprintf("geom: %s (%p), rank=%d", gp->name, gp, gp->rank);
 1465                 if (gp->flags != 0) {
 1466                         db_printf(", flags=%s (0x%04x)",
 1467                             geom_flags_to_string(gp, flags, sizeof(flags)),
 1468                             gp->flags);
 1469                 }
 1470                 db_printf("\n");
 1471         }
 1472         if (!LIST_EMPTY(&gp->provider)) {
 1473                 LIST_FOREACH(pp, &gp->provider, provider) {
 1474                         db_show_geom_provider(indent + 2, pp);
 1475                         if (db_pager_quit)
 1476                                 break;
 1477                 }
 1478         }
 1479         if (!LIST_EMPTY(&gp->consumer)) {
 1480                 LIST_FOREACH(cp, &gp->consumer, consumer) {
 1481                         db_show_geom_consumer(indent + 2, cp);
 1482                         if (db_pager_quit)
 1483                                 break;
 1484                 }
 1485         }
 1486 }
 1487 
 1488 static void
 1489 db_show_geom_class(struct g_class *mp)
 1490 {
 1491         struct g_geom *gp;
 1492 
 1493         db_printf("class: %s (%p)\n", mp->name, mp);
 1494         LIST_FOREACH(gp, &mp->geom, geom) {
 1495                 db_show_geom_geom(2, gp);
 1496                 if (db_pager_quit)
 1497                         break;
 1498         }
 1499 }
 1500 
 1501 /*
 1502  * Print the GEOM topology or the given object.
 1503  */
 1504 DB_SHOW_COMMAND(geom, db_show_geom)
 1505 {
 1506         struct g_class *mp;
 1507 
 1508         if (!have_addr) {
 1509                 /* No address given, print the entire topology. */
 1510                 LIST_FOREACH(mp, &g_classes, class) {
 1511                         db_show_geom_class(mp);
 1512                         db_printf("\n");
 1513                         if (db_pager_quit)
 1514                                 break;
 1515                 }
 1516         } else {
 1517                 switch (g_valid_obj((void *)addr)) {
 1518                 case 1:
 1519                         db_show_geom_class((struct g_class *)addr);
 1520                         break;
 1521                 case 2:
 1522                         db_show_geom_geom(0, (struct g_geom *)addr);
 1523                         break;
 1524                 case 3:
 1525                         db_show_geom_consumer(0, (struct g_consumer *)addr);
 1526                         break;
 1527                 case 4:
 1528                         db_show_geom_provider(0, (struct g_provider *)addr);
 1529                         break;
 1530                 default:
 1531                         db_printf("Not a GEOM object.\n");
 1532                         break;
 1533                 }
 1534         }
 1535 }
 1536 
 1537 static void
 1538 db_print_bio_cmd(struct bio *bp)
 1539 {
 1540         db_printf("  cmd: ");
 1541         switch (bp->bio_cmd) {
 1542         case BIO_READ: db_printf("BIO_READ"); break;
 1543         case BIO_WRITE: db_printf("BIO_WRITE"); break;
 1544         case BIO_DELETE: db_printf("BIO_DELETE"); break;
 1545         case BIO_GETATTR: db_printf("BIO_GETATTR"); break;
 1546         case BIO_FLUSH: db_printf("BIO_FLUSH"); break;
 1547         case BIO_CMD0: db_printf("BIO_CMD0"); break;
 1548         case BIO_CMD1: db_printf("BIO_CMD1"); break;
 1549         case BIO_CMD2: db_printf("BIO_CMD2"); break;
 1550         case BIO_ZONE: db_printf("BIO_ZONE"); break;
 1551         default: db_printf("UNKNOWN"); break;
 1552         }
 1553         db_printf("\n");
 1554 }
 1555 
 1556 static void
 1557 db_print_bio_flags(struct bio *bp)
 1558 {
 1559         int comma;
 1560 
 1561         comma = 0;
 1562         db_printf("  flags: ");
 1563         if (bp->bio_flags & BIO_ERROR) {
 1564                 db_printf("BIO_ERROR");
 1565                 comma = 1;
 1566         }
 1567         if (bp->bio_flags & BIO_DONE) {
 1568                 db_printf("%sBIO_DONE", (comma ? ", " : ""));
 1569                 comma = 1;
 1570         }
 1571         if (bp->bio_flags & BIO_ONQUEUE)
 1572                 db_printf("%sBIO_ONQUEUE", (comma ? ", " : ""));
 1573         db_printf("\n");
 1574 }
 1575 
 1576 /*
 1577  * Print useful information in a BIO
 1578  */
 1579 DB_SHOW_COMMAND(bio, db_show_bio)
 1580 {
 1581         struct bio *bp;
 1582 
 1583         if (have_addr) {
 1584                 bp = (struct bio *)addr;
 1585                 db_printf("BIO %p\n", bp);
 1586                 db_print_bio_cmd(bp);
 1587                 db_print_bio_flags(bp);
 1588                 db_printf("  cflags: 0x%hx\n", bp->bio_cflags);
 1589                 db_printf("  pflags: 0x%hx\n", bp->bio_pflags);
 1590                 db_printf("  offset: %jd\n", (intmax_t)bp->bio_offset);
 1591                 db_printf("  length: %jd\n", (intmax_t)bp->bio_length);
 1592                 db_printf("  bcount: %ld\n", bp->bio_bcount);
 1593                 db_printf("  resid: %ld\n", bp->bio_resid);
 1594                 db_printf("  completed: %jd\n", (intmax_t)bp->bio_completed);
 1595                 db_printf("  children: %u\n", bp->bio_children);
 1596                 db_printf("  inbed: %u\n", bp->bio_inbed);
 1597                 db_printf("  error: %d\n", bp->bio_error);
 1598                 db_printf("  parent: %p\n", bp->bio_parent);
 1599                 db_printf("  driver1: %p\n", bp->bio_driver1);
 1600                 db_printf("  driver2: %p\n", bp->bio_driver2);
 1601                 db_printf("  caller1: %p\n", bp->bio_caller1);
 1602                 db_printf("  caller2: %p\n", bp->bio_caller2);
 1603                 db_printf("  bio_from: %p\n", bp->bio_from);
 1604                 db_printf("  bio_to: %p\n", bp->bio_to);
 1605 
 1606 #if defined(BUF_TRACKING) || defined(FULL_BUF_TRACKING)
 1607                 db_printf("  bio_track_bp: %p\n", bp->bio_track_bp);
 1608 #endif
 1609         }
 1610 }
 1611 
 1612 #undef  gprintf
 1613 #undef  gprintln
 1614 #undef  ADDFLAG
 1615 
 1616 #endif  /* DDB */

Cache object: 91f9f3990362a1103ac449e305f92ae7


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.