root/dev/raidframe/rf_openbsdkintf.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. rf_probe
  2. rf_attach
  3. rf_detach
  4. rf_activate
  5. raidattach
  6. rf_buildroothack
  7. rf_shutdown_hook
  8. raidsize
  9. raiddump
  10. raidopen
  11. raidclose
  12. raidstrategy
  13. raidread
  14. raidwrite
  15. raidioctl
  16. raidinit
  17. rf_GetSpareTableFromDaemon
  18. raidstart
  19. rf_DispatchKernelIO
  20. rf_KernelWakeupFunc
  21. rf_InitBP
  22. raidgetdefaultlabel
  23. raidgetdisklabel
  24. raidlookup
  25. raidlock
  26. raidunlock
  27. raidmarkclean
  28. raidmarkdirty
  29. raidread_component_label
  30. raidwrite_component_label
  31. rf_markalldirty
  32. rf_update_component_labels
  33. rf_close_component
  34. rf_UnconfigureVnodes
  35. rf_ReconThread
  36. rf_RewriteParityThread
  37. rf_CopybackThread
  38. rf_ReconstructInPlaceThread
  39. rf_find_raid_components
  40. rf_reasonable_label
  41. rf_print_component_label
  42. rf_create_auto_sets
  43. rf_does_it_fit
  44. rf_have_enough_components
  45. rf_create_configuration
  46. rf_set_autoconfig
  47. rf_set_rootpartition
  48. rf_release_all_vps
  49. rf_cleanup_config_set
  50. raid_init_component_label
  51. rf_auto_config_set
  52. rf_disk_unbusy

    1 /* $OpenBSD: rf_openbsdkintf.c,v 1.42 2007/06/23 03:11:34 krw Exp $     */
    2 /* $NetBSD: rf_netbsdkintf.c,v 1.109 2001/07/27 03:30:07 oster Exp $    */
    3 
    4 /*-
    5  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
    6  * All rights reserved.
    7  *
    8  * This code is derived from software contributed to The NetBSD Foundation
    9  * by Greg Oster; Jason R. Thorpe.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  * 3. All advertising materials mentioning features or use of this software
   20  *    must display the following acknowledgement:
   21  *        This product includes software developed by the NetBSD
   22  *        Foundation, Inc. and its contributors.
   23  * 4. Neither the name of The NetBSD Foundation nor the names of its
   24  *    contributors may be used to endorse or promote products derived
   25  *    from this software without specific prior written permission.
   26  *
   27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   37  * POSSIBILITY OF SUCH DAMAGE.
   38  */
   39 
   40 /*
   41  * Copyright (c) 1988 University of Utah.
   42  * Copyright (c) 1990, 1993
   43  *      The Regents of the University of California.  All rights reserved.
   44  *
   45  * This code is derived from software contributed to Berkeley by
   46  * the Systems Programming Group of the University of Utah Computer
   47  * Science Department.
   48  *
   49  * Redistribution and use in source and binary forms, with or without
   50  * modification, are permitted provided that the following conditions
   51  * are met:
   52  * 1. Redistributions of source code must retain the above copyright
   53  *    notice, this list of conditions and the following disclaimer.
   54  * 2. Redistributions in binary form must reproduce the above copyright
   55  *    notice, this list of conditions and the following disclaimer in the
   56  *    documentation and/or other materials provided with the distribution.
   57  * 3. Neither the name of the University nor the names of its contributors
   58  *    may be used to endorse or promote products derived from this software
   59  *    without specific prior written permission.
   60  *
   61  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   62  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   63  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   64  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   65  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   66  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   67  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   68  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   69  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   70  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   71  * SUCH DAMAGE.
   72  *
   73  * from: Utah $Hdr: cd.c 1.6 90/11/28$
   74  *
   75  *      @(#)cd.c        8.2 (Berkeley) 11/16/93
   76  */
   77 
   78 /*
   79  * Copyright (c) 1995 Carnegie-Mellon University.
   80  * All rights reserved.
   81  *
   82  * Authors: Mark Holland, Jim Zelenka
   83  *
   84  * Permission to use, copy, modify and distribute this software and
   85  * its documentation is hereby granted, provided that both the copyright
   86  * notice and this permission notice appear in all copies of the
   87  * software, derivative works or modified versions, and any portions
   88  * thereof, and that both notices appear in supporting documentation.
   89  *
   90  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   91  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
   92  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   93  *
   94  * Carnegie Mellon requests users of this software to return to
   95  *
   96  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   97  *  School of Computer Science
   98  *  Carnegie Mellon University
   99  *  Pittsburgh PA 15213-3890
  100  *
  101  * any improvements or extensions that they make and grant Carnegie the
  102  * rights to redistribute these changes.
  103  */
  104 
  105 /*****************************************************************************
  106  *
  107  * rf_kintf.c -- The kernel interface routines for RAIDframe.
  108  *
  109  *****************************************************************************/
  110 
  111 #include <sys/errno.h>
  112 
  113 #include <sys/param.h>
  114 #include <sys/pool.h>
  115 #include <sys/malloc.h>
  116 #include <sys/queue.h>
  117 #include <sys/disk.h>
  118 #include <sys/device.h>
  119 #include <sys/stat.h>
  120 #include <sys/ioctl.h>
  121 #include <sys/fcntl.h>
  122 #include <sys/systm.h>
  123 #include <sys/namei.h>
  124 #include <sys/conf.h>
  125 #include <sys/lock.h>
  126 #include <sys/buf.h>
  127 #include <sys/user.h>
  128 #include <sys/reboot.h>
  129 
  130 #include "raid.h"
  131 #include "rf_raid.h"
  132 #include "rf_raidframe.h"
  133 #include "rf_copyback.h"
  134 #include "rf_dag.h"
  135 #include "rf_dagflags.h"
  136 #include "rf_desc.h"
  137 #include "rf_diskqueue.h"
  138 #include "rf_engine.h"
  139 #include "rf_acctrace.h"
  140 #include "rf_etimer.h"
  141 #include "rf_general.h"
  142 #include "rf_debugMem.h"
  143 #include "rf_kintf.h"
  144 #include "rf_options.h"
  145 #include "rf_driver.h"
  146 #include "rf_parityscan.h"
  147 #include "rf_debugprint.h"
  148 #include "rf_threadstuff.h"
  149 #include "rf_configure.h"
  150 
  151 int     rf_kdebug_level = 0;
  152 
  153 #ifdef  RAIDDEBUG
  154 #define db1_printf(a) do { if (rf_kdebug_level > 0) printf a; } while(0)
  155 #else   /* RAIDDEBUG */
  156 #define db1_printf(a) (void)0
  157 #endif  /* ! RAIDDEBUG */
  158 
  159 static RF_Raid_t **raidPtrs;    /* Global raid device descriptors. */
  160 
  161 RF_DECLARE_STATIC_MUTEX(rf_sparet_wait_mutex);
  162 
  163 /* Requests to install a spare table. */
  164 static RF_SparetWait_t *rf_sparet_wait_queue;
  165 
  166 /* Responses from installation process. */
  167 static RF_SparetWait_t *rf_sparet_resp_queue;
  168 
  169 /* Prototypes. */
  170 void rf_KernelWakeupFunc(struct buf *);
  171 void rf_InitBP(struct buf *, struct vnode *, unsigned, dev_t, RF_SectorNum_t,
  172     RF_SectorCount_t, caddr_t, void (*)(struct buf *), void *, int,
  173     struct proc *);
  174 void raidinit(RF_Raid_t *);
  175 
  176 void raidattach(int);
  177 daddr64_t raidsize(dev_t);
  178 int  raidopen(dev_t, int, int, struct proc *);
  179 int  raidclose(dev_t, int, int, struct proc *);
  180 int  raidioctl(dev_t, u_long, caddr_t, int, struct proc *);
  181 int  raidwrite(dev_t, struct uio *, int);
  182 int  raidread(dev_t, struct uio *, int);
  183 void raidstrategy(struct buf *);
  184 int  raiddump(dev_t, daddr64_t, caddr_t, size_t);
  185 
  186 /*
  187  * Pilfered from ccd.c
  188  */
  189 struct raidbuf {
  190         struct buf       rf_buf;        /* New I/O buf.  MUST BE FIRST!!! */
  191         struct buf      *rf_obp;        /* Ptr. to original I/O buf. */
  192         int              rf_flags;      /* Miscellaneous flags. */
  193         RF_DiskQueueData_t *req;        /* The request that this was part of. */
  194 };
  195 
  196 #define RAIDGETBUF(rs)          pool_get(&(rs)->sc_cbufpool, PR_NOWAIT)
  197 #define RAIDPUTBUF(rs, cbp)     pool_put(&(rs)->sc_cbufpool, cbp)
  198 
  199 /*
  200  * Some port (like i386) use a swapgeneric that wants to snoop around
  201  * in this raid_cd structure.  It is preserved (for now) to remain
  202  * compatible with such practice.
  203  */
  204 struct cfdriver raid_cd = {
  205         NULL, "raid", DV_DISK
  206 };
  207 
  208 /*
  209  * XXX Not sure if the following should be replacing the raidPtrs above,
  210  * or if it should be used in conjunction with that...
  211  */
  212 struct raid_softc {
  213         int             sc_flags;               /* Flags. */
  214         int             sc_cflags;              /* Configuration flags. */
  215         size_t          sc_size;                /* Size of the raid device. */
  216         char            sc_xname[20];           /* XXX external name. */
  217         struct disk     sc_dkdev;               /* Generic disk device info. */
  218         struct pool     sc_cbufpool;            /* Component buffer pool. */
  219         struct buf      sc_q;                   /* Used for the device queue. */
  220 };
  221 
  222 /* sc_flags */
  223 #define RAIDF_INITED    0x01    /* Unit has been initialized. */
  224 #define RAIDF_WLABEL    0x02    /* Label area is writable. */
  225 #define RAIDF_LABELLING 0x04    /* Unit is currently being labelled. */
  226 #define RAIDF_WANTED    0x40    /* Someone is waiting to obtain a lock. */
  227 #define RAIDF_LOCKED    0x80    /* Unit is locked. */
  228 
  229 int numraid = 0;
  230 
  231 /*
  232  * Here we define a cfattach structure for inserting any new raid device
  233  * into the device tree.  This is needed by some archs that look for
  234  * bootable devices in there.
  235  */
  236 int  rf_probe(struct device *, void *, void *);
  237 void rf_attach(struct device *, struct device *, void *);
  238 int  rf_detach(struct device *, int);
  239 int  rf_activate(struct device *, enum devact);
  240 
  241 struct cfattach raid_ca = {
  242         sizeof(struct raid_softc), rf_probe, rf_attach,
  243         rf_detach, rf_activate
  244 };
  245 
  246 /*
  247  * Allow RAIDOUTSTANDING number of simultaneous IO's to this RAID device.
  248  * Be aware that large numbers can allow the driver to consume a lot of
  249  * kernel memory, especially on writes, and in degraded mode reads.
  250  *
  251  * For example: with a stripe width of 64 blocks (32k) and 5 disks,
  252  * a single 64K write will typically require 64K for the old data,
  253  * 64K for the old parity, and 64K for the new parity, for a total
  254  * of 192K (if the parity buffer is not re-used immediately).
  255  * Even it if is used immedately, that's still 128K, which when multiplied
  256  * by say 10 requests, is 1280K, *on top* of the 640K of incoming data.
  257  *
  258  * Now in degraded mode, for example, a 64K read on the above setup may
  259  * require data reconstruction, which will require *all* of the 4 remaining
  260  * disks to participate -- 4 * 32K/disk == 128K again.
  261  */
  262 
  263 #ifndef RAIDOUTSTANDING
  264 #define RAIDOUTSTANDING         6
  265 #endif
  266 
  267 /* Declared here, and made public, for the benefit of KVM stuff... */
  268 struct raid_softc  *raid_softc;
  269 struct raid_softc **raid_scPtrs;
  270 
  271 void rf_shutdown_hook(RF_ThreadArg_t);
  272 void raidgetdefaultlabel(RF_Raid_t *, struct raid_softc *, struct disklabel *);
  273 void raidgetdisklabel(dev_t, struct disklabel *, int);
  274 
  275 int  raidlock(struct raid_softc *);
  276 void raidunlock(struct raid_softc *);
  277 
  278 void rf_markalldirty(RF_Raid_t *);
  279 
  280 struct device *raidrootdev;
  281 
  282 int  findblkmajor(struct device *dv);
  283 char *findblkname(int);
  284 
  285 void rf_ReconThread(struct rf_recon_req *);
  286 /* XXX what I want is: */
  287 /*void rf_ReconThread(RF_Raid_t *raidPtr);*/
  288 void rf_RewriteParityThread(RF_Raid_t *raidPtr);
  289 void rf_CopybackThread(RF_Raid_t *raidPtr);
  290 void rf_ReconstructInPlaceThread(struct rf_recon_req *);
  291 #ifdef  RAID_AUTOCONFIG
  292 void rf_buildroothack(void *);
  293 int  rf_reasonable_label(RF_ComponentLabel_t *);
  294 #endif  /* RAID_AUTOCONFIG */
  295 
  296 RF_AutoConfig_t *rf_find_raid_components(void);
  297 RF_ConfigSet_t *rf_create_auto_sets(RF_AutoConfig_t *);
  298 int  rf_does_it_fit(RF_ConfigSet_t *,RF_AutoConfig_t *);
  299 void rf_create_configuration(RF_AutoConfig_t *,RF_Config_t *,
  300                                   RF_Raid_t *);
  301 int  rf_set_autoconfig(RF_Raid_t *, int);
  302 int  rf_set_rootpartition(RF_Raid_t *, int);
  303 void rf_release_all_vps(RF_ConfigSet_t *);
  304 void rf_cleanup_config_set(RF_ConfigSet_t *);
  305 int  rf_have_enough_components(RF_ConfigSet_t *);
  306 int  rf_auto_config_set(RF_ConfigSet_t *, int *);
  307 
  308 #ifdef  RAID_AUTOCONFIG
  309 static int raidautoconfig = 0;  /*
  310                                  * Debugging, mostly.  Set to 0 to not
  311                                  * allow autoconfig to take place.
  312                                  * Note that this is overridden by having
  313                                  * RAID_AUTOCONFIG as an option in the
  314                                  * kernel config file.
  315                                  */
  316 #endif  /* RAID_AUTOCONFIG */
  317 
  318 int
  319 rf_probe(struct device *parent, void *match_, void *aux)
  320 {
  321         return 0;
  322 }
  323 
  324 void
  325 rf_attach(struct device *parent, struct device *self, void *aux)
  326 {
  327         /*struct raid_softc *raid = (void *)self;*/
  328 }
  329 
  330 int
  331 rf_detach(struct device *self, int flags)
  332 {
  333         return 0;
  334 }
  335 
  336 int
  337 rf_activate(struct device *self, enum devact act)
  338 {
  339         return 0;
  340 }
  341 
  342 void
  343 raidattach(int num)
  344 {
  345         int raidID;
  346         int i, rc;
  347 #ifdef  RAID_AUTOCONFIG
  348         RF_AutoConfig_t *ac_list;       /* Autoconfig list. */
  349         RF_ConfigSet_t *config_sets;
  350 #endif  /* RAID_AUTOCONFIG */
  351 
  352         db1_printf(("raidattach: Asked for %d units\n", num));
  353 
  354         if (num <= 0) {
  355 #ifdef  DIAGNOSTIC
  356                 panic("raidattach: count <= 0");
  357 #endif  /* DIAGNOSTIC */
  358                 return;
  359         }
  360 
  361         /* This is where all the initialization stuff gets done. */
  362 
  363         numraid = num;
  364 
  365         /* Make some space for requested number of units... */
  366         RF_Calloc(raidPtrs, num, sizeof(RF_Raid_t *), (RF_Raid_t **));
  367         if (raidPtrs == NULL) {
  368                 panic("raidPtrs is NULL!!");
  369         }
  370 
  371         rc = rf_mutex_init(&rf_sparet_wait_mutex);
  372         if (rc) {
  373                 RF_PANIC();
  374         }
  375 
  376         rf_sparet_wait_queue = rf_sparet_resp_queue = NULL;
  377 
  378         for (i = 0; i < num; i++)
  379                 raidPtrs[i] = NULL;
  380         rc = rf_BootRaidframe();
  381         if (rc == 0)
  382                 printf("Kernelized RAIDframe activated\n");
  383         else
  384                 panic("Serious error booting RAID !!!");
  385         
  386         /*
  387          * Put together some datastructures like the CCD device does...
  388          * This lets us lock the device and what-not when it gets opened.
  389          */
  390 
  391         raid_softc = (struct raid_softc *)
  392                 malloc(num * sizeof(struct raid_softc), M_RAIDFRAME, M_NOWAIT);
  393         if (raid_softc == NULL) {
  394                 printf("WARNING: no memory for RAIDframe driver\n");
  395                 return;
  396         }
  397 
  398         bzero(raid_softc, num * sizeof (struct raid_softc));
  399 
  400         raid_scPtrs = (struct raid_softc **)
  401                 malloc(num * sizeof(struct raid_softc *), M_RAIDFRAME,
  402                     M_NOWAIT);
  403         if (raid_scPtrs == NULL) {
  404                 printf("WARNING: no memory for RAIDframe driver\n");
  405                 return;
  406         }
  407 
  408         bzero(raid_scPtrs, num * sizeof (struct raid_softc *));
  409 
  410         raidrootdev = (struct device *)malloc(num * sizeof(struct device),
  411             M_RAIDFRAME, M_NOWAIT);
  412         if (raidrootdev == NULL) {
  413                 panic("No memory for RAIDframe driver!!?!?!");
  414         }
  415 
  416         for (raidID = 0; raidID < num; raidID++) {
  417 #if 0
  418                 SIMPLEQ_INIT(&raid_softc[raidID].sc_q);
  419 #endif
  420 
  421                 raidrootdev[raidID].dv_class  = DV_DISK;
  422                 raidrootdev[raidID].dv_cfdata = NULL;
  423                 raidrootdev[raidID].dv_unit   = raidID;
  424                 raidrootdev[raidID].dv_parent = NULL;
  425                 raidrootdev[raidID].dv_flags  = 0;
  426                 snprintf(raidrootdev[raidID].dv_xname,
  427                     sizeof raidrootdev[raidID].dv_xname,"raid%d",raidID);
  428 
  429                 RF_Calloc(raidPtrs[raidID], 1, sizeof (RF_Raid_t),
  430                     (RF_Raid_t *));
  431                 if (raidPtrs[raidID] == NULL) {
  432                         printf("WARNING: raidPtrs[%d] is NULL\n", raidID);
  433                         numraid = raidID;
  434                         return;
  435                 }
  436         }
  437 
  438         raid_cd.cd_devs = (void **) raid_scPtrs;
  439         raid_cd.cd_ndevs = num;
  440 
  441 #ifdef  RAID_AUTOCONFIG
  442         raidautoconfig = 1;
  443 
  444         if (raidautoconfig) {
  445                 /* 1. Locate all RAID components on the system. */
  446 
  447 #ifdef  RAIDDEBUG
  448                 printf("Searching for raid components...\n");
  449 #endif  /* RAIDDEBUG */
  450                 ac_list = rf_find_raid_components();
  451 
  452                 /* 2. Sort them into their respective sets. */
  453 
  454                 config_sets = rf_create_auto_sets(ac_list);
  455 
  456                 /*
  457                  * 3. Evaluate each set and configure the valid ones
  458                  * This gets done in rf_buildroothack().
  459                  */
  460 
  461                 /*
  462                  * Schedule the creation of the thread to do the
  463                  * "/ on RAID" stuff.
  464                  */
  465 
  466                 rf_buildroothack(config_sets);
  467 
  468         }
  469 #endif  /* RAID_AUTOCONFIG */
  470 
  471 }
  472 
  473 #ifdef  RAID_AUTOCONFIG
  474 void
  475 rf_buildroothack(void *arg)
  476 {
  477         RF_ConfigSet_t *config_sets = arg;
  478         RF_ConfigSet_t *cset;
  479         RF_ConfigSet_t *next_cset;
  480         int retcode;
  481         int raidID;
  482         int rootID;
  483         int num_root;
  484         int majdev;
  485 
  486         rootID = 0;
  487         num_root = 0;
  488         cset = config_sets;
  489         while(cset != NULL ) {
  490                 next_cset = cset->next;
  491                 if (rf_have_enough_components(cset) &&
  492                     cset->ac->clabel->autoconfigure==1) {
  493                         retcode = rf_auto_config_set(cset,&raidID);
  494                         if (!retcode) {
  495                                 if (cset->rootable) {
  496                                         rootID = raidID;
  497 #ifdef  RAIDDEBUG
  498                                         printf("eligible root device %d:"
  499                                             " raid%d\n", num_root, rootID);
  500 #endif  /* RAIDDEBUG */
  501                                         num_root++;
  502                                 }
  503                         } else {
  504                                 /* The autoconfig didn't work :( */
  505 #ifdef  RAIDDEBUG
  506                                 printf("Autoconfig failed with code %d for"
  507                                     " raid%d\n", retcode, raidID);
  508 #endif  /* RAIDDEBUG */
  509                                 rf_release_all_vps(cset);
  510                         }
  511                 } else {
  512                         /*
  513                          * We're not autoconfiguring this set...
  514                          * Release the associated resources.
  515                          */
  516                         rf_release_all_vps(cset);
  517                 }
  518                 /* Cleanup. */
  519                 rf_cleanup_config_set(cset);
  520                 cset = next_cset;
  521         }
  522         if (boothowto & RB_ASKNAME) {
  523                 /* We don't auto-config... */
  524         } else {
  525                 /* They didn't ask, and we found something bootable... */
  526 
  527                 if (num_root == 1) {
  528                         majdev = findblkmajor(&raidrootdev[rootID]);
  529                         if (majdev < 0)
  530                                 boothowto |= RB_ASKNAME;
  531                         else {
  532                                 rootdev = MAKEDISKDEV(majdev,rootID,0);
  533                                 boothowto |= RB_DFLTROOT;
  534                         }
  535                 } else if (num_root > 1) {
  536                         /* We can't guess... Require the user to answer... */
  537                         boothowto |= RB_ASKNAME;
  538                 }
  539         }
  540 }
  541 #endif  /* RAID_AUTOCONFIG */
  542 
  543 void
  544 rf_shutdown_hook(RF_ThreadArg_t arg)
  545 {
  546         int unit;
  547         struct raid_softc *rs;
  548         RF_Raid_t *raidPtr;
  549 
  550         /* Don't do it if we are not "safe". */
  551         if (boothowto & RB_NOSYNC)
  552                 return;
  553 
  554         raidPtr = (RF_Raid_t *) arg;
  555         unit = raidPtr->raidid;
  556         rs = &raid_softc[unit];
  557 
  558         /* Shutdown the system. */
  559 
  560         if (rf_hook_cookies != NULL && rf_hook_cookies[unit] != NULL)
  561                 rf_hook_cookies[unit] = NULL;
  562 
  563         rf_Shutdown(raidPtr);
  564 
  565         pool_destroy(&rs->sc_cbufpool);
  566 
  567         /* It's no longer initialized... */
  568         rs->sc_flags &= ~RAIDF_INITED;
  569 
  570         /* config_detach the device. */
  571         config_detach(device_lookup(&raid_cd, unit), 0);
  572 
  573         /* Detach the disk. */
  574         disk_detach(&rs->sc_dkdev);
  575 }
  576 
  577 daddr64_t
  578 raidsize(dev_t dev)
  579 {
  580         struct raid_softc *rs;
  581         struct disklabel *lp;
  582         int part, unit, omask, size;
  583 
  584         unit = DISKUNIT(dev);
  585         if (unit >= numraid)
  586                 return (-1);
  587         rs = &raid_softc[unit];
  588 
  589         if ((rs->sc_flags & RAIDF_INITED) == 0)
  590                 return (-1);
  591 
  592         part = DISKPART(dev);
  593         omask = rs->sc_dkdev.dk_openmask & (1 << part);
  594         lp = rs->sc_dkdev.dk_label;
  595 
  596         if (omask == 0 && raidopen(dev, 0, S_IFBLK, curproc))
  597                 return (-1);
  598 
  599         if (lp->d_partitions[part].p_fstype != FS_SWAP)
  600                 size = -1;
  601         else
  602                 size = DL_GETPSIZE(&lp->d_partitions[part]) *
  603                     (lp->d_secsize / DEV_BSIZE);
  604 
  605         if (omask == 0 && raidclose(dev, 0, S_IFBLK, curproc))
  606                 return (-1);
  607 
  608         return (size);
  609 
  610 }
  611 
  612 int
  613 raiddump(dev_t dev, daddr64_t blkno, caddr_t va, size_t size)
  614 {
  615         /* Not implemented. */
  616         return (ENXIO);
  617 }
  618 
  619 /* ARGSUSED */
  620 int
  621 raidopen(dev_t dev, int flags, int fmt, struct proc *p)
  622 {
  623         int unit = DISKUNIT(dev);
  624         struct raid_softc *rs;
  625         int part,pmask;
  626         int error = 0;
  627 
  628         if (unit >= numraid)
  629                 return (ENXIO);
  630         rs = &raid_softc[unit];
  631 
  632         if ((error = raidlock(rs)) != 0)
  633                 return (error);
  634 
  635         part = DISKPART(dev);
  636         pmask = (1 << part);
  637 
  638         db1_printf(
  639             ("Opening raid device number: %d partition: %d\n", unit, part));
  640 
  641 
  642         if ((rs->sc_flags & RAIDF_INITED) && (rs->sc_dkdev.dk_openmask == 0))
  643                 raidgetdisklabel(dev, rs->sc_dkdev.dk_label, 0);
  644 
  645         /* Make sure that this partition exists. */
  646 
  647         if (part != RAW_PART) {
  648                 db1_printf(("Not a raw partition..\n"));
  649                 if (((rs->sc_flags & RAIDF_INITED) == 0) ||
  650                     ((part >= rs->sc_dkdev.dk_label->d_npartitions) ||
  651                     (rs->sc_dkdev.dk_label->d_partitions[part].p_fstype ==
  652                     FS_UNUSED))) {
  653                         error = ENXIO;
  654                         raidunlock(rs);
  655                         db1_printf(("Bailing out...\n"));
  656                         return (error);
  657                 }
  658         }
  659 
  660         /* Prevent this unit from being unconfigured while opened. */
  661         switch (fmt) {
  662         case S_IFCHR:
  663                 rs->sc_dkdev.dk_copenmask |= pmask;
  664                 break;
  665 
  666         case S_IFBLK:
  667                 rs->sc_dkdev.dk_bopenmask |= pmask;
  668                 break;
  669         }
  670 
  671         if ((rs->sc_dkdev.dk_openmask == 0) &&
  672             ((rs->sc_flags & RAIDF_INITED) != 0)) {
  673                 /*
  674                  * First one...  Mark things as dirty...  Note that we *MUST*
  675                  * have done a configure before this.  I DO NOT WANT TO BE
  676                  * SCRIBBLING TO RANDOM COMPONENTS UNTIL IT'S BEEN DETERMINED
  677                  * THAT THEY BELONG TOGETHER!!!!!
  678                  */
  679                 /*
  680                  * XXX should check to see if we're only open for reading
  681                  * here...  If so, we needn't do this, but then need some
  682                  * other way of keeping track of what's happened...
  683                  */
  684 
  685                 rf_markalldirty( raidPtrs[unit] );
  686         }
  687 
  688         rs->sc_dkdev.dk_openmask =
  689             rs->sc_dkdev.dk_copenmask | rs->sc_dkdev.dk_bopenmask;
  690 
  691         raidunlock(rs);
  692 
  693         return (error);
  694 }
  695 
  696 /* ARGSUSED */
  697 int
  698 raidclose(dev_t dev, int flags, int fmt, struct proc *p)
  699 {
  700         int unit = DISKUNIT(dev);
  701         struct raid_softc *rs;
  702         int error = 0;
  703         int part;
  704 
  705         if (unit >= numraid)
  706                 return (ENXIO);
  707         rs = &raid_softc[unit];
  708 
  709         if ((error = raidlock(rs)) != 0)
  710                 return (error);
  711 
  712         part = DISKPART(dev);
  713 
  714         /* ...that much closer to allowing unconfiguration... */
  715         switch (fmt) {
  716         case S_IFCHR:
  717                 rs->sc_dkdev.dk_copenmask &= ~(1 << part);
  718                 break;
  719 
  720         case S_IFBLK:
  721                 rs->sc_dkdev.dk_bopenmask &= ~(1 << part);
  722                 break;
  723         }
  724         rs->sc_dkdev.dk_openmask =
  725             rs->sc_dkdev.dk_copenmask | rs->sc_dkdev.dk_bopenmask;
  726 
  727         if ((rs->sc_dkdev.dk_openmask == 0) &&
  728             ((rs->sc_flags & RAIDF_INITED) != 0)) {
  729                 /*
  730                  * Last one...  Device is not unconfigured yet.
  731                  * Device shutdown has taken care of setting the
  732                  * clean bits if RAIDF_INITED is not set.
  733                  * Mark things as clean...
  734                  */
  735                 db1_printf(("Last one on raid%d.  Updating status.\n",unit));
  736                 rf_update_component_labels(raidPtrs[unit],
  737                                                  RF_FINAL_COMPONENT_UPDATE);
  738         }
  739 
  740         raidunlock(rs);
  741         return (0);
  742 }
  743 
  744 void
  745 raidstrategy(struct buf *bp)
  746 {
  747         int s;
  748 
  749         unsigned int raidID = DISKUNIT(bp->b_dev);
  750         RF_Raid_t *raidPtr;
  751         struct raid_softc *rs = &raid_softc[raidID];
  752         struct disklabel *lp;
  753         int wlabel;
  754 
  755         s = splbio();
  756 
  757         if ((rs->sc_flags & RAIDF_INITED) ==0) {
  758                 bp->b_error = ENXIO;
  759                 bp->b_flags |= B_ERROR;
  760                 bp->b_resid = bp->b_bcount;
  761                 biodone(bp);
  762                 goto raidstrategy_end;
  763         }
  764         if (raidID >= numraid || !raidPtrs[raidID]) {
  765                 bp->b_error = ENODEV;
  766                 bp->b_flags |= B_ERROR;
  767                 bp->b_resid = bp->b_bcount;
  768                 biodone(bp);
  769                 goto raidstrategy_end;
  770         }
  771         raidPtr = raidPtrs[raidID];
  772         if (!raidPtr->valid) {
  773                 bp->b_error = ENODEV;
  774                 bp->b_flags |= B_ERROR;
  775                 bp->b_resid = bp->b_bcount;
  776                 biodone(bp);
  777                 goto raidstrategy_end;
  778         }
  779         if (bp->b_bcount == 0) {
  780                 db1_printf(("b_bcount is zero..\n"));
  781                 biodone(bp);
  782                 goto raidstrategy_end;
  783         }
  784         lp = rs->sc_dkdev.dk_label;
  785 
  786         /*
  787          * Do bounds checking and adjust transfer.  If there's an
  788          * error, the bounds check will flag that for us.
  789          */
  790         wlabel = rs->sc_flags & (RAIDF_WLABEL | RAIDF_LABELLING);
  791         if (DISKPART(bp->b_dev) != RAW_PART)
  792                 if (bounds_check_with_label(bp, lp, wlabel) <= 0) {
  793                         db1_printf(("Bounds check failed!!:%d %d\n",
  794                             (int)bp->b_blkno, (int)wlabel));
  795                         biodone(bp);
  796                         goto raidstrategy_end;
  797                 }
  798 
  799         bp->b_resid = 0;
  800 
  801         bp->b_actf = rs->sc_q.b_actf;
  802         rs->sc_q.b_actf = bp;
  803         rs->sc_q.b_active++;
  804 
  805         raidstart(raidPtrs[raidID]);
  806 
  807 raidstrategy_end:
  808         splx(s);
  809 }
  810 
  811 /* ARGSUSED */
  812 int
  813 raidread(dev_t dev, struct uio *uio, int flags)
  814 {
  815         int unit = DISKUNIT(dev);
  816         struct raid_softc *rs;
  817         int part;
  818 
  819         if (unit >= numraid)
  820                 return (ENXIO);
  821         rs = &raid_softc[unit];
  822 
  823         if ((rs->sc_flags & RAIDF_INITED) == 0)
  824                 return (ENXIO);
  825         part = DISKPART(dev);
  826 
  827         db1_printf(("raidread: unit: %d partition: %d\n", unit, part));
  828 
  829         return (physio(raidstrategy, NULL, dev, B_READ, minphys, uio));
  830 }
  831 
  832 /* ARGSUSED */
  833 int
  834 raidwrite(dev_t dev, struct uio *uio, int flags)
  835 {
  836         int unit = DISKUNIT(dev);
  837         struct raid_softc *rs;
  838 
  839         if (unit >= numraid)
  840                 return (ENXIO);
  841         rs = &raid_softc[unit];
  842 
  843         if ((rs->sc_flags & RAIDF_INITED) == 0)
  844                 return (ENXIO);
  845         db1_printf(("raidwrite\n"));
  846         return (physio(raidstrategy, NULL, dev, B_WRITE, minphys, uio));
  847 }
  848 
  849 int
  850 raidioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
  851 {
  852         int unit = DISKUNIT(dev);
  853         int error = 0;
  854         int part, pmask;
  855         struct raid_softc *rs;
  856         RF_Config_t *k_cfg, *u_cfg;
  857         RF_Raid_t *raidPtr;
  858         RF_RaidDisk_t *diskPtr;
  859         RF_AccTotals_t *totals;
  860         RF_DeviceConfig_t *d_cfg, **ucfgp;
  861         u_char *specific_buf;
  862         int retcode = 0;
  863         int row;
  864         int column;
  865         struct rf_recon_req *rrcopy, *rr;
  866         RF_ComponentLabel_t *clabel;
  867         RF_ComponentLabel_t ci_label;
  868         RF_ComponentLabel_t **clabel_ptr;
  869         RF_SingleComponent_t *sparePtr,*componentPtr;
  870         RF_SingleComponent_t hot_spare;
  871         RF_SingleComponent_t component;
  872         RF_ProgressInfo_t progressInfo, **progressInfoPtr;
  873         int i, j, d;
  874 
  875         if (unit >= numraid)
  876                 return (ENXIO);
  877         rs = &raid_softc[unit];
  878         raidPtr = raidPtrs[unit];
  879 
  880         db1_printf(("raidioctl: %d %d %d %d\n", (int)dev, (int)DISKPART(dev),
  881             (int)unit, (int)cmd));
  882 
  883         /* Must be open for writes for these commands... */
  884         switch (cmd) {
  885         case DIOCSDINFO:
  886         case DIOCWDINFO:
  887         case DIOCWLABEL:
  888                 if ((flag & FWRITE) == 0)
  889                         return (EBADF);
  890         }
  891 
  892         /* Must be initialized for these... */
  893         switch (cmd) {
  894         case DIOCGDINFO:
  895         case DIOCSDINFO:
  896         case DIOCWDINFO:
  897         case DIOCGPART:
  898         case DIOCWLABEL:
  899         case DIOCGPDINFO:
  900         case RAIDFRAME_SHUTDOWN:
  901         case RAIDFRAME_REWRITEPARITY:
  902         case RAIDFRAME_GET_INFO:
  903         case RAIDFRAME_RESET_ACCTOTALS:
  904         case RAIDFRAME_GET_ACCTOTALS:
  905         case RAIDFRAME_KEEP_ACCTOTALS:
  906         case RAIDFRAME_GET_SIZE:
  907         case RAIDFRAME_FAIL_DISK:
  908         case RAIDFRAME_COPYBACK:
  909         case RAIDFRAME_CHECK_RECON_STATUS:
  910         case RAIDFRAME_CHECK_RECON_STATUS_EXT:
  911         case RAIDFRAME_GET_COMPONENT_LABEL:
  912         case RAIDFRAME_SET_COMPONENT_LABEL:
  913         case RAIDFRAME_ADD_HOT_SPARE:
  914         case RAIDFRAME_REMOVE_HOT_SPARE:
  915         case RAIDFRAME_INIT_LABELS:
  916         case RAIDFRAME_REBUILD_IN_PLACE:
  917         case RAIDFRAME_CHECK_PARITY:
  918         case RAIDFRAME_CHECK_PARITYREWRITE_STATUS:
  919         case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT:
  920         case RAIDFRAME_CHECK_COPYBACK_STATUS:
  921         case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT:
  922         case RAIDFRAME_SET_AUTOCONFIG:
  923         case RAIDFRAME_SET_ROOT:
  924         case RAIDFRAME_DELETE_COMPONENT:
  925         case RAIDFRAME_INCORPORATE_HOT_SPARE:
  926                 if ((rs->sc_flags & RAIDF_INITED) == 0)
  927                         return (ENXIO);
  928         }
  929 
  930         switch (cmd) {
  931                 /* Configure the system. */
  932         case RAIDFRAME_CONFIGURE:
  933 
  934                 if (raidPtr->valid) {
  935                         /* There is a valid RAID set running on this unit ! */
  936                         printf("raid%d: Device already configured!\n",unit);
  937                         return(EINVAL);
  938                 }
  939 
  940                 /*
  941                  * Copy-in the configuration information.
  942                  * data points to a pointer to the configuration structure.
  943                  */
  944                 u_cfg = *((RF_Config_t **)data);
  945                 RF_Malloc(k_cfg, sizeof (RF_Config_t), (RF_Config_t *));
  946                 if (k_cfg == NULL) {
  947                         return (ENOMEM);
  948                 }
  949                 retcode = copyin((caddr_t)u_cfg, (caddr_t)k_cfg,
  950                     sizeof (RF_Config_t));
  951                 if (retcode) {
  952                         RF_Free(k_cfg, sizeof(RF_Config_t));
  953                         return (retcode);
  954                 }
  955 
  956                 /*
  957                  * Allocate a buffer for the layout-specific data,
  958                  * and copy it in.
  959                  */
  960                 if (k_cfg->layoutSpecificSize) {
  961                         if (k_cfg->layoutSpecificSize > 10000) {
  962                                 /* Sanity check. */
  963                                 RF_Free(k_cfg, sizeof(RF_Config_t));
  964                                 return (EINVAL);
  965                         }
  966                         RF_Malloc(specific_buf, k_cfg->layoutSpecificSize,
  967                             (u_char *));
  968                         if (specific_buf == NULL) {
  969                                 RF_Free(k_cfg, sizeof (RF_Config_t));
  970                                 return (ENOMEM);
  971                         }
  972                         retcode = copyin(k_cfg->layoutSpecific,
  973                             (caddr_t)specific_buf, k_cfg->layoutSpecificSize);
  974                         if (retcode) {
  975                                 RF_Free(k_cfg, sizeof(RF_Config_t));
  976                                 RF_Free(specific_buf,
  977                                         k_cfg->layoutSpecificSize);
  978                                 return (retcode);
  979                         }
  980                 } else
  981                         specific_buf = NULL;
  982                 k_cfg->layoutSpecific = specific_buf;
  983 
  984                 /*
  985                  * We should do some kind of sanity check on the
  986                  * configuration.
  987                  * Store the sum of all the bytes in the last byte ?
  988                  */
  989 
  990                 /*
  991                  * Clear the entire RAID descriptor, just to make sure
  992                  *  there is no stale data left in the case of a
  993                  *  reconfiguration.
  994                  */
  995                 bzero((char *) raidPtr, sizeof(RF_Raid_t));
  996 
  997                 /* Configure the system. */
  998                 raidPtr->raidid = unit;
  999 
 1000                 retcode = rf_Configure(raidPtr, k_cfg, NULL);
 1001 
 1002                 if (retcode == 0) {
 1003 
 1004                         /*
 1005                          * Allow this many simultaneous IO's to
 1006                          * this RAID device.
 1007                          */
 1008                         raidPtr->openings = RAIDOUTSTANDING;
 1009 
 1010                         raidinit(raidPtr);
 1011                         rf_markalldirty(raidPtr);
 1012                 }
 1013 
 1014                 /* Free the buffers.  No return code here. */
 1015                 if (k_cfg->layoutSpecificSize) {
 1016                         RF_Free(specific_buf, k_cfg->layoutSpecificSize);
 1017                 }
 1018                 RF_Free(k_cfg, sizeof (RF_Config_t));
 1019 
 1020                 return (retcode);
 1021 
 1022         case RAIDFRAME_SHUTDOWN:
 1023                 /* Shutdown the system. */
 1024 
 1025                 if ((error = raidlock(rs)) != 0)
 1026                         return (error);
 1027 
 1028                 /*
 1029                  * If somebody has a partition mounted, we shouldn't
 1030                  * shutdown.
 1031                  */
 1032 
 1033                 part = DISKPART(dev);
 1034                 pmask = (1 << part);
 1035                 if ((rs->sc_dkdev.dk_openmask & ~pmask) ||
 1036                     ((rs->sc_dkdev.dk_bopenmask & pmask) &&
 1037                     (rs->sc_dkdev.dk_copenmask & pmask))) {
 1038                         raidunlock(rs);
 1039                         return (EBUSY);
 1040                 }
 1041 
 1042                 if ((retcode = rf_Shutdown(raidPtr)) == 0) {
 1043 
 1044                         pool_destroy(&rs->sc_cbufpool);
 1045 
 1046                         /* It's no longer initialized... */
 1047                         rs->sc_flags &= ~RAIDF_INITED;
 1048 
 1049                         /* config_detach the device. */
 1050                         config_detach(device_lookup(&raid_cd, unit), 0);
 1051 
 1052                         /* Detach the disk. */
 1053                         disk_detach(&rs->sc_dkdev);
 1054                 }
 1055 
 1056                 raidunlock(rs);
 1057 
 1058                 return (retcode);
 1059 
 1060         case RAIDFRAME_GET_COMPONENT_LABEL:
 1061                 clabel_ptr = (RF_ComponentLabel_t **) data;
 1062                 /*
 1063                  * We need to read the component label for the disk indicated
 1064                  * by row,column in clabel.
 1065                  */
 1066 
 1067                 /*
 1068                  * For practice, let's get it directly from disk, rather
 1069                  * than from the in-core copy.
 1070                  */
 1071                 RF_Malloc( clabel, sizeof( RF_ComponentLabel_t ),
 1072                            (RF_ComponentLabel_t *));
 1073                 if (clabel == NULL)
 1074                         return (ENOMEM);
 1075 
 1076                 bzero((char *) clabel, sizeof(RF_ComponentLabel_t));
 1077 
 1078                 retcode = copyin( *clabel_ptr, clabel,
 1079                                   sizeof(RF_ComponentLabel_t));
 1080 
 1081                 if (retcode) {
 1082                         RF_Free( clabel, sizeof(RF_ComponentLabel_t));
 1083                         return(retcode);
 1084                 }
 1085 
 1086                 row = clabel->row;
 1087                 column = clabel->column;
 1088 
 1089                 if ((row < 0) || (row >= raidPtr->numRow) ||
 1090                     (column < 0) || (column >= raidPtr->numCol)) {
 1091                         RF_Free( clabel, sizeof(RF_ComponentLabel_t));
 1092                         return(EINVAL);
 1093                 }
 1094 
 1095                 raidread_component_label(raidPtr->Disks[row][column].dev,
 1096                     raidPtr->raid_cinfo[row][column].ci_vp, clabel );
 1097 
 1098                 retcode = copyout((caddr_t) clabel,
 1099                                   (caddr_t) *clabel_ptr,
 1100                                   sizeof(RF_ComponentLabel_t));
 1101                 RF_Free( clabel, sizeof(RF_ComponentLabel_t));
 1102                 return (retcode);
 1103 
 1104         case RAIDFRAME_SET_COMPONENT_LABEL:
 1105                 clabel = (RF_ComponentLabel_t *) data;
 1106 
 1107                 /* XXX check the label for valid stuff... */
 1108                 /*
 1109                  * Note that some things *should not* get modified --
 1110                  * the user should be re-initing the labels instead of
 1111                  * trying to patch things.
 1112                  */
 1113 
 1114 #ifdef  RAIDDEBUG
 1115                 printf("Got component label:\n");
 1116                 printf("Version: %d\n",clabel->version);
 1117                 printf("Serial Number: %d\n",clabel->serial_number);
 1118                 printf("Mod counter: %d\n",clabel->mod_counter);
 1119                 printf("Row: %d\n", clabel->row);
 1120                 printf("Column: %d\n", clabel->column);
 1121                 printf("Num Rows: %d\n", clabel->num_rows);
 1122                 printf("Num Columns: %d\n", clabel->num_columns);
 1123                 printf("Clean: %d\n", clabel->clean);
 1124                 printf("Status: %d\n", clabel->status);
 1125 #endif  /* RAIDDEBUG */
 1126 
 1127                 row = clabel->row;
 1128                 column = clabel->column;
 1129 
 1130                 if ((row < 0) || (row >= raidPtr->numRow) ||
 1131                     (column < 0) || (column >= raidPtr->numCol)) {
 1132                         return(EINVAL);
 1133                 }
 1134 
 1135                 /* XXX this isn't allowed to do anything for now :-) */
 1136 #if 0
 1137                 raidwrite_component_label(raidPtr->Disks[row][column].dev,
 1138                     raidPtr->raid_cinfo[row][column].ci_vp, clabel );
 1139 #endif
 1140                 return (0);
 1141 
 1142         case RAIDFRAME_INIT_LABELS:
 1143                 clabel = (RF_ComponentLabel_t *) data;
 1144                 /*
 1145                  * We only want the serial number from the above.
 1146                  * We get all the rest of the information from
 1147                  * the config that was used to create this RAID
 1148                  * set.
 1149                  */
 1150 
 1151                 raidPtr->serial_number = clabel->serial_number;
 1152 
 1153                 raid_init_component_label(raidPtr, &ci_label);
 1154                 ci_label.serial_number = clabel->serial_number;
 1155 
 1156                 for(row=0;row<raidPtr->numRow;row++) {
 1157                         ci_label.row = row;
 1158                         for(column=0;column<raidPtr->numCol;column++) {
 1159                                 diskPtr = &raidPtr->Disks[row][column];
 1160                                 if (!RF_DEAD_DISK(diskPtr->status)) {
 1161                                         ci_label.partitionSize =
 1162                                             diskPtr->partitionSize;
 1163                                         ci_label.column = column;
 1164                                         raidwrite_component_label(
 1165                                             raidPtr->Disks[row][column].dev,
 1166                                             raidPtr->raid_cinfo[row][column].ci_vp,
 1167                                             &ci_label );
 1168                                 }
 1169                         }
 1170                 }
 1171 
 1172                 return (retcode);
 1173 
 1174         case RAIDFRAME_REWRITEPARITY:
 1175 
 1176                 if (raidPtr->Layout.map->faultsTolerated == 0) {
 1177                         /* Parity for RAID 0 is trivially correct. */
 1178                         raidPtr->parity_good = RF_RAID_CLEAN;
 1179                         return(0);
 1180                 }
 1181 
 1182 
 1183                 if (raidPtr->parity_rewrite_in_progress == 1) {
 1184                         /* Re-write is already in progress ! */
 1185                         return(EINVAL);
 1186                 }
 1187 
 1188                 retcode = RF_CREATE_THREAD(raidPtr->parity_rewrite_thread,
 1189                                            rf_RewriteParityThread,
 1190                                            raidPtr,"raid_parity");
 1191 
 1192                 return (retcode);
 1193 
 1194         case RAIDFRAME_SET_AUTOCONFIG:
 1195                 d = rf_set_autoconfig(raidPtr, *(int *) data);
 1196                 db1_printf(("New autoconfig value is: %d\n", d));
 1197                 *(int *) data = d;
 1198                 return (retcode);
 1199 
 1200         case RAIDFRAME_SET_ROOT:
 1201                 d = rf_set_rootpartition(raidPtr, *(int *) data);
 1202                 db1_printf(("New rootpartition value is: %d\n", d));
 1203                 *(int *) data = d;
 1204                 return (retcode);
 1205 
 1206 
 1207         case RAIDFRAME_ADD_HOT_SPARE:
 1208                 sparePtr = (RF_SingleComponent_t *) data;
 1209                 memcpy( &hot_spare, sparePtr, sizeof(RF_SingleComponent_t));
 1210                 retcode = rf_add_hot_spare(raidPtr, &hot_spare);
 1211                 return(retcode);
 1212 
 1213         case RAIDFRAME_REMOVE_HOT_SPARE:
 1214                 return(retcode);
 1215 
 1216         case RAIDFRAME_DELETE_COMPONENT:
 1217                 componentPtr = (RF_SingleComponent_t *)data;
 1218                 memcpy( &component, componentPtr,
 1219                         sizeof(RF_SingleComponent_t));
 1220                 retcode = rf_delete_component(raidPtr, &component);
 1221                 return(retcode);
 1222 
 1223         case RAIDFRAME_INCORPORATE_HOT_SPARE:
 1224                 componentPtr = (RF_SingleComponent_t *)data;
 1225                 memcpy( &component, componentPtr,
 1226                         sizeof(RF_SingleComponent_t));
 1227                 retcode = rf_incorporate_hot_spare(raidPtr, &component);
 1228                 return(retcode);
 1229 
 1230         case RAIDFRAME_REBUILD_IN_PLACE:
 1231 
 1232                 if (raidPtr->Layout.map->faultsTolerated == 0) {
 1233                         /* Can't do this on a RAID 0 !! */
 1234                         return(EINVAL);
 1235                 }
 1236 
 1237                 if (raidPtr->recon_in_progress == 1) {
 1238                         /* A reconstruct is already in progress ! */
 1239                         return(EINVAL);
 1240                 }
 1241 
 1242                 componentPtr = (RF_SingleComponent_t *) data;
 1243                 memcpy( &component, componentPtr,
 1244                         sizeof(RF_SingleComponent_t));
 1245                 row = component.row;
 1246                 column = component.column;
 1247                 db1_printf(("Rebuild: %d %d\n",row, column));
 1248                 if ((row < 0) || (row >= raidPtr->numRow) ||
 1249                     (column < 0) || (column >= raidPtr->numCol)) {
 1250                         return(EINVAL);
 1251                 }
 1252 
 1253                 RF_Malloc(rrcopy, sizeof(*rrcopy), (struct rf_recon_req *));
 1254                 if (rrcopy == NULL)
 1255                         return(ENOMEM);
 1256 
 1257                 rrcopy->raidPtr = (void *) raidPtr;
 1258                 rrcopy->row = row;
 1259                 rrcopy->col = column;
 1260 
 1261                 retcode = RF_CREATE_THREAD(raidPtr->recon_thread,
 1262                                            rf_ReconstructInPlaceThread,
 1263                                            rrcopy,"raid_reconip");
 1264 
 1265                 return (retcode);
 1266 
 1267         case RAIDFRAME_GET_INFO:
 1268                 if (!raidPtr->valid)
 1269                         return (ENODEV);
 1270                 ucfgp = (RF_DeviceConfig_t **) data;
 1271                 RF_Malloc(d_cfg, sizeof(RF_DeviceConfig_t),
 1272                           (RF_DeviceConfig_t *));
 1273                 if (d_cfg == NULL)
 1274                         return (ENOMEM);
 1275                 bzero((char *) d_cfg, sizeof(RF_DeviceConfig_t));
 1276                 d_cfg->rows = raidPtr->numRow;
 1277                 d_cfg->cols = raidPtr->numCol;
 1278                 d_cfg->ndevs = raidPtr->numRow * raidPtr->numCol;
 1279                 if (d_cfg->ndevs >= RF_MAX_DISKS) {
 1280                         RF_Free(d_cfg, sizeof(RF_DeviceConfig_t));
 1281                         return (ENOMEM);
 1282                 }
 1283                 d_cfg->nspares = raidPtr->numSpare;
 1284                 if (d_cfg->nspares >= RF_MAX_DISKS) {
 1285                         RF_Free(d_cfg, sizeof(RF_DeviceConfig_t));
 1286                         return (ENOMEM);
 1287                 }
 1288                 d_cfg->maxqdepth = raidPtr->maxQueueDepth;
 1289                 d = 0;
 1290                 for (i = 0; i < d_cfg->rows; i++) {
 1291                         for (j = 0; j < d_cfg->cols; j++) {
 1292                                 d_cfg->devs[d] = raidPtr->Disks[i][j];
 1293                                 d++;
 1294                         }
 1295                 }
 1296                 for (j = d_cfg->cols, i = 0; i < d_cfg->nspares; i++, j++) {
 1297                         d_cfg->spares[i] = raidPtr->Disks[0][j];
 1298                 }
 1299                 retcode = copyout((caddr_t) d_cfg, (caddr_t) * ucfgp,
 1300                                   sizeof(RF_DeviceConfig_t));
 1301                 RF_Free(d_cfg, sizeof(RF_DeviceConfig_t));
 1302 
 1303                 return (retcode);
 1304 
 1305         case RAIDFRAME_CHECK_PARITY:
 1306                 *(int *) data = raidPtr->parity_good;
 1307                 return (0);
 1308 
 1309         case RAIDFRAME_RESET_ACCTOTALS:
 1310                 bzero(&raidPtr->acc_totals, sizeof(raidPtr->acc_totals));
 1311                 return (0);
 1312 
 1313         case RAIDFRAME_GET_ACCTOTALS:
 1314                 totals = (RF_AccTotals_t *) data;
 1315                 *totals = raidPtr->acc_totals;
 1316                 return (0);
 1317 
 1318         case RAIDFRAME_KEEP_ACCTOTALS:
 1319                 raidPtr->keep_acc_totals = *(int *)data;
 1320                 return (0);
 1321 
 1322         case RAIDFRAME_GET_SIZE:
 1323                 *(int *) data = raidPtr->totalSectors;
 1324                 return (0);
 1325 
 1326         /* Fail a disk & optionally start reconstruction. */
 1327         case RAIDFRAME_FAIL_DISK:
 1328                 rr = (struct rf_recon_req *)data;
 1329 
 1330                 if (rr->row < 0 || rr->row >= raidPtr->numRow ||
 1331                     rr->col < 0 || rr->col >= raidPtr->numCol)
 1332                         return (EINVAL);
 1333 
 1334                 db1_printf(("raid%d: Failing the disk: row: %d col: %d\n",
 1335                     unit, rr->row, rr->col));
 1336 
 1337                 /*
 1338                  * Make a copy of the recon request so that we don't
 1339                  * rely on the user's buffer.
 1340                  */
 1341                 RF_Malloc(rrcopy, sizeof(*rrcopy), (struct rf_recon_req *));
 1342                 if (rrcopy == NULL)
 1343                         return(ENOMEM);
 1344                 bcopy(rr, rrcopy, sizeof(*rr));
 1345                 rrcopy->raidPtr = (void *)raidPtr;
 1346 
 1347                 retcode = RF_CREATE_THREAD(raidPtr->recon_thread,
 1348                                            rf_ReconThread,
 1349                                            rrcopy,"raid_recon");
 1350                 return (0);
 1351 
 1352         /*
 1353          * Invoke a copyback operation after recon on whatever
 1354          * disk needs it, if any.
 1355          */
 1356         case RAIDFRAME_COPYBACK:
 1357                 if (raidPtr->Layout.map->faultsTolerated == 0) {
 1358                         /* This makes no sense on a RAID 0 !! */
 1359                         return(EINVAL);
 1360                 }
 1361 
 1362                 if (raidPtr->copyback_in_progress == 1) {
 1363                         /* Copyback is already in progress ! */
 1364                         return(EINVAL);
 1365                 }
 1366 
 1367                 retcode = RF_CREATE_THREAD(raidPtr->copyback_thread,
 1368                                            rf_CopybackThread,
 1369                                            raidPtr,"raid_copyback");
 1370                 return (retcode);
 1371 
 1372         /* Return the percentage completion of reconstruction. */
 1373         case RAIDFRAME_CHECK_RECON_STATUS:
 1374                 if (raidPtr->Layout.map->faultsTolerated == 0) {
 1375                         /*
 1376                          * This makes no sense on a RAID 0, so tell the
 1377                          * user it's done.
 1378                          */
 1379                         *(int *) data = 100;
 1380                         return(0);
 1381                 }
 1382                 row = 0; /* XXX we only consider a single row... */
 1383                 if (raidPtr->status[row] != rf_rs_reconstructing)
 1384                         *(int *)data = 100;
 1385                 else
 1386                         *(int *)data =
 1387                             raidPtr->reconControl[row]->percentComplete;
 1388                 return (0);
 1389 
 1390         case RAIDFRAME_CHECK_RECON_STATUS_EXT:
 1391                 progressInfoPtr = (RF_ProgressInfo_t **) data;
 1392                 row = 0; /* XXX we only consider a single row... */
 1393                 if (raidPtr->status[row] != rf_rs_reconstructing) {
 1394                         progressInfo.remaining = 0;
 1395                         progressInfo.completed = 100;
 1396                         progressInfo.total = 100;
 1397                 } else {
 1398                         progressInfo.total =
 1399                                 raidPtr->reconControl[row]->numRUsTotal;
 1400                         progressInfo.completed =
 1401                                 raidPtr->reconControl[row]->numRUsComplete;
 1402                         progressInfo.remaining = progressInfo.total -
 1403                                 progressInfo.completed;
 1404                 }
 1405                 retcode = copyout((caddr_t) &progressInfo,
 1406                                   (caddr_t) *progressInfoPtr,
 1407                                   sizeof(RF_ProgressInfo_t));
 1408                 return (retcode);
 1409 
 1410         case RAIDFRAME_CHECK_PARITYREWRITE_STATUS:
 1411                 if (raidPtr->Layout.map->faultsTolerated == 0) {
 1412                         /*
 1413                          * This makes no sense on a RAID 0, so tell the
 1414                          * user it's done.
 1415                          */
 1416                         *(int *) data = 100;
 1417                         return(0);
 1418                 }
 1419                 if (raidPtr->parity_rewrite_in_progress == 1) {
 1420                         *(int *) data = 100 *
 1421                                 raidPtr->parity_rewrite_stripes_done /
 1422                                 raidPtr->Layout.numStripe;
 1423                 } else {
 1424                         *(int *) data = 100;
 1425                 }
 1426                 return (0);
 1427 
 1428         case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT:
 1429                 progressInfoPtr = (RF_ProgressInfo_t **) data;
 1430                 if (raidPtr->parity_rewrite_in_progress == 1) {
 1431                         progressInfo.total = raidPtr->Layout.numStripe;
 1432                         progressInfo.completed =
 1433                                 raidPtr->parity_rewrite_stripes_done;
 1434                         progressInfo.remaining = progressInfo.total -
 1435                                 progressInfo.completed;
 1436                 } else {
 1437                         progressInfo.remaining = 0;
 1438                         progressInfo.completed = 100;
 1439                         progressInfo.total = 100;
 1440                 }
 1441                 retcode = copyout((caddr_t) &progressInfo,
 1442                                   (caddr_t) *progressInfoPtr,
 1443                                   sizeof(RF_ProgressInfo_t));
 1444                 return (retcode);
 1445 
 1446         case RAIDFRAME_CHECK_COPYBACK_STATUS:
 1447                 if (raidPtr->Layout.map->faultsTolerated == 0) {
 1448                         /* This makes no sense on a RAID 0 !! */
 1449                         *(int *) data = 100;
 1450                         return(0);
 1451                 }
 1452                 if (raidPtr->copyback_in_progress == 1) {
 1453                         *(int *) data = 100 * raidPtr->copyback_stripes_done /
 1454                                 raidPtr->Layout.numStripe;
 1455                 } else {
 1456                         *(int *) data = 100;
 1457                 }
 1458                 return (0);
 1459 
 1460         case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT:
 1461                 progressInfoPtr = (RF_ProgressInfo_t **) data;
 1462                 if (raidPtr->copyback_in_progress == 1) {
 1463                         progressInfo.total = raidPtr->Layout.numStripe;
 1464                         progressInfo.completed =
 1465                                 raidPtr->copyback_stripes_done;
 1466                         progressInfo.remaining = progressInfo.total -
 1467                                 progressInfo.completed;
 1468                 } else {
 1469                         progressInfo.remaining = 0;
 1470                         progressInfo.completed = 100;
 1471                         progressInfo.total = 100;
 1472                 }
 1473                 retcode = copyout((caddr_t) &progressInfo,
 1474                                   (caddr_t) *progressInfoPtr,
 1475                                   sizeof(RF_ProgressInfo_t));
 1476                 return (retcode);
 1477 
 1478 #if 0
 1479         case RAIDFRAME_SPARET_WAIT:
 1480                 /*
 1481                  * The sparetable daemon calls this to wait for the
 1482                  * kernel to need a spare table.
 1483                  * This ioctl does not return until a spare table is needed.
 1484                  * XXX -- Calling mpsleep here in the ioctl code is almost
 1485                  * certainly wrong and evil. -- XXX
 1486                  * XXX -- I should either compute the spare table in the
 1487                  * kernel, or have a different. -- XXX
 1488                  * XXX -- Interface (a different character device) for
 1489                  * delivering the table. -- XXX
 1490                  */
 1491                 RF_LOCK_MUTEX(rf_sparet_wait_mutex);
 1492                 while (!rf_sparet_wait_queue)
 1493                         mpsleep(&rf_sparet_wait_queue, (PZERO + 1) | PCATCH,
 1494                             "sparet wait", 0,
 1495                             (void *)simple_lock_addr(rf_sparet_wait_mutex),
 1496                             MS_LOCK_SIMPLE);
 1497                 waitreq = rf_sparet_wait_queue;
 1498                 rf_sparet_wait_queue = rf_sparet_wait_queue->next;
 1499                 RF_UNLOCK_MUTEX(rf_sparet_wait_mutex);
 1500 
 1501                 *((RF_SparetWait_t *)data) = *waitreq;
 1502 
 1503                 RF_Free(waitreq, sizeof *waitreq);
 1504                 return (0);
 1505 
 1506         case RAIDFRAME_ABORT_SPARET_WAIT:
 1507                 /*
 1508                  * Wakes up a process waiting on SPARET_WAIT and puts an
 1509                  * error code in it that will cause the dameon to exit.
 1510                  */
 1511                 RF_Malloc(waitreq, sizeof (*waitreq), (RF_SparetWait_t *));
 1512                 waitreq->fcol = -1;
 1513                 RF_LOCK_MUTEX(rf_sparet_wait_mutex);
 1514                 waitreq->next = rf_sparet_wait_queue;
 1515                 rf_sparet_wait_queue = waitreq;
 1516                 RF_UNLOCK_MUTEX(rf_sparet_wait_mutex);
 1517                 wakeup(&rf_sparet_wait_queue);
 1518                 return (0);
 1519 
 1520         case RAIDFRAME_SEND_SPARET:
 1521                 /*
 1522                  * Used by the spare table daemon to deliver a spare table
 1523                  * into the kernel.
 1524                  */
 1525 
 1526                 /* Install the spare table. */
 1527                 retcode = rf_SetSpareTable(raidPtr,*(void **)data);
 1528 
 1529                 /*
 1530                  * Respond to the requestor.  The return status of the
 1531                  * spare table installation is passed in the "fcol" field.
 1532                  */
 1533                 RF_Malloc(waitreq, sizeof *waitreq, (RF_SparetWait_t *));
 1534                 waitreq->fcol = retcode;
 1535                 RF_LOCK_MUTEX(rf_sparet_wait_mutex);
 1536                 waitreq->next = rf_sparet_resp_queue;
 1537                 rf_sparet_resp_queue = waitreq;
 1538                 wakeup(&rf_sparet_resp_queue);
 1539                 RF_UNLOCK_MUTEX(rf_sparet_wait_mutex);
 1540 
 1541                 return (retcode);
 1542 #endif
 1543         /* Fall through to the os-specific code below. */
 1544         default:
 1545                 break;
 1546         }
 1547 
 1548         if (!raidPtr->valid)
 1549                 return (EINVAL);
 1550 
 1551         /*
 1552          * Add support for "regular" device ioctls here.
 1553          */
 1554         switch (cmd) {
 1555         case DIOCGDINFO:
 1556                 *(struct disklabel *)data = *(rs->sc_dkdev.dk_label);
 1557                 break;
 1558 
 1559         case DIOCGPART:
 1560                 ((struct partinfo *)data)->disklab = rs->sc_dkdev.dk_label;
 1561                 ((struct partinfo *)data)->part =
 1562                     &rs->sc_dkdev.dk_label->d_partitions[DISKPART(dev)];
 1563                 break;
 1564 
 1565         case DIOCWDINFO:
 1566         case DIOCSDINFO:
 1567         {
 1568                 struct disklabel *lp;
 1569                 lp = (struct disklabel *)data;
 1570 
 1571                 if ((error = raidlock(rs)) != 0)
 1572                         return (error);
 1573 
 1574                 rs->sc_flags |= RAIDF_LABELLING;
 1575 
 1576                 error = setdisklabel(rs->sc_dkdev.dk_label, lp, 0);
 1577                 if (error == 0) {
 1578                         if (cmd == DIOCWDINFO)
 1579                                 error = writedisklabel(DISKLABELDEV(dev),
 1580                                     raidstrategy, rs->sc_dkdev.dk_label);
 1581                 }
 1582 
 1583                 rs->sc_flags &= ~RAIDF_LABELLING;
 1584 
 1585                 raidunlock(rs);
 1586 
 1587                 if (error)
 1588                         return (error);
 1589                 break;
 1590         }
 1591 
 1592         case DIOCWLABEL:
 1593                 if (*(int *)data != 0)
 1594                         rs->sc_flags |= RAIDF_WLABEL;
 1595                 else
 1596                         rs->sc_flags &= ~RAIDF_WLABEL;
 1597                 break;
 1598 
 1599         case DIOCGPDINFO:
 1600                 raidgetdisklabel(dev, (struct disklabel *)data, 1);
 1601                 break;
 1602 
 1603         default:
 1604                 retcode = ENOTTY;
 1605         }
 1606 
 1607         return (retcode);
 1608 }
 1609 
 1610 /*
 1611  * raidinit -- Complete the rest of the initialization for the
 1612  * RAIDframe device.
 1613  */
 1614 void
 1615 raidinit(RF_Raid_t *raidPtr)
 1616 {
 1617         struct raid_softc *rs;
 1618         struct cfdata   *cf;
 1619         int unit;
 1620 
 1621         unit = raidPtr->raidid;
 1622 
 1623         rs = &raid_softc[unit];
 1624         pool_init(&rs->sc_cbufpool, sizeof(struct raidbuf), 0,
 1625                 0, 0, "raidpl", NULL);
 1626 
 1627         /* XXX should check return code first... */
 1628         rs->sc_flags |= RAIDF_INITED;
 1629 
 1630         /* XXX doesn't check bounds. */
 1631         snprintf(rs->sc_xname, sizeof rs->sc_xname, "raid%d", unit);
 1632 
 1633         rs->sc_dkdev.dk_name = rs->sc_xname;
 1634 
 1635         /*
 1636          * disk_attach actually creates space for the CPU disklabel, among
 1637          * other things, so it's critical to call this *BEFORE* we try
 1638          * putzing with disklabels.
 1639          */
 1640         disk_attach(&rs->sc_dkdev);
 1641 
 1642         /*
 1643          * XXX There may be a weird interaction here between this, and
 1644          * protectedSectors, as used in RAIDframe.
 1645          */
 1646         rs->sc_size = raidPtr->totalSectors;
 1647 
 1648         /*
 1649          * config_attach the raid device into the device tree.
 1650          * For autoconf rootdev selection...
 1651          */
 1652         cf = malloc(sizeof(struct cfdata), M_RAIDFRAME, M_NOWAIT);
 1653         if (cf == NULL) {
 1654                 printf("WARNING: no memory for cfdata struct\n");
 1655                 return;
 1656         }
 1657         bzero(cf, sizeof(struct cfdata));
 1658 
 1659         cf->cf_attach = &raid_ca;
 1660         cf->cf_driver = &raid_cd;
 1661         cf->cf_unit   = unit;
 1662 
 1663         config_attach(NULL, cf, NULL, NULL);
 1664 }
 1665 
 1666 /*
 1667  * Wake up the daemon & tell it to get us a spare table.
 1668  * XXX
 1669  * The entries in the queues should be tagged with the raidPtr so that
 1670  * in the extremely rare case that two recons happen at once, we know
 1671  * which devices were requesting a spare table.
 1672  * XXX
 1673  *
 1674  * XXX This code is not currently used. GO
 1675  */
 1676 int
 1677 rf_GetSpareTableFromDaemon(RF_SparetWait_t *req)
 1678 {
 1679         int retcode;
 1680 
 1681         RF_LOCK_MUTEX(rf_sparet_wait_mutex);
 1682         req->next = rf_sparet_wait_queue;
 1683         rf_sparet_wait_queue = req;
 1684         wakeup(&rf_sparet_wait_queue);
 1685 
 1686         /* mpsleep unlocks the mutex. */
 1687         while (!rf_sparet_resp_queue) {
 1688                 tsleep(&rf_sparet_resp_queue, PRIBIO,
 1689                     "RAIDframe getsparetable", 0);
 1690         }
 1691         req = rf_sparet_resp_queue;
 1692         rf_sparet_resp_queue = req->next;
 1693         RF_UNLOCK_MUTEX(rf_sparet_wait_mutex);
 1694 
 1695         retcode = req->fcol;
 1696         /* This is not the same req as we alloc'd. */
 1697         RF_Free(req, sizeof *req);
 1698         return (retcode);
 1699 }
 1700 
 1701 /*
 1702  * A wrapper around rf_DoAccess that extracts appropriate info from the
 1703  * bp and passes it down.
 1704  * Any calls originating in the kernel must use non-blocking I/O.
 1705  * Do some extra sanity checking to return "appropriate" error values for
 1706  * certain conditions (to make some standard utilities work).
 1707  *
 1708  * Formerly known as: rf_DoAccessKernel
 1709  */
 1710 void
 1711 raidstart(RF_Raid_t *raidPtr)
 1712 {
 1713         RF_SectorCount_t num_blocks, pb, sum;
 1714         RF_RaidAddr_t raid_addr;
 1715         int retcode;
 1716         struct partition *pp;
 1717         daddr64_t blocknum;
 1718         int unit;
 1719         struct raid_softc *rs;
 1720         int     do_async;
 1721         struct buf *bp;
 1722 
 1723         unit = raidPtr->raidid;
 1724         rs = &raid_softc[unit];
 1725 
 1726         /* Quick check to see if anything has died recently. */
 1727         RF_LOCK_MUTEX(raidPtr->mutex);
 1728         if (raidPtr->numNewFailures > 0) {
 1729                 rf_update_component_labels(raidPtr,
 1730                                            RF_NORMAL_COMPONENT_UPDATE);
 1731                 raidPtr->numNewFailures--;
 1732         }
 1733         RF_UNLOCK_MUTEX(raidPtr->mutex);
 1734 
 1735         /* Check to see if we're at the limit... */
 1736         RF_LOCK_MUTEX(raidPtr->mutex);
 1737         while (raidPtr->openings > 0) {
 1738                 RF_UNLOCK_MUTEX(raidPtr->mutex);
 1739 
 1740                 bp = rs->sc_q.b_actf;
 1741                 if (bp == NULL) {
 1742                         /* Nothing more to do. */
 1743                         return;
 1744                 }
 1745                 rs->sc_q.b_actf = bp->b_actf;
 1746 
 1747                 /*
 1748                  * Ok, for the bp we have here, bp->b_blkno is relative to the
 1749                  * partition... We need to make it absolute to the underlying
 1750                  * device...
 1751                  */
 1752 
 1753                 blocknum = bp->b_blkno;
 1754                 if (DISKPART(bp->b_dev) != RAW_PART) {
 1755                         pp = &rs->sc_dkdev.dk_label->d_partitions[DISKPART(bp->b_dev)];
 1756                         blocknum += DL_GETPOFFSET(pp);
 1757                 }
 1758 
 1759                 db1_printf(("Blocks: %d, %lld\n", (int) bp->b_blkno,
 1760                             blocknum));
 1761 
 1762                 db1_printf(("bp->b_bcount = %d\n", (int) bp->b_bcount));
 1763                 db1_printf(("bp->b_resid = %d\n", (int) bp->b_resid));
 1764 
 1765                 /*
 1766                  * *THIS* is where we adjust what block we're going to...
 1767                  * But DO NOT TOUCH bp->b_blkno !!!
 1768                  */
 1769                 raid_addr = blocknum;
 1770 
 1771                 num_blocks = bp->b_bcount >> raidPtr->logBytesPerSector;
 1772                 pb = (bp->b_bcount & raidPtr->sectorMask) ? 1 : 0;
 1773                 sum = raid_addr + num_blocks + pb;
 1774                 if (1 || rf_debugKernelAccess) {
 1775                         db1_printf(("raid_addr=%d sum=%d num_blocks=%d(+%d)"
 1776                             " (%d)\n", (int)raid_addr, (int)sum,
 1777                             (int)num_blocks, (int)pb, (int)bp->b_resid));
 1778                 }
 1779                 if ((sum > raidPtr->totalSectors) || (sum < raid_addr)
 1780                     || (sum < num_blocks) || (sum < pb)) {
 1781                         bp->b_error = ENOSPC;
 1782                         bp->b_flags |= B_ERROR;
 1783                         bp->b_resid = bp->b_bcount;
 1784                         /* db1_printf(("%s: Calling biodone on 0x%x\n",
 1785                             __func__, bp)); */
 1786                         splassert(IPL_BIO);
 1787                         biodone(bp);
 1788                         RF_LOCK_MUTEX(raidPtr->mutex);
 1789                         continue;
 1790                 }
 1791                 /*
 1792                  * XXX rf_DoAccess() should do this, not just DoAccessKernel().
 1793                  */
 1794 
 1795                 if (bp->b_bcount & raidPtr->sectorMask) {
 1796                         bp->b_error = EINVAL;
 1797                         bp->b_flags |= B_ERROR;
 1798                         bp->b_resid = bp->b_bcount;
 1799                         /* db1_printf(("%s: Calling biodone on 0x%x\n",
 1800                             __func__, bp)); */
 1801                         splassert(IPL_BIO);
 1802                         biodone(bp);
 1803                         RF_LOCK_MUTEX(raidPtr->mutex);
 1804                         continue;
 1805 
 1806                 }
 1807                 db1_printf(("Calling DoAccess..\n"));
 1808 
 1809 
 1810                 RF_LOCK_MUTEX(raidPtr->mutex);
 1811                 raidPtr->openings--;
 1812                 RF_UNLOCK_MUTEX(raidPtr->mutex);
 1813 
 1814                 /*
 1815                  * Everything is async.
 1816                  */
 1817                 do_async = 1;
 1818 
 1819                 disk_busy(&rs->sc_dkdev);
 1820 
 1821                 /*
 1822                  * XXX we're still at splbio() here...  Do we *really*
 1823                  * need to be ?
 1824                  */
 1825 
 1826                 /*
 1827                  * Don't ever condition on bp->b_flags & B_WRITE.
 1828                  * Always condition on B_READ instead.
 1829                  */
 1830 
 1831                 retcode = rf_DoAccess(raidPtr, (bp->b_flags & B_READ) ?
 1832                                       RF_IO_TYPE_READ : RF_IO_TYPE_WRITE,
 1833                                       do_async, raid_addr, num_blocks,
 1834                                       bp->b_data, bp, NULL, NULL,
 1835                                       RF_DAG_NONBLOCKING_IO, NULL, NULL, NULL);
 1836 
 1837                 RF_LOCK_MUTEX(raidPtr->mutex);
 1838         }
 1839         RF_UNLOCK_MUTEX(raidPtr->mutex);
 1840 }
 1841 
 1842 /* Invoke an I/O from kernel mode.  Disk queue should be locked upon entry. */
 1843 
 1844 int
 1845 rf_DispatchKernelIO(RF_DiskQueue_t *queue, RF_DiskQueueData_t *req)
 1846 {
 1847         int op = (req->type == RF_IO_TYPE_READ) ? B_READ : B_WRITE;
 1848         struct buf *bp;
 1849         struct raidbuf *raidbp = NULL;
 1850         struct raid_softc *rs;
 1851         int unit;
 1852         /*int s = splbio();*/   /* Want to test this. */
 1853 
 1854         /*
 1855          * XXX along with the vnode, we also need the softc associated with
 1856          * this device...
 1857          */
 1858         req->queue = queue;
 1859 
 1860         unit = queue->raidPtr->raidid;
 1861 
 1862         db1_printf(("DispatchKernelIO unit: %d\n", unit));
 1863 
 1864         if (unit >= numraid) {
 1865                 printf("Invalid unit number: %d %d\n", unit, numraid);
 1866                 panic("Invalid Unit number in rf_DispatchKernelIO");
 1867         }
 1868 
 1869         rs = &raid_softc[unit];
 1870 
 1871         bp = req->bp;
 1872 
 1873 #if 1
 1874         /*
 1875          * XXX When there is a physical disk failure, someone is passing
 1876          * us a buffer that contains old stuff !!  Attempt to deal with
 1877          * this problem without taking a performance hit...
 1878          * (not sure where the real bug is; it's buried in RAIDframe
 1879          * somewhere) :-( GO )
 1880          */
 1881         if (bp->b_flags & B_ERROR) {
 1882                 bp->b_flags &= ~B_ERROR;
 1883         }
 1884         if (bp->b_error!=0) {
 1885                 bp->b_error = 0;
 1886         }
 1887 #endif
 1888 
 1889         raidbp = RAIDGETBUF(rs);
 1890 
 1891         raidbp->rf_flags = 0;   /* XXX not really used anywhere... */
 1892 
 1893         /*
 1894          * Context for raidiodone.
 1895          */
 1896         raidbp->rf_obp = bp;
 1897         raidbp->req = req;
 1898 
 1899         LIST_INIT(&raidbp->rf_buf.b_dep);
 1900 
 1901         switch (req->type) {
 1902         case RF_IO_TYPE_NOP:
 1903                 /* Used primarily to unlock a locked queue. */
 1904 
 1905                 db1_printf(("rf_DispatchKernelIO: NOP to r %d c %d\n",
 1906                     queue->row, queue->col));
 1907 
 1908                 /* XXX need to do something extra here... */
 1909 
 1910                 /*
 1911                  * I'm leaving this in, as I've never actually seen it
 1912                  * used, and I'd like folks to report it... GO
 1913                  */
 1914                 db1_printf(("WAKEUP CALLED\n"));
 1915                 queue->numOutstanding++;
 1916 
 1917                 /* XXX need to glue the original buffer into this ?? */
 1918 
 1919                 rf_KernelWakeupFunc(&raidbp->rf_buf);
 1920                 break;
 1921 
 1922         case RF_IO_TYPE_READ:
 1923         case RF_IO_TYPE_WRITE:
 1924                 if (req->tracerec) {
 1925                         RF_ETIMER_START(req->tracerec->timer);
 1926                 }
 1927 
 1928                 rf_InitBP(&raidbp->rf_buf, queue->rf_cinfo->ci_vp,
 1929                     op | bp->b_flags, queue->rf_cinfo->ci_dev,
 1930                     req->sectorOffset, req->numSector,
 1931                     req->buf, rf_KernelWakeupFunc, (void *)req,
 1932                     queue->raidPtr->logBytesPerSector, req->b_proc);
 1933 
 1934                 if (rf_debugKernelAccess) {
 1935                         db1_printf(("dispatch: bp->b_blkno = %ld\n",
 1936                             (long)bp->b_blkno));
 1937                 }
 1938                 queue->numOutstanding++;
 1939                 queue->last_deq_sector = req->sectorOffset;
 1940 
 1941                 /*
 1942                  * Acc wouldn't have been let in if there were any
 1943                  * pending reqs at any other priority.
 1944                  */
 1945                 queue->curPriority = req->priority;
 1946 
 1947                 db1_printf(("Going for %c to unit %d row %d col %d\n",
 1948                     req->type, unit, queue->row, queue->col));
 1949                 db1_printf(("sector %d count %d (%d bytes) %d\n",
 1950                     (int)req->sectorOffset, (int)req->numSector,
 1951                     (int)(req->numSector << queue->raidPtr->logBytesPerSector),
 1952                     (int)queue->raidPtr->logBytesPerSector));
 1953                 if ((raidbp->rf_buf.b_flags & B_READ) == 0) {
 1954                         raidbp->rf_buf.b_vp->v_numoutput++;
 1955                 }
 1956 
 1957                 VOP_STRATEGY(&raidbp->rf_buf);
 1958                 break;
 1959 
 1960         default:
 1961                 panic("bad req->type in rf_DispatchKernelIO");
 1962         }
 1963         db1_printf(("Exiting from DispatchKernelIO\n"));
 1964         /*splx(s);*/    /* want to test this */
 1965         return (0);
 1966 }
 1967 
 1968 /*
 1969  * This is the callback function associated with a I/O invoked from
 1970  * kernel code.
 1971  */
 1972 void
 1973 rf_KernelWakeupFunc(struct buf *vbp)
 1974 {
 1975         RF_DiskQueueData_t *req = NULL;
 1976         RF_DiskQueue_t *queue;
 1977         struct raidbuf *raidbp = (struct raidbuf *)vbp;
 1978         struct buf *bp;
 1979         struct raid_softc *rs;
 1980         int unit;
 1981         int s;
 1982 
 1983         s = splbio();
 1984         db1_printf(("recovering the request queue:\n"));
 1985         req = raidbp->req;
 1986 
 1987         bp = raidbp->rf_obp;
 1988 
 1989         queue = (RF_DiskQueue_t *)req->queue;
 1990 
 1991         if (raidbp->rf_buf.b_flags & B_ERROR) {
 1992                 bp->b_flags |= B_ERROR;
 1993                 bp->b_error =
 1994                     raidbp->rf_buf.b_error ? raidbp->rf_buf.b_error : EIO;
 1995         }
 1996 
 1997 #if 1
 1998         /* XXX Methinks this could be wrong... */
 1999         bp->b_resid = raidbp->rf_buf.b_resid;
 2000 #endif
 2001 
 2002         if (req->tracerec) {
 2003                 RF_ETIMER_STOP(req->tracerec->timer);
 2004                 RF_ETIMER_EVAL(req->tracerec->timer);
 2005                 RF_LOCK_MUTEX(rf_tracing_mutex);
 2006                 req->tracerec->diskwait_us +=
 2007                     RF_ETIMER_VAL_US(req->tracerec->timer);
 2008                 req->tracerec->phys_io_us +=
 2009                     RF_ETIMER_VAL_US(req->tracerec->timer);
 2010                 req->tracerec->num_phys_ios++;
 2011                 RF_UNLOCK_MUTEX(rf_tracing_mutex);
 2012         }
 2013 
 2014         bp->b_bcount = raidbp->rf_buf.b_bcount; /* XXXX ?? */
 2015 
 2016         unit = queue->raidPtr->raidid;  /* *Much* simpler :-> */
 2017 
 2018         /*
 2019          * XXX Ok, let's get aggressive...  If B_ERROR is set, let's go
 2020          * ballistic, and mark the component as hosed...
 2021          */
 2022         if (bp->b_flags & B_ERROR) {
 2023                 /* Mark the disk as dead but only mark it once... */
 2024                 if (queue->raidPtr->Disks[queue->row][queue->col].status ==
 2025                     rf_ds_optimal) {
 2026                         printf("raid%d: IO Error.  Marking %s as failed.\n",
 2027                             unit,
 2028                             queue->raidPtr->
 2029                             Disks[queue->row][queue->col].devname);
 2030                         queue->raidPtr->Disks[queue->row][queue->col].status =
 2031                             rf_ds_failed;
 2032                         queue->raidPtr->status[queue->row] = rf_rs_degraded;
 2033                         queue->raidPtr->numFailures++;
 2034                         queue->raidPtr->numNewFailures++;
 2035                 } else {
 2036                         /* Disk is already dead... */
 2037                         /* printf("Disk already marked as dead!\n"); */
 2038                 }
 2039         }
 2040 
 2041         rs = &raid_softc[unit];
 2042         RAIDPUTBUF(rs, raidbp);
 2043 
 2044         rf_DiskIOComplete(queue, req, (bp->b_flags & B_ERROR) ? 1 : 0);
 2045         (req->CompleteFunc)(req->argument, (bp->b_flags & B_ERROR) ? 1 : 0);
 2046 
 2047         splx(s);
 2048 }
 2049 
 2050 /*
 2051  * Initialize a buf structure for doing an I/O in the kernel.
 2052  */
 2053 void
 2054 rf_InitBP(
 2055         struct buf       *bp,
 2056         struct vnode     *b_vp,
 2057         unsigned          rw_flag,
 2058         dev_t             dev,
 2059         RF_SectorNum_t    startSect,
 2060         RF_SectorCount_t  numSect,
 2061         caddr_t           buf,
 2062         void            (*cbFunc)(struct buf *),
 2063         void             *cbArg,
 2064         int               logBytesPerSector,
 2065         struct proc      *b_proc
 2066 )
 2067 {
 2068         /*bp->b_flags = B_PHYS | rw_flag;*/
 2069         bp->b_flags = B_CALL | rw_flag; /* XXX need B_PHYS here too ??? */
 2070         bp->b_bcount = numSect << logBytesPerSector;
 2071         bp->b_bufsize = bp->b_bcount;
 2072         bp->b_error = 0;
 2073         bp->b_dev = dev;
 2074         bp->b_data = buf;
 2075         bp->b_blkno = startSect;
 2076         bp->b_resid = bp->b_bcount;     /* XXX is this right !??!?!! */
 2077         if (bp->b_bcount == 0) {
 2078                 panic("bp->b_bcount is zero in rf_InitBP!!");
 2079         }
 2080         bp->b_proc = b_proc;
 2081         bp->b_iodone = cbFunc;
 2082         bp->b_vp = b_vp;
 2083         LIST_INIT(&bp->b_dep);
 2084 }
 2085 
 2086 void
 2087 raidgetdefaultlabel(RF_Raid_t *raidPtr, struct raid_softc *rs,
 2088     struct disklabel *lp)
 2089 {
 2090         db1_printf(("Building a default label...\n"));
 2091         bzero(lp, sizeof(*lp));
 2092 
 2093         /* Fabricate a label... */
 2094         DL_SETDSIZE(lp, raidPtr->totalSectors);
 2095         lp->d_secsize = raidPtr->bytesPerSector;
 2096         lp->d_nsectors = raidPtr->Layout.dataSectorsPerStripe;
 2097         lp->d_ntracks = 4 * raidPtr->numCol;
 2098         lp->d_ncylinders = raidPtr->totalSectors /
 2099             (lp->d_nsectors * lp->d_ntracks);
 2100         lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
 2101 
 2102         strncpy(lp->d_typename, "raid", sizeof(lp->d_typename));
 2103         lp->d_type = DTYPE_RAID;
 2104         strncpy(lp->d_packname, "fictitious", sizeof(lp->d_packname));
 2105         lp->d_rpm = 3600;
 2106         lp->d_flags = 0;
 2107         lp->d_interleave = 1;
 2108         lp->d_version = 1;
 2109 
 2110         DL_SETPOFFSET(&lp->d_partitions[RAW_PART], 0);
 2111         DL_SETPSIZE(&lp->d_partitions[RAW_PART], raidPtr->totalSectors);
 2112         lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED;
 2113         lp->d_npartitions = RAW_PART + 1;
 2114 
 2115         lp->d_magic = DISKMAGIC;
 2116         lp->d_magic2 = DISKMAGIC;
 2117         lp->d_checksum = dkcksum(rs->sc_dkdev.dk_label);
 2118 }
 2119 
 2120 /*
 2121  * Read the disklabel from the raid device.
 2122  * If one is not present, fake one up.
 2123  */
 2124 void
 2125 raidgetdisklabel(dev_t dev, struct disklabel *lp, int spoofonly)
 2126 {
 2127         int unit = DISKUNIT(dev);
 2128         struct raid_softc *rs = &raid_softc[unit];
 2129         char *errstring;
 2130         RF_Raid_t *raidPtr;
 2131         int i;
 2132         struct partition *pp;
 2133 
 2134         db1_printf(("Getting the disklabel...\n"));
 2135 
 2136         bzero(lp, sizeof(*lp));
 2137 
 2138         raidPtr = raidPtrs[unit];
 2139 
 2140         raidgetdefaultlabel(raidPtr, rs, lp);
 2141 
 2142         /*
 2143          * Call the generic disklabel extraction routine.
 2144          */
 2145         errstring = readdisklabel(DISKLABELDEV(dev), raidstrategy, lp,
 2146             spoofonly);
 2147         if (errstring) {
 2148                 /*printf("%s: %s\n", rs->sc_xname, errstring);*/
 2149                 return;
 2150         }
 2151 
 2152         /*
 2153          * Sanity check whether the found disklabel is valid.
 2154          *
 2155          * This is necessary since total size of the raid device
 2156          * may vary when an interleave is changed even though exactly
 2157          * same componets are used, and old disklabel may used
 2158          * if that is found.
 2159          */
 2160 #ifdef  RAIDDEBUG
 2161         if (DL_GETDSIZE(lp) != rs->sc_size)
 2162                 printf("WARNING: %s: "
 2163                     "total sector size in disklabel (%d) != "
 2164                     "the size of raid (%ld)\n", rs->sc_xname,
 2165                     DL_GETDSIZE(lp), (long) rs->sc_size);
 2166 #endif  /* RAIDDEBUG */
 2167         for (i = 0; i < lp->d_npartitions; i++) {
 2168                 pp = &lp->d_partitions[i];
 2169                 if (DL_GETPOFFSET(pp) + DL_GETPSIZE(pp) > rs->sc_size)
 2170                         printf("WARNING: %s: end of partition `%c' "
 2171                             "exceeds the size of raid (%ld)\n",
 2172                             rs->sc_xname, 'a' + i, (long) rs->sc_size);
 2173         }
 2174 }
 2175 
 2176 /*
 2177  * Lookup the provided name in the filesystem.  If the file exists,
 2178  * is a valid block device, and isn't being used by anyone else,
 2179  * set *vpp to the file's vnode.
 2180  * You'll find the original of this in ccd.c
 2181  */
 2182 int
 2183 raidlookup(char *path, struct proc *p, struct vnode **vpp /* result */)
 2184 {
 2185         struct nameidata nd;
 2186         struct vnode *vp;
 2187         struct vattr va;
 2188         int error;
 2189 
 2190         NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, path, p);
 2191         if ((error = vn_open(&nd, FREAD|FWRITE, 0)) != 0) {
 2192 #ifdef  RAIDDEBUG
 2193                 printf("RAIDframe: vn_open returned %d\n", error);
 2194 #endif  /* RAIDDEBUG */
 2195                 return (error);
 2196         }
 2197         vp = nd.ni_vp;
 2198         if (vp->v_usecount > 1) {
 2199                 VOP_UNLOCK(vp, 0, p);
 2200                 (void)vn_close(vp, FREAD|FWRITE, p->p_ucred, p);
 2201                 return (EBUSY);
 2202         }
 2203         if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p)) != 0) {
 2204                 VOP_UNLOCK(vp, 0, p);
 2205                 (void)vn_close(vp, FREAD|FWRITE, p->p_ucred, p);
 2206                 return (error);
 2207         }
 2208         /* XXX: eventually we should handle VREG, too. */
 2209         if (va.va_type != VBLK) {
 2210                 VOP_UNLOCK(vp, 0, p);
 2211                 (void)vn_close(vp, FREAD|FWRITE, p->p_ucred, p);
 2212                 return (ENOTBLK);
 2213         }
 2214         VOP_UNLOCK(vp, 0, p);
 2215         *vpp = vp;
 2216         return (0);
 2217 }
 2218 
 2219 /*
 2220  * Wait interruptibly for an exclusive lock.
 2221  *
 2222  * XXX
 2223  * Several drivers do this; it should be abstracted and made MP-safe.
 2224  * (Hmm... where have we seen this warning before :->  GO )
 2225  */
 2226 int
 2227 raidlock(struct raid_softc *rs)
 2228 {
 2229         int error;
 2230 
 2231         while ((rs->sc_flags & RAIDF_LOCKED) != 0) {
 2232                 rs->sc_flags |= RAIDF_WANTED;
 2233                 if ((error = tsleep(rs, PRIBIO | PCATCH, "raidlck", 0)) != 0)
 2234                         return (error);
 2235         }
 2236         rs->sc_flags |= RAIDF_LOCKED;
 2237         return (0);
 2238 }
 2239 
 2240 /*
 2241  * Unlock and wake up any waiters.
 2242  */
 2243 void
 2244 raidunlock(struct raid_softc *rs)
 2245 {
 2246         rs->sc_flags &= ~RAIDF_LOCKED;
 2247         if ((rs->sc_flags & RAIDF_WANTED) != 0) {
 2248                 rs->sc_flags &= ~RAIDF_WANTED;
 2249                 wakeup(rs);
 2250         }
 2251 }
 2252 
 2253 
 2254 #define RF_COMPONENT_INFO_OFFSET        16384   /* bytes */
 2255 #define RF_COMPONENT_INFO_SIZE           1024   /* bytes */
 2256 
 2257 int
 2258 raidmarkclean(dev_t dev, struct vnode *b_vp, int mod_counter)
 2259 {
 2260         RF_ComponentLabel_t clabel;
 2261         raidread_component_label(dev, b_vp, &clabel);
 2262         clabel.mod_counter = mod_counter;
 2263         clabel.clean = RF_RAID_CLEAN;
 2264         raidwrite_component_label(dev, b_vp, &clabel);
 2265         return(0);
 2266 }
 2267 
 2268 
 2269 int
 2270 raidmarkdirty(dev_t dev, struct vnode *b_vp, int mod_counter)
 2271 {
 2272         RF_ComponentLabel_t clabel;
 2273         raidread_component_label(dev, b_vp, &clabel);
 2274         clabel.mod_counter = mod_counter;
 2275         clabel.clean = RF_RAID_DIRTY;
 2276         raidwrite_component_label(dev, b_vp, &clabel);
 2277         return(0);
 2278 }
 2279 
 2280 /* ARGSUSED */
 2281 int
 2282 raidread_component_label(dev_t dev, struct vnode *b_vp,
 2283     RF_ComponentLabel_t *clabel)
 2284 {
 2285         struct buf *bp;
 2286         int error;
 2287 
 2288         /*
 2289          * XXX should probably ensure that we don't try to do this if
 2290          * someone has changed rf_protected_sectors.
 2291          */
 2292 
 2293         if (b_vp == NULL) {
 2294                 /*
 2295                  * For whatever reason, this component is not valid.
 2296                  * Don't try to read a component label from it.
 2297                  */
 2298                 return(EINVAL);
 2299         }
 2300 
 2301         /* Get a block of the appropriate size... */
 2302         bp = geteblk((int)RF_COMPONENT_INFO_SIZE);
 2303         bp->b_dev = dev;
 2304 
 2305         /* Get our ducks in a row for the read. */
 2306         bp->b_blkno = RF_COMPONENT_INFO_OFFSET / DEV_BSIZE;
 2307         bp->b_bcount = RF_COMPONENT_INFO_SIZE;
 2308         bp->b_flags |= B_READ;
 2309         bp->b_resid = RF_COMPONENT_INFO_SIZE / DEV_BSIZE;
 2310 
 2311         (*bdevsw[major(bp->b_dev)].d_strategy)(bp);
 2312 
 2313         error = biowait(bp);
 2314 
 2315         if (!error) {
 2316                 memcpy(clabel, bp->b_data, sizeof(RF_ComponentLabel_t));
 2317 #if 0
 2318                 rf_print_component_label( clabel );
 2319 #endif
 2320         } else {
 2321                 db1_printf(("Failed to read RAID component label!\n"));
 2322         }
 2323 
 2324         brelse(bp);
 2325         return(error);
 2326 }
 2327 
 2328 /* ARGSUSED */
 2329 int
 2330 raidwrite_component_label(dev_t dev, struct vnode *b_vp,
 2331     RF_ComponentLabel_t *clabel)
 2332 {
 2333         struct buf *bp;
 2334         int error;
 2335 
 2336         /* Get a block of the appropriate size... */
 2337         bp = geteblk((int)RF_COMPONENT_INFO_SIZE);
 2338         bp->b_dev = dev;
 2339 
 2340         /* Get our ducks in a row for the write. */
 2341         bp->b_blkno = RF_COMPONENT_INFO_OFFSET / DEV_BSIZE;
 2342         bp->b_bcount = RF_COMPONENT_INFO_SIZE;
 2343         bp->b_flags |= B_WRITE;
 2344         bp->b_resid = RF_COMPONENT_INFO_SIZE / DEV_BSIZE;
 2345 
 2346         memset(bp->b_data, 0, RF_COMPONENT_INFO_SIZE );
 2347 
 2348         memcpy(bp->b_data, clabel, sizeof(RF_ComponentLabel_t));
 2349 
 2350         (*bdevsw[major(bp->b_dev)].d_strategy)(bp);
 2351         error = biowait(bp);
 2352         brelse(bp);
 2353         if (error) {
 2354                 printf("Failed to write RAID component info!\n");
 2355         }
 2356 
 2357         return(error);
 2358 }
 2359 
 2360 void
 2361 rf_markalldirty(RF_Raid_t *raidPtr)
 2362 {
 2363         RF_ComponentLabel_t clabel;
 2364         int r,c;
 2365 
 2366         raidPtr->mod_counter++;
 2367         for (r = 0; r < raidPtr->numRow; r++) {
 2368                 for (c = 0; c < raidPtr->numCol; c++) {
 2369                         /*
 2370                          * We don't want to touch (at all) a disk that has
 2371                          * failed.
 2372                          */
 2373                         if (!RF_DEAD_DISK(raidPtr->Disks[r][c].status)) {
 2374                                 raidread_component_label(
 2375                                     raidPtr->Disks[r][c].dev,
 2376                                     raidPtr->raid_cinfo[r][c].ci_vp, &clabel);
 2377                                 if (clabel.status == rf_ds_spared) {
 2378                                         /*
 2379                                          * XXX do something special...
 2380                                          * But whatever you do, don't
 2381                                          * try to access it !!!
 2382                                          */
 2383                                 } else {
 2384 #if 0
 2385                                         clabel.status =
 2386                                             raidPtr->Disks[r][c].status;
 2387                                         raidwrite_component_label(
 2388                                             raidPtr->Disks[r][c].dev,
 2389                                             raidPtr->raid_cinfo[r][c].ci_vp,
 2390                                             &clabel);
 2391 #endif
 2392                                         raidmarkdirty(
 2393                                             raidPtr->Disks[r][c].dev,
 2394                                             raidPtr->raid_cinfo[r][c].ci_vp,
 2395                                             raidPtr->mod_counter);
 2396                                 }
 2397                         }
 2398                 }
 2399         }
 2400         /*printf("Component labels marked dirty.\n");*/
 2401 #if 0
 2402         for( c = 0; c < raidPtr->numSpare ; c++) {
 2403                 sparecol = raidPtr->numCol + c;
 2404                 if (raidPtr->Disks[r][sparecol].status == rf_ds_used_spare) {
 2405                         /*
 2406                          * XXX This is where we get fancy and map this spare
 2407                          * into it's correct spot in the array.
 2408                          */
 2409                         /*
 2410                          * We claim this disk is "optimal" if it's
 2411                          * rf_ds_used_spare, as that means it should be
 2412                          * directly substitutable for the disk it replaced.
 2413                          * We note that too...
 2414                          */
 2415 
 2416                         for(i=0;i<raidPtr->numRow;i++) {
 2417                                 for(j=0;j<raidPtr->numCol;j++) {
 2418                                         if ((raidPtr->Disks[i][j].spareRow ==
 2419                                              r) &&
 2420                                             (raidPtr->Disks[i][j].spareCol ==
 2421                                              sparecol)) {
 2422                                                 srow = r;
 2423                                                 scol = sparecol;
 2424                                                 break;
 2425                                         }
 2426                                 }
 2427                         }
 2428 
 2429                         raidread_component_label(
 2430                             raidPtr->Disks[r][sparecol].dev,
 2431                             raidPtr->raid_cinfo[r][sparecol].ci_vp, &clabel);
 2432                         /* Make sure status is noted. */
 2433                         clabel.version = RF_COMPONENT_LABEL_VERSION;
 2434                         clabel.mod_counter = raidPtr->mod_counter;
 2435                         clabel.serial_number = raidPtr->serial_number;
 2436                         clabel.row = srow;
 2437                         clabel.column = scol;
 2438                         clabel.num_rows = raidPtr->numRow;
 2439                         clabel.num_columns = raidPtr->numCol;
 2440                         clabel.clean = RF_RAID_DIRTY;   /* Changed in a bit. */
 2441                         clabel.status = rf_ds_optimal;
 2442                         raidwrite_component_label(
 2443                             raidPtr->Disks[r][sparecol].dev,
 2444                             raidPtr->raid_cinfo[r][sparecol].ci_vp, &clabel);
 2445                         raidmarkclean( raidPtr->Disks[r][sparecol].dev,
 2446                             raidPtr->raid_cinfo[r][sparecol].ci_vp);
 2447                 }
 2448         }
 2449 
 2450 #endif
 2451 }
 2452 
 2453 
 2454 void
 2455 rf_update_component_labels(RF_Raid_t *raidPtr, int final)
 2456 {
 2457         RF_ComponentLabel_t clabel;
 2458         int sparecol;
 2459         int r,c;
 2460         int i,j;
 2461         int srow, scol;
 2462 
 2463         srow = -1;
 2464         scol = -1;
 2465 
 2466         /*
 2467          * XXX should do extra checks to make sure things really are clean,
 2468          * rather than blindly setting the clean bit...
 2469          */
 2470 
 2471         raidPtr->mod_counter++;
 2472 
 2473         for (r = 0; r < raidPtr->numRow; r++) {
 2474                 for (c = 0; c < raidPtr->numCol; c++) {
 2475                         if (raidPtr->Disks[r][c].status == rf_ds_optimal) {
 2476                                 raidread_component_label(
 2477                                         raidPtr->Disks[r][c].dev,
 2478                                         raidPtr->raid_cinfo[r][c].ci_vp,
 2479                                         &clabel);
 2480                                 /* Make sure status is noted. */
 2481                                 clabel.status = rf_ds_optimal;
 2482                                 /* Bump the counter. */
 2483                                 clabel.mod_counter = raidPtr->mod_counter;
 2484 
 2485                                 raidwrite_component_label(
 2486                                         raidPtr->Disks[r][c].dev,
 2487                                         raidPtr->raid_cinfo[r][c].ci_vp,
 2488                                         &clabel);
 2489                                 if (final == RF_FINAL_COMPONENT_UPDATE) {
 2490                                         if (raidPtr->parity_good ==
 2491                                             RF_RAID_CLEAN) {
 2492                                                 raidmarkclean(
 2493                                                     raidPtr->Disks[r][c].dev,
 2494                                                     raidPtr->
 2495                                                     raid_cinfo[r][c].ci_vp,
 2496                                                     raidPtr->mod_counter);
 2497                                         }
 2498                                 }
 2499                         }
 2500                         /* Else we don't touch it... */
 2501                 }
 2502         }
 2503 
 2504         for( c = 0; c < raidPtr->numSpare ; c++) {
 2505                 sparecol = raidPtr->numCol + c;
 2506                 if (raidPtr->Disks[0][sparecol].status == rf_ds_used_spare) {
 2507                         /*
 2508                          * We claim this disk is "optimal" if it's
 2509                          * rf_ds_used_spare, as that means it should be
 2510                          * directly substitutable for the disk it replaced.
 2511                          * We note that too...
 2512                          */
 2513 
 2514                         for(i=0;i<raidPtr->numRow;i++) {
 2515                                 for(j=0;j<raidPtr->numCol;j++) {
 2516                                         if ((raidPtr->Disks[i][j].spareRow ==
 2517                                              0) &&
 2518                                             (raidPtr->Disks[i][j].spareCol ==
 2519                                              sparecol)) {
 2520                                                 srow = i;
 2521                                                 scol = j;
 2522                                                 break;
 2523                                         }
 2524                                 }
 2525                         }
 2526 
 2527                         /* XXX Shouldn't *really* need this... */
 2528                         raidread_component_label(
 2529                             raidPtr->Disks[0][sparecol].dev,
 2530                             raidPtr->raid_cinfo[0][sparecol].ci_vp, &clabel);
 2531                         /* Make sure status is noted. */
 2532 
 2533                         raid_init_component_label(raidPtr, &clabel);
 2534 
 2535                         clabel.mod_counter = raidPtr->mod_counter;
 2536                         clabel.row = srow;
 2537                         clabel.column = scol;
 2538                         clabel.status = rf_ds_optimal;
 2539 
 2540                         raidwrite_component_label(
 2541                             raidPtr->Disks[0][sparecol].dev,
 2542                             raidPtr->raid_cinfo[0][sparecol].ci_vp, &clabel);
 2543                         if (final == RF_FINAL_COMPONENT_UPDATE) {
 2544                                 if (raidPtr->parity_good == RF_RAID_CLEAN) {
 2545                                         raidmarkclean(raidPtr->
 2546                                             Disks[0][sparecol].dev,
 2547                                             raidPtr->
 2548                                             raid_cinfo[0][sparecol].ci_vp,
 2549                                             raidPtr->mod_counter);
 2550                                 }
 2551                         }
 2552                 }
 2553         }
 2554         /*printf("Component labels updated\n");*/
 2555 }
 2556 
 2557 void
 2558 rf_close_component(RF_Raid_t *raidPtr, struct vnode *vp, int auto_configured)
 2559 {
 2560         struct proc *p = curproc;
 2561 
 2562         if (vp != NULL) {
 2563                 if (auto_configured == 1) {
 2564                         /* component was opened by rf_find_raid_components() */
 2565                         VOP_CLOSE(vp, FREAD | FWRITE, NOCRED, p);
 2566                         vrele(vp);
 2567                 } else {
 2568                         /* component was opened by raidlookup() */
 2569                         (void) vn_close(vp, FREAD | FWRITE, p->p_ucred, p);
 2570                 }
 2571         } else {
 2572                 printf("vnode was NULL\n");
 2573         }
 2574 }
 2575 
 2576 void
 2577 rf_UnconfigureVnodes(RF_Raid_t *raidPtr)
 2578 {
 2579         int r,c;
 2580         struct vnode *vp;
 2581         int acd;
 2582 
 2583 
 2584         /* We take this opportunity to close the vnodes like we should... */
 2585 
 2586         for (r = 0; r < raidPtr->numRow; r++) {
 2587                 for (c = 0; c < raidPtr->numCol; c++) {
 2588                         db1_printf(("Closing vnode for row: %d col: %d\n",
 2589                             r, c));
 2590                         vp = raidPtr->raid_cinfo[r][c].ci_vp;
 2591                         acd = raidPtr->Disks[r][c].auto_configured;
 2592                         rf_close_component(raidPtr, vp, acd);
 2593                         raidPtr->raid_cinfo[r][c].ci_vp = NULL;
 2594                         raidPtr->Disks[r][c].auto_configured = 0;
 2595                 }
 2596         }
 2597         for (r = 0; r < raidPtr->numSpare; r++) {
 2598                 db1_printf(("Closing vnode for spare: %d\n", r));
 2599                 vp = raidPtr->raid_cinfo[0][raidPtr->numCol + r].ci_vp;
 2600                 acd = raidPtr->Disks[0][raidPtr->numCol + r].auto_configured;
 2601                 rf_close_component(raidPtr, vp, acd);
 2602                 raidPtr->raid_cinfo[0][raidPtr->numCol + r].ci_vp = NULL;
 2603                 raidPtr->Disks[0][raidPtr->numCol + r].auto_configured = 0;
 2604         }
 2605 }
 2606 
 2607 
 2608 void
 2609 rf_ReconThread(struct rf_recon_req *req)
 2610 {
 2611         int s;
 2612         RF_Raid_t *raidPtr;
 2613 
 2614         s = splbio();
 2615         raidPtr = (RF_Raid_t *) req->raidPtr;
 2616         raidPtr->recon_in_progress = 1;
 2617 
 2618         rf_FailDisk((RF_Raid_t *) req->raidPtr, req->row, req->col,
 2619                     ((req->flags & RF_FDFLAGS_RECON) ? 1 : 0));
 2620 
 2621         /* XXX Get rid of this! we don't need it at all... */
 2622         RF_Free(req, sizeof(*req));
 2623 
 2624         raidPtr->recon_in_progress = 0;
 2625         splx(s);
 2626 
 2627         /* That's all... */
 2628         kthread_exit(0);        /* Does not return. */
 2629 }
 2630 
 2631 void
 2632 rf_RewriteParityThread(RF_Raid_t *raidPtr)
 2633 {
 2634         int retcode;
 2635         int s;
 2636 
 2637         s = splbio();
 2638         raidPtr->parity_rewrite_in_progress = 1;
 2639         retcode = rf_RewriteParity(raidPtr);
 2640         if (retcode) {
 2641                 printf("raid%d: Error re-writing parity!\n",raidPtr->raidid);
 2642         } else {
 2643                 /*
 2644                  * Set the clean bit !  If we shutdown correctly,
 2645                  * the clean bit on each component label will get
 2646                  * set.
 2647                  */
 2648                 raidPtr->parity_good = RF_RAID_CLEAN;
 2649         }
 2650         raidPtr->parity_rewrite_in_progress = 0;
 2651         splx(s);
 2652 
 2653         /* Anyone waiting for us to stop ?  If so, inform them... */
 2654         if (raidPtr->waitShutdown) {
 2655                 wakeup(&raidPtr->parity_rewrite_in_progress);
 2656         }
 2657 
 2658         /* That's all... */
 2659         kthread_exit(0);        /* Does not return. */
 2660 }
 2661 
 2662 
 2663 void
 2664 rf_CopybackThread(RF_Raid_t *raidPtr)
 2665 {
 2666         int s;
 2667 
 2668         s = splbio();
 2669         raidPtr->copyback_in_progress = 1;
 2670         rf_CopybackReconstructedData(raidPtr);
 2671         raidPtr->copyback_in_progress = 0;
 2672         splx(s);
 2673 
 2674         /* That's all... */
 2675         kthread_exit(0);        /* Does not return. */
 2676 }
 2677 
 2678 
 2679 void
 2680 rf_ReconstructInPlaceThread(struct rf_recon_req *req)
 2681 {
 2682         int retcode;
 2683         int s;
 2684         RF_Raid_t *raidPtr;
 2685 
 2686         s = splbio();
 2687         raidPtr = req->raidPtr;
 2688         raidPtr->recon_in_progress = 1;
 2689         retcode = rf_ReconstructInPlace(raidPtr, req->row, req->col);
 2690         RF_Free(req, sizeof(*req));
 2691         raidPtr->recon_in_progress = 0;
 2692         splx(s);
 2693 
 2694         /* That's all... */
 2695         kthread_exit(0);        /* Does not return. */
 2696 }
 2697 
 2698 
 2699 RF_AutoConfig_t *
 2700 rf_find_raid_components(void)
 2701 {
 2702 #ifdef  RAID_AUTOCONFIG
 2703         int major;
 2704         struct vnode *vp;
 2705         struct disklabel label;
 2706         struct device *dv;
 2707         dev_t dev;
 2708         int error;
 2709         int i;
 2710         int good_one;
 2711         RF_ComponentLabel_t *clabel;
 2712         RF_AutoConfig_t *ac;
 2713 #endif  /* RAID_AUTOCONFIG */
 2714         RF_AutoConfig_t *ac_list;
 2715 
 2716 
 2717         /* Initialize the AutoConfig list. */
 2718         ac_list = NULL;
 2719 
 2720 #ifdef  RAID_AUTOCONFIG
 2721         /* We begin by trolling through *all* the devices on the system. */
 2722 
 2723         TAILQ_FOREACH(dv, &alldevs, dv_list) {
 2724 
 2725                 /* We are only interested in disks... */
 2726                 if (dv->dv_class != DV_DISK)
 2727                         continue;
 2728 
 2729                 /* We don't care about floppies... */
 2730                 if (!strcmp(dv->dv_cfdata->cf_driver->cd_name,"fd")) {
 2731                         continue;
 2732                 }
 2733 
 2734                 /*
 2735                  * We need to find the device_name_to_block_device_major
 2736                  * stuff.
 2737                  */
 2738                 major = findblkmajor(dv);
 2739 
 2740                 /* Get a vnode for the raw partition of this disk. */
 2741 
 2742                 dev = MAKEDISKDEV(major, dv->dv_unit, RAW_PART);
 2743                 if (bdevvp(dev, &vp))
 2744                         panic("RAID can't alloc vnode");
 2745 
 2746                 error = VOP_OPEN(vp, FREAD, NOCRED, 0);
 2747 
 2748                 if (error) {
 2749                         /*
 2750                          * "Who cares."  Continue looking
 2751                          * for something that exists.
 2752                          */
 2753                         vput(vp);
 2754                         continue;
 2755                 }
 2756 
 2757                 /* Ok, the disk exists.  Go get the disklabel. */
 2758                 error = VOP_IOCTL(vp, DIOCGDINFO, (caddr_t)&label,
 2759                                   FREAD, NOCRED, 0);
 2760                 if (error) {
 2761                         /*
 2762                          * XXX can't happen - open() would
 2763                          * have errored out (or faked up one).
 2764                          */
 2765                         printf("can't get label for dev %s%c (%d)!?!?\n",
 2766                             dv->dv_xname, 'a' + RAW_PART, error);
 2767                 }
 2768 
 2769                 /*
 2770                  * We don't need this any more.  We'll allocate it again
 2771                  * a little later if we really do...
 2772                  */
 2773                 VOP_CLOSE(vp, FREAD | FWRITE, NOCRED, 0);
 2774                 vrele(vp);
 2775 
 2776                 for (i=0; i < label.d_npartitions; i++) {
 2777                         /*
 2778                          * We only support partitions marked as RAID.
 2779                          * Except on sparc/sparc64 where FS_RAID doesn't
 2780                          * fit in the SUN disklabel and we need to look
 2781                          * into each and every partition !!!
 2782                          */
 2783 #if !defined(__sparc__) && !defined(__sparc64__) && !defined(__sun3__)
 2784                         if (label.d_partitions[i].p_fstype != FS_RAID)
 2785                                 continue;
 2786 #else /* !__sparc__ && !__sparc64__ && !__sun3__ */
 2787                         if (label.d_partitions[i].p_fstype == FS_SWAP ||
 2788                             label.d_partitions[i].p_fstype == FS_UNUSED)
 2789                                 continue;
 2790 #endif /* __sparc__ || __sparc64__ || __sun3__ */
 2791 
 2792                         dev = MAKEDISKDEV(major, dv->dv_unit, i);
 2793                         if (bdevvp(dev, &vp))
 2794                                 panic("RAID can't alloc vnode");
 2795 
 2796                         error = VOP_OPEN(vp, FREAD, NOCRED, 0);
 2797                         if (error) {
 2798                                 /* Whatever... */
 2799                                 vput(vp);
 2800                                 continue;
 2801                         }
 2802 
 2803                         good_one = 0;
 2804 
 2805                         clabel = (RF_ComponentLabel_t *)
 2806                                 malloc(sizeof(RF_ComponentLabel_t), M_RAIDFRAME,
 2807                                     M_NOWAIT);
 2808                         if (clabel == NULL) {
 2809                                 /* XXX CLEANUP HERE. */
 2810                                 printf("RAID auto config: out of memory!\n");
 2811                                 return(NULL); /* XXX probably should panic ? */
 2812                         }
 2813 
 2814                         if (!raidread_component_label(dev, vp, clabel)) {
 2815                                 /* Got the label.  Does it look reasonable ? */
 2816                                 if (rf_reasonable_label(clabel) &&
 2817                                     (clabel->partitionSize <=
 2818                                      DL_GETPSIZE(&label.d_partitions[i]))) {
 2819 #ifdef  RAIDDEBUG
 2820                                         printf("Component on: %s%c: %d\n",
 2821                                             dv->dv_xname, 'a'+i,
 2822                                             DL_GETPSIZE(&label.d_partitions[i]));
 2823                                         rf_print_component_label(clabel);
 2824 #endif  /* RAIDDEBUG */
 2825                                         /*
 2826                                          * If it's reasonable, add it,
 2827                                          * else ignore it.
 2828                                          */
 2829                                         ac = (RF_AutoConfig_t *)
 2830                                                 malloc(sizeof(RF_AutoConfig_t),
 2831                                                     M_RAIDFRAME, M_NOWAIT);
 2832                                         if (ac == NULL) {
 2833                                                 /* XXX should panic ??? */
 2834                                                 return(NULL);
 2835                                         }
 2836 
 2837                                         snprintf(ac->devname,
 2838                                                  sizeof ac->devname, "%s%c",
 2839                                                  dv->dv_xname, 'a'+i);
 2840                                         ac->dev = dev;
 2841                                         ac->vp = vp;
 2842                                         ac->clabel = clabel;
 2843                                         ac->next = ac_list;
 2844                                         ac_list = ac;
 2845                                         good_one = 1;
 2846                                 }
 2847                         }
 2848                         if (!good_one) {
 2849                                 /* Cleanup. */
 2850                                 free(clabel, M_RAIDFRAME);
 2851                                 VOP_CLOSE(vp, FREAD | FWRITE, NOCRED, 0);
 2852                                 vrele(vp);
 2853                         }
 2854                 }
 2855         }
 2856 #endif  /* RAID_AUTOCONFIG */
 2857         return(ac_list);
 2858 }
 2859 
 2860 #ifdef  RAID_AUTOCONFIG
 2861 int
 2862 rf_reasonable_label(RF_ComponentLabel_t *clabel)
 2863 {
 2864 
 2865         if (((clabel->version==RF_COMPONENT_LABEL_VERSION_1) ||
 2866              (clabel->version==RF_COMPONENT_LABEL_VERSION)) &&
 2867             ((clabel->clean == RF_RAID_CLEAN) ||
 2868              (clabel->clean == RF_RAID_DIRTY)) &&
 2869             clabel->row >=0 &&
 2870             clabel->column >= 0 &&
 2871             clabel->num_rows > 0 &&
 2872             clabel->num_columns > 0 &&
 2873             clabel->row < clabel->num_rows &&
 2874             clabel->column < clabel->num_columns &&
 2875             clabel->blockSize > 0 &&
 2876             clabel->numBlocks > 0) {
 2877                 /* Label looks reasonable enough... */
 2878                 return(1);
 2879         }
 2880         return(0);
 2881 }
 2882 #endif  /* RAID_AUTOCONFIG */
 2883 
 2884 void
 2885 rf_print_component_label(RF_ComponentLabel_t *clabel)
 2886 {
 2887         printf("   Row: %d Column: %d Num Rows: %d Num Columns: %d\n",
 2888             clabel->row, clabel->column, clabel->num_rows, clabel->num_columns);
 2889         printf("   Version: %d Serial Number: %d Mod Counter: %d\n",
 2890             clabel->version, clabel->serial_number, clabel->mod_counter);
 2891         printf("   Clean: %s Status: %d\n", clabel->clean ? "Yes" : "No",
 2892             clabel->status );
 2893         printf("   sectPerSU: %d SUsPerPU: %d SUsPerRU: %d\n",
 2894             clabel->sectPerSU, clabel->SUsPerPU, clabel->SUsPerRU);
 2895         printf("   RAID Level: %c  blocksize: %d numBlocks: %d\n",
 2896             (char) clabel->parityConfig, clabel->blockSize, clabel->numBlocks);
 2897         printf("   Autoconfig: %s\n", clabel->autoconfigure ? "Yes" : "No" );
 2898         printf("   Contains root partition: %s\n", clabel->root_partition ?
 2899             "Yes" : "No" );
 2900         printf("   Last configured as: raid%d\n", clabel->last_unit );
 2901 #if 0
 2902         printf("   Config order: %d\n", clabel->config_order);
 2903 #endif
 2904 }
 2905 
 2906 RF_ConfigSet_t *
 2907 rf_create_auto_sets(RF_AutoConfig_t *ac_list)
 2908 {
 2909         RF_AutoConfig_t *ac;
 2910         RF_ConfigSet_t *config_sets;
 2911         RF_ConfigSet_t *cset;
 2912         RF_AutoConfig_t *ac_next;
 2913 
 2914 
 2915         config_sets = NULL;
 2916 
 2917         /*
 2918          * Go through the AutoConfig list, and figure out which components
 2919          * belong to what sets.
 2920          */
 2921         ac = ac_list;
 2922         while(ac!=NULL) {
 2923                 /*
 2924                  * We're going to putz with ac->next, so save it here
 2925                  * for use at the end of the loop.
 2926                  */
 2927                 ac_next = ac->next;
 2928 
 2929                 if (config_sets == NULL) {
 2930                         /* We will need at least this one... */
 2931                         config_sets = (RF_ConfigSet_t *)
 2932                                 malloc(sizeof(RF_ConfigSet_t), M_RAIDFRAME,
 2933                                     M_NOWAIT);
 2934                         if (config_sets == NULL) {
 2935                                 panic("rf_create_auto_sets: No memory!");
 2936                         }
 2937                         /* This one is easy :) */
 2938                         config_sets->ac = ac;
 2939                         config_sets->next = NULL;
 2940                         config_sets->rootable = 0;
 2941                         ac->next = NULL;
 2942                 } else {
 2943                         /* Which set does this component fit into ? */
 2944                         cset = config_sets;
 2945                         while(cset!=NULL) {
 2946                                 if (rf_does_it_fit(cset, ac)) {
 2947                                         /* Looks like it matches... */
 2948                                         ac->next = cset->ac;
 2949                                         cset->ac = ac;
 2950                                         break;
 2951                                 }
 2952                                 cset = cset->next;
 2953                         }
 2954                         if (cset==NULL) {
 2955                                 /* Didn't find a match above... new set... */
 2956                                 cset = (RF_ConfigSet_t *)
 2957                                         malloc(sizeof(RF_ConfigSet_t),
 2958                                             M_RAIDFRAME, M_NOWAIT);
 2959                                 if (cset == NULL) {
 2960                                         panic("rf_create_auto_sets: No memory!");
 2961                                 }
 2962                                 cset->ac = ac;
 2963                                 ac->next = NULL;
 2964                                 cset->next = config_sets;
 2965                                 cset->rootable = 0;
 2966                                 config_sets = cset;
 2967                         }
 2968                 }
 2969                 ac = ac_next;
 2970         }
 2971 
 2972 
 2973         return(config_sets);
 2974 }
 2975 
 2976 int
 2977 rf_does_it_fit(RF_ConfigSet_t *cset, RF_AutoConfig_t *ac)
 2978 {
 2979         RF_ComponentLabel_t *clabel1, *clabel2;
 2980 
 2981         /*
 2982          * If this one matches the *first* one in the set, that's good
 2983          * enough, since the other members of the set would have been
 2984          * through here too...
 2985          */
 2986         /*
 2987          * Note that we are not checking partitionSize here...
 2988          *
 2989          * Note that we are also not checking the mod_counters here.
 2990          * If everything else matches except the mod_counter, that's
 2991          * good enough for this test.  We will deal with the mod_counters
 2992          * a little later in the autoconfiguration process.
 2993          *
 2994          *  (clabel1->mod_counter == clabel2->mod_counter) &&
 2995          *
 2996          * The reason we don't check for this is that failed disks
 2997          * will have lower modification counts.  If those disks are
 2998          * not added to the set they used to belong to, then they will
 2999          * form their own set, which may result in 2 different sets,
 3000          * for example, competing to be configured at raid0, and
 3001          * perhaps competing to be the root filesystem set.  If the
 3002          * wrong ones get configured, or both attempt to become /,
 3003          * weird behaviour and or serious lossage will occur.  Thus we
 3004          * need to bring them into the fold here, and kick them out at
 3005          * a later point.
 3006          */
 3007 
 3008         clabel1 = cset->ac->clabel;
 3009         clabel2 = ac->clabel;
 3010         if ((clabel1->version == clabel2->version) &&
 3011             (clabel1->serial_number == clabel2->serial_number) &&
 3012             (clabel1->num_rows == clabel2->num_rows) &&
 3013             (clabel1->num_columns == clabel2->num_columns) &&
 3014             (clabel1->sectPerSU == clabel2->sectPerSU) &&
 3015             (clabel1->SUsPerPU == clabel2->SUsPerPU) &&
 3016             (clabel1->SUsPerRU == clabel2->SUsPerRU) &&
 3017             (clabel1->parityConfig == clabel2->parityConfig) &&
 3018             (clabel1->maxOutstanding == clabel2->maxOutstanding) &&
 3019             (clabel1->blockSize == clabel2->blockSize) &&
 3020             (clabel1->numBlocks == clabel2->numBlocks) &&
 3021             (clabel1->autoconfigure == clabel2->autoconfigure) &&
 3022             (clabel1->root_partition == clabel2->root_partition) &&
 3023             (clabel1->last_unit == clabel2->last_unit) &&
 3024             (clabel1->config_order == clabel2->config_order)) {
 3025                 /* If it get's here, it almost *has* to be a match. */
 3026         } else {
 3027                 /* It's not consistent with somebody in the set...  Punt. */
 3028                 return(0);
 3029         }
 3030         /* All was fine.. It must fit... */
 3031         return(1);
 3032 }
 3033 
 3034 int
 3035 rf_have_enough_components(RF_ConfigSet_t *cset)
 3036 {
 3037         RF_AutoConfig_t *ac;
 3038         RF_AutoConfig_t *auto_config;
 3039         RF_ComponentLabel_t *clabel;
 3040         int r,c;
 3041         int num_rows;
 3042         int num_cols;
 3043         int num_missing;
 3044         int mod_counter;
 3045         int mod_counter_found;
 3046         int even_pair_failed;
 3047         char parity_type;
 3048 
 3049 
 3050         /*
 3051          * Check to see that we have enough 'live' components
 3052          * of this set.  If so, we can configure it if necessary.
 3053          */
 3054 
 3055         num_rows = cset->ac->clabel->num_rows;
 3056         num_cols = cset->ac->clabel->num_columns;
 3057         parity_type = cset->ac->clabel->parityConfig;
 3058 
 3059         /* XXX Check for duplicate components !?!?!? */
 3060 
 3061         /* Determine what the mod_counter is supposed to be for this set. */
 3062 
 3063         mod_counter_found = 0;
 3064         mod_counter = 0;
 3065         ac = cset->ac;
 3066         while(ac!=NULL) {
 3067                 if (mod_counter_found==0) {
 3068                         mod_counter = ac->clabel->mod_counter;
 3069                         mod_counter_found = 1;
 3070                 } else {
 3071                         if (ac->clabel->mod_counter > mod_counter) {
 3072                                 mod_counter = ac->clabel->mod_counter;
 3073                         }
 3074                 }
 3075                 ac = ac->next;
 3076         }
 3077 
 3078         num_missing = 0;
 3079         auto_config = cset->ac;
 3080 
 3081         for(r=0; r<num_rows; r++) {
 3082                 even_pair_failed = 0;
 3083                 for(c=0; c<num_cols; c++) {
 3084                         ac = auto_config;
 3085                         while(ac!=NULL) {
 3086                                 if ((ac->clabel->row == r) &&
 3087                                     (ac->clabel->column == c) &&
 3088                                     (ac->clabel->mod_counter == mod_counter)) {
 3089                                         /* It's this one... */
 3090 #ifdef  RAIDDEBUG
 3091                                         printf("Found: %s at %d,%d\n",
 3092                                             ac->devname,r,c);
 3093 #endif  /* RAIDDEBUG */
 3094                                         break;
 3095                                 }
 3096                                 ac=ac->next;
 3097                         }
 3098                         if (ac==NULL) {
 3099                                 /* Didn't find one here! */
 3100                                 /*
 3101                                  * Special case for RAID 1, especially
 3102                                  * where there are more than 2
 3103                                  * components (where RAIDframe treats
 3104                                  * things a little differently :( )
 3105                                  */
 3106                                 if (parity_type == '1') {
 3107                                         if (c%2 == 0) { /* Even component. */
 3108                                                 even_pair_failed = 1;
 3109                                         } else {        /*
 3110                                                          * Odd component.
 3111                                                          * If we're failed,
 3112                                                          * and so is the even
 3113                                                          * component, it's
 3114                                                          * "Good Night, Charlie"
 3115                                                          */
 3116                                                 if (even_pair_failed == 1) {
 3117                                                         return(0);
 3118                                                 }
 3119                                         }
 3120                                 } else {
 3121                                         /* Normal accounting. */
 3122                                         num_missing++;
 3123                                 }
 3124                         }
 3125                         if ((parity_type == '1') && (c%2 == 1)) {
 3126                                 /*
 3127                                  * Just did an even component, and we didn't
 3128                                  * bail... Reset the even_pair_failed flag,
 3129                                  * and go on to the next component...
 3130                                  */
 3131                                 even_pair_failed = 0;
 3132                         }
 3133                 }
 3134         }
 3135 
 3136         clabel = cset->ac->clabel;
 3137 
 3138         if (((clabel->parityConfig == '0') && (num_missing > 0)) ||
 3139             ((clabel->parityConfig == '4') && (num_missing > 1)) ||
 3140             ((clabel->parityConfig == '5') && (num_missing > 1))) {
 3141                 /* XXX This needs to be made *much* more general. */
 3142                 /* Too many failures. */
 3143                 return(0);
 3144         }
 3145         /*
 3146          * Otherwise, all is well, and we've got enough to take a kick
 3147          * at autoconfiguring this set.
 3148          */
 3149         return(1);
 3150 }
 3151 
 3152 void
 3153 rf_create_configuration(RF_AutoConfig_t *ac, RF_Config_t *config,
 3154     RF_Raid_t *raidPtr)
 3155 {
 3156         RF_ComponentLabel_t *clabel;
 3157         int i;
 3158 
 3159         clabel = ac->clabel;
 3160 
 3161         /* 1. Fill in the common stuff. */
 3162         config->numRow = clabel->num_rows;
 3163         config->numCol = clabel->num_columns;
 3164         config->numSpare = 0;   /* XXX Should this be set here ? */
 3165         config->sectPerSU = clabel->sectPerSU;
 3166         config->SUsPerPU = clabel->SUsPerPU;
 3167         config->SUsPerRU = clabel->SUsPerRU;
 3168         config->parityConfig = clabel->parityConfig;
 3169         /* XXX... */
 3170         strlcpy(config->diskQueueType,"fifo", sizeof config->diskQueueType);
 3171         config->maxOutstandingDiskReqs = clabel->maxOutstanding;
 3172         config->layoutSpecificSize = 0; /* XXX ?? */
 3173 
 3174         while(ac!=NULL) {
 3175                 /*
 3176                  * row/col values will be in range due to the checks
 3177                  * in reasonable_label().
 3178                  */
 3179                 strlcpy(config->devnames[ac->clabel->row][ac->clabel->column],
 3180                     ac->devname,
 3181                     sizeof config->devnames[ac->clabel->row][ac->clabel->column]);
 3182                 ac = ac->next;
 3183         }
 3184 
 3185         for(i=0;i<RF_MAXDBGV;i++) {
 3186                 config->debugVars[i][0] = NULL;
 3187         }
 3188 
 3189 #ifdef  RAID_DEBUG_ALL
 3190 
 3191 #ifdef  RF_DBG_OPTION
 3192 #undef  RF_DBG_OPTION
 3193 #endif  /* RF_DBG_OPTION */
 3194 
 3195 #ifdef  __STDC__
 3196 #define RF_DBG_OPTION(_option_,_val_)   do {                            \
 3197         snprintf(&(config->debugVars[i++][0]), 50, "%s %ld",            \
 3198             #_option_, _val_);                                          \
 3199 } while (0)
 3200 #else   /* __STDC__ */
 3201 #define RF_DBG_OPTION(_option_,_val_)   do {                            \
 3202         snprintf(&(config->debugVars[i++][0]), 50, "%s %ld",            \
 3203             "/**/_option_/**/", _val_);                                 \
 3204 } while (0)
 3205 #endif  /* __STDC__ */
 3206 
 3207         i = 0;
 3208 
 3209 /*      RF_DBG_OPTION(accessDebug, 0);                                  */
 3210 /*      RF_DBG_OPTION(accessTraceBufSize, 0);                           */
 3211         RF_DBG_OPTION(cscanDebug, 1);           /* Debug CSCAN sorting. */
 3212         RF_DBG_OPTION(dagDebug, 1);
 3213 /*      RF_DBG_OPTION(debugPrintUseBuffer, 0);                          */
 3214         RF_DBG_OPTION(degDagDebug, 1);
 3215         RF_DBG_OPTION(disableAsyncAccs, 1);
 3216         RF_DBG_OPTION(diskDebug, 1);
 3217         RF_DBG_OPTION(enableAtomicRMW, 0);
 3218                 /*
 3219                  * This debug variable enables locking of the
 3220                  * disk arm during small-write operations.
 3221                  * Setting this variable to anything other than
 3222                  * 0 will result in deadlock.  (wvcii)
 3223                  */
 3224         RF_DBG_OPTION(engineDebug, 1);
 3225         RF_DBG_OPTION(fifoDebug, 1);            /* Debug fifo queueing. */
 3226 /*      RF_DBG_OPTION(floatingRbufDebug, 1);                            */
 3227 /*      RF_DBG_OPTION(forceHeadSepLimit, -1);                           */
 3228 /*      RF_DBG_OPTION(forceNumFloatingReconBufs, -1);                   */
 3229                 /*
 3230                  * Wire down the number of extra recon buffers
 3231                  * to use.
 3232                  */
 3233 /*      RF_DBG_OPTION(keepAccTotals, 1);                                */
 3234                 /* Turn on keep_acc_totals. */
 3235         RF_DBG_OPTION(lockTableSize, RF_DEFAULT_LOCK_TABLE_SIZE);
 3236         RF_DBG_OPTION(mapDebug, 1);
 3237         RF_DBG_OPTION(maxNumTraces, -1);
 3238 
 3239 /*      RF_DBG_OPTION(memChunkDebug, 1);                                */
 3240 /*      RF_DBG_OPTION(memDebug, 1);                                     */
 3241 /*      RF_DBG_OPTION(memDebugAddress, 1);                              */
 3242 /*      RF_DBG_OPTION(numBufsToAccumulate, 1);                          */
 3243                 /*
 3244                  * Number of buffers to accumulate before
 3245                  * doing XOR.
 3246                  */
 3247         RF_DBG_OPTION(prReconSched, 0);
 3248         RF_DBG_OPTION(printDAGsDebug, 1);
 3249         RF_DBG_OPTION(printStatesDebug, 1);
 3250         RF_DBG_OPTION(protectedSectors, 64L);
 3251                 /*
 3252                  * Number of sectors at start of disk to exclude
 3253                  * from RAID address space.
 3254                  */
 3255         RF_DBG_OPTION(pssDebug, 1);
 3256         RF_DBG_OPTION(queueDebug, 1);
 3257         RF_DBG_OPTION(quiesceDebug, 1);
 3258         RF_DBG_OPTION(raidSectorOffset, 0);
 3259                 /*
 3260                  * Value added to all incoming sectors to debug
 3261                  * alignment problems.
 3262                  */
 3263         RF_DBG_OPTION(reconDebug, 1);
 3264         RF_DBG_OPTION(reconbufferDebug, 1);
 3265         RF_DBG_OPTION(scanDebug, 1);            /* Debug SCAN sorting.  */
 3266         RF_DBG_OPTION(showXorCallCounts, 0);
 3267                 /* Show n-way Xor call counts. */
 3268         RF_DBG_OPTION(shutdownDebug, 1);        /* Show shutdown calls. */
 3269         RF_DBG_OPTION(sizePercentage, 100);
 3270         RF_DBG_OPTION(sstfDebug, 1);
 3271                 /* Turn on debugging info for sstf queueing. */
 3272         RF_DBG_OPTION(stripeLockDebug, 1);
 3273         RF_DBG_OPTION(suppressLocksAndLargeWrites, 0);
 3274         RF_DBG_OPTION(suppressTraceDelays, 0);
 3275         RF_DBG_OPTION(useMemChunks, 1);
 3276         RF_DBG_OPTION(validateDAGDebug, 1);
 3277         RF_DBG_OPTION(validateVisitedDebug, 1);
 3278                 /* XXX turn to zero by default ? */
 3279         RF_DBG_OPTION(verifyParityDebug, 1);
 3280         RF_DBG_OPTION(debugKernelAccess, 1);
 3281                 /* DoAccessKernel debugging. */
 3282 
 3283 #if RF_INCLUDE_PARITYLOGGING > 0
 3284         RF_DBG_OPTION(forceParityLogReint, 0);
 3285         RF_DBG_OPTION(numParityRegions, 0);
 3286                 /* Number of regions in the array. */
 3287         RF_DBG_OPTION(numReintegrationThreads, 1);
 3288         RF_DBG_OPTION(parityLogDebug, 1);
 3289                 /* If nonzero, enables debugging of parity logging. */
 3290         RF_DBG_OPTION(totalInCoreLogCapacity, 1024 * 1024);
 3291                 /* Target bytes available for in-core logs. */
 3292 #endif  /* RF_INCLUDE_PARITYLOGGING > 0 */
 3293 
 3294 #endif  /* RAID_DEBUG_ALL */
 3295 }
 3296 
 3297 int
 3298 rf_set_autoconfig(RF_Raid_t *raidPtr, int new_value)
 3299 {
 3300         RF_ComponentLabel_t clabel;
 3301         struct vnode *vp;
 3302         dev_t dev;
 3303         int row, column;
 3304 
 3305         raidPtr->autoconfigure = new_value;
 3306         for(row=0; row<raidPtr->numRow; row++) {
 3307                 for(column=0; column<raidPtr->numCol; column++) {
 3308                         if (raidPtr->Disks[row][column].status ==
 3309                             rf_ds_optimal) {
 3310                                 dev = raidPtr->Disks[row][column].dev;
 3311                                 vp = raidPtr->raid_cinfo[row][column].ci_vp;
 3312                                 raidread_component_label(dev, vp, &clabel);
 3313                                 clabel.autoconfigure = new_value;
 3314                                 raidwrite_component_label(dev, vp, &clabel);
 3315                         }
 3316                 }
 3317         }
 3318         return(new_value);
 3319 }
 3320 
 3321 int
 3322 rf_set_rootpartition(RF_Raid_t *raidPtr, int new_value)
 3323 {
 3324         RF_ComponentLabel_t clabel;
 3325         struct vnode *vp;
 3326         dev_t dev;
 3327         int row, column;
 3328 
 3329         raidPtr->root_partition = new_value;
 3330         for(row=0; row<raidPtr->numRow; row++) {
 3331                 for(column=0; column<raidPtr->numCol; column++) {
 3332                         if (raidPtr->Disks[row][column].status ==
 3333                             rf_ds_optimal) {
 3334                                 dev = raidPtr->Disks[row][column].dev;
 3335                                 vp = raidPtr->raid_cinfo[row][column].ci_vp;
 3336                                 raidread_component_label(dev, vp, &clabel);
 3337                                 clabel.root_partition = new_value;
 3338                                 raidwrite_component_label(dev, vp, &clabel);
 3339                         }
 3340                 }
 3341         }
 3342         return(new_value);
 3343 }
 3344 
 3345 void
 3346 rf_release_all_vps(RF_ConfigSet_t *cset)
 3347 {
 3348         RF_AutoConfig_t *ac;
 3349 
 3350         ac = cset->ac;
 3351         while(ac!=NULL) {
 3352                 /* Close the vp, and give it back. */
 3353                 if (ac->vp) {
 3354                         VOP_CLOSE(ac->vp, FREAD, NOCRED, 0);
 3355                         vrele(ac->vp);
 3356                         ac->vp = NULL;
 3357                 }
 3358                 ac = ac->next;
 3359         }
 3360 }
 3361 
 3362 
 3363 void
 3364 rf_cleanup_config_set(RF_ConfigSet_t *cset)
 3365 {
 3366         RF_AutoConfig_t *ac;
 3367         RF_AutoConfig_t *next_ac;
 3368 
 3369         ac = cset->ac;
 3370         while(ac!=NULL) {
 3371                 next_ac = ac->next;
 3372                 /* Nuke the label. */
 3373                 free(ac->clabel, M_RAIDFRAME);
 3374                 /* Cleanup the config structure. */
 3375                 free(ac, M_RAIDFRAME);
 3376                 /* "next..." */
 3377                 ac = next_ac;
 3378         }
 3379         /* And, finally, nuke the config set. */
 3380         free(cset, M_RAIDFRAME);
 3381 }
 3382 
 3383 
 3384 void
 3385 raid_init_component_label(RF_Raid_t *raidPtr, RF_ComponentLabel_t *clabel)
 3386 {
 3387         /* Current version number. */
 3388         clabel->version = RF_COMPONENT_LABEL_VERSION;
 3389         clabel->serial_number = raidPtr->serial_number;
 3390         clabel->mod_counter = raidPtr->mod_counter;
 3391         clabel->num_rows = raidPtr->numRow;
 3392         clabel->num_columns = raidPtr->numCol;
 3393         clabel->clean = RF_RAID_DIRTY;  /* Not clean. */
 3394         clabel->status = rf_ds_optimal; /* "It's good !" */
 3395 
 3396         clabel->sectPerSU = raidPtr->Layout.sectorsPerStripeUnit;
 3397         clabel->SUsPerPU = raidPtr->Layout.SUsPerPU;
 3398         clabel->SUsPerRU = raidPtr->Layout.SUsPerRU;
 3399 
 3400         clabel->blockSize = raidPtr->bytesPerSector;
 3401         clabel->numBlocks = raidPtr->sectorsPerDisk;
 3402 
 3403         /* XXX Not portable. */
 3404         clabel->parityConfig = raidPtr->Layout.map->parityConfig;
 3405         clabel->maxOutstanding = raidPtr->maxOutstanding;
 3406         clabel->autoconfigure = raidPtr->autoconfigure;
 3407         clabel->root_partition = raidPtr->root_partition;
 3408         clabel->last_unit = raidPtr->raidid;
 3409         clabel->config_order = raidPtr->config_order;
 3410 }
 3411 
 3412 int
 3413 rf_auto_config_set(RF_ConfigSet_t *cset, int *unit)
 3414 {
 3415         RF_Raid_t *raidPtr;
 3416         RF_Config_t *config;
 3417         int raidID;
 3418         int retcode;
 3419 
 3420         db1_printf(("RAID autoconfigure\n"));
 3421 
 3422         retcode = 0;
 3423         *unit = -1;
 3424 
 3425         /* 1. Create a config structure. */
 3426 
 3427         config = (RF_Config_t *)malloc(sizeof(RF_Config_t), M_RAIDFRAME,
 3428             M_NOWAIT);
 3429         if (config==NULL) {
 3430                 printf("Out of mem!?!?\n");
 3431                                 /* XXX Do something more intelligent here. */
 3432                 return(1);
 3433         }
 3434 
 3435         memset(config, 0, sizeof(RF_Config_t));
 3436 
 3437         /* XXX raidID needs to be set correctly... */
 3438 
 3439         /*
 3440          * 2. Figure out what RAID ID this one is supposed to live at.
 3441          * See if we can get the same RAID dev that it was configured
 3442          * on last time...
 3443          */
 3444 
 3445         raidID = cset->ac->clabel->last_unit;
 3446         if ((raidID < 0) || (raidID >= numraid)) {
 3447                 /* Let's not wander off into lala land. */
 3448                 raidID = numraid - 1;
 3449         }
 3450         if (raidPtrs[raidID]->valid != 0) {
 3451 
 3452                 /*
 3453                  * Nope...  Go looking for an alternative...
 3454                  * Start high so we don't immediately use raid0 if that's
 3455                  * not taken.
 3456                  */
 3457 
 3458                 for(raidID = numraid - 1; raidID >= 0; raidID--) {
 3459                         if (raidPtrs[raidID]->valid == 0) {
 3460                                 /* We can use this one ! */
 3461                                 break;
 3462                         }
 3463                 }
 3464         }
 3465 
 3466         if (raidID < 0) {
 3467                 /* Punt... */
 3468                 printf("Unable to auto configure this set!\n");
 3469                 printf("(Out of RAID devs!)\n");
 3470                 return(1);
 3471         }
 3472         raidPtr = raidPtrs[raidID];
 3473 
 3474         /* XXX All this stuff should be done SOMEWHERE ELSE ! */
 3475         raidPtr->raidid = raidID;
 3476         raidPtr->openings = RAIDOUTSTANDING;
 3477 
 3478         /* 3. Build the configuration structure. */
 3479         rf_create_configuration(cset->ac, config, raidPtr);
 3480 
 3481         /* 4. Do the configuration. */
 3482         retcode = rf_Configure(raidPtr, config, cset->ac);
 3483 
 3484         if (retcode == 0) {
 3485 
 3486                 raidinit(raidPtrs[raidID]);
 3487 
 3488                 rf_markalldirty(raidPtrs[raidID]);
 3489                 raidPtrs[raidID]->autoconfigure = 1; /* XXX Do this here ? */
 3490                 if (cset->ac->clabel->root_partition==1) {
 3491                         /*
 3492                          * Everything configured just fine.  Make a note
 3493                          * that this set is eligible to be root.
 3494                          */
 3495                         cset->rootable = 1;
 3496                         /* XXX Do this here ? */
 3497                         raidPtrs[raidID]->root_partition = 1;
 3498                 }
 3499         }
 3500 
 3501         printf(": (%s) total number of sectors is %lu (%lu MB)%s\n",
 3502             (raidPtrs[raidID]->Layout).map->configName,
 3503             (unsigned long) raidPtrs[raidID]->totalSectors,
 3504             (unsigned long) (raidPtrs[raidID]->totalSectors / 1024 *
 3505             (1 << raidPtrs[raidID]->logBytesPerSector) / 1024),
 3506             raidPtrs[raidID]->root_partition ? " as root" : "");
 3507 
 3508         /* 5. Cleanup. */
 3509         free(config, M_RAIDFRAME);
 3510 
 3511         *unit = raidID;
 3512         return(retcode);
 3513 }
 3514 
 3515 void
 3516 rf_disk_unbusy(RF_RaidAccessDesc_t *desc)
 3517 {
 3518         struct buf *bp;
 3519 
 3520         bp = (struct buf *)desc->bp;
 3521         disk_unbusy(&raid_softc[desc->raidPtr->raidid].sc_dkdev,
 3522                             (bp->b_bcount - bp->b_resid),
 3523                             (bp->b_flags & B_READ));
 3524 }

/* [<][>][^][v][top][bottom][index][help] */