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