rf_netbsdkintf.c revision 1.100 1 /* $NetBSD: rf_netbsdkintf.c,v 1.100 2000/11/20 08:24:24 chs 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_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 brelse(bp);
2196 return(error);
2197 }
2198 /* ARGSUSED */
2199 int
2200 raidwrite_component_label(dev, b_vp, clabel)
2201 dev_t dev;
2202 struct vnode *b_vp;
2203 RF_ComponentLabel_t *clabel;
2204 {
2205 struct buf *bp;
2206 int error;
2207
2208 /* get a block of the appropriate size... */
2209 bp = geteblk((int)RF_COMPONENT_INFO_SIZE);
2210 bp->b_dev = dev;
2211
2212 /* get our ducks in a row for the write */
2213 bp->b_blkno = RF_COMPONENT_INFO_OFFSET / DEV_BSIZE;
2214 bp->b_bcount = RF_COMPONENT_INFO_SIZE;
2215 bp->b_flags |= B_WRITE;
2216 bp->b_resid = RF_COMPONENT_INFO_SIZE / DEV_BSIZE;
2217
2218 memset(bp->b_data, 0, RF_COMPONENT_INFO_SIZE );
2219
2220 memcpy(bp->b_data, clabel, sizeof(RF_ComponentLabel_t));
2221
2222 (*bdevsw[major(bp->b_dev)].d_strategy)(bp);
2223 error = biowait(bp);
2224 brelse(bp);
2225 if (error) {
2226 #if 1
2227 printf("Failed to write RAID component info!\n");
2228 #endif
2229 }
2230
2231 return(error);
2232 }
2233
2234 void
2235 rf_markalldirty(raidPtr)
2236 RF_Raid_t *raidPtr;
2237 {
2238 RF_ComponentLabel_t clabel;
2239 int r,c;
2240
2241 raidPtr->mod_counter++;
2242 for (r = 0; r < raidPtr->numRow; r++) {
2243 for (c = 0; c < raidPtr->numCol; c++) {
2244 /* we don't want to touch (at all) a disk that has
2245 failed */
2246 if (!RF_DEAD_DISK(raidPtr->Disks[r][c].status)) {
2247 raidread_component_label(
2248 raidPtr->Disks[r][c].dev,
2249 raidPtr->raid_cinfo[r][c].ci_vp,
2250 &clabel);
2251 if (clabel.status == rf_ds_spared) {
2252 /* XXX do something special...
2253 but whatever you do, don't
2254 try to access it!! */
2255 } else {
2256 #if 0
2257 clabel.status =
2258 raidPtr->Disks[r][c].status;
2259 raidwrite_component_label(
2260 raidPtr->Disks[r][c].dev,
2261 raidPtr->raid_cinfo[r][c].ci_vp,
2262 &clabel);
2263 #endif
2264 raidmarkdirty(
2265 raidPtr->Disks[r][c].dev,
2266 raidPtr->raid_cinfo[r][c].ci_vp,
2267 raidPtr->mod_counter);
2268 }
2269 }
2270 }
2271 }
2272 /* printf("Component labels marked dirty.\n"); */
2273 #if 0
2274 for( c = 0; c < raidPtr->numSpare ; c++) {
2275 sparecol = raidPtr->numCol + c;
2276 if (raidPtr->Disks[r][sparecol].status == rf_ds_used_spare) {
2277 /*
2278
2279 XXX this is where we get fancy and map this spare
2280 into it's correct spot in the array.
2281
2282 */
2283 /*
2284
2285 we claim this disk is "optimal" if it's
2286 rf_ds_used_spare, as that means it should be
2287 directly substitutable for the disk it replaced.
2288 We note that too...
2289
2290 */
2291
2292 for(i=0;i<raidPtr->numRow;i++) {
2293 for(j=0;j<raidPtr->numCol;j++) {
2294 if ((raidPtr->Disks[i][j].spareRow ==
2295 r) &&
2296 (raidPtr->Disks[i][j].spareCol ==
2297 sparecol)) {
2298 srow = r;
2299 scol = sparecol;
2300 break;
2301 }
2302 }
2303 }
2304
2305 raidread_component_label(
2306 raidPtr->Disks[r][sparecol].dev,
2307 raidPtr->raid_cinfo[r][sparecol].ci_vp,
2308 &clabel);
2309 /* make sure status is noted */
2310 clabel.version = RF_COMPONENT_LABEL_VERSION;
2311 clabel.mod_counter = raidPtr->mod_counter;
2312 clabel.serial_number = raidPtr->serial_number;
2313 clabel.row = srow;
2314 clabel.column = scol;
2315 clabel.num_rows = raidPtr->numRow;
2316 clabel.num_columns = raidPtr->numCol;
2317 clabel.clean = RF_RAID_DIRTY; /* changed in a bit*/
2318 clabel.status = rf_ds_optimal;
2319 raidwrite_component_label(
2320 raidPtr->Disks[r][sparecol].dev,
2321 raidPtr->raid_cinfo[r][sparecol].ci_vp,
2322 &clabel);
2323 raidmarkclean( raidPtr->Disks[r][sparecol].dev,
2324 raidPtr->raid_cinfo[r][sparecol].ci_vp);
2325 }
2326 }
2327
2328 #endif
2329 }
2330
2331
2332 void
2333 rf_update_component_labels(raidPtr, final)
2334 RF_Raid_t *raidPtr;
2335 int final;
2336 {
2337 RF_ComponentLabel_t clabel;
2338 int sparecol;
2339 int r,c;
2340 int i,j;
2341 int srow, scol;
2342
2343 srow = -1;
2344 scol = -1;
2345
2346 /* XXX should do extra checks to make sure things really are clean,
2347 rather than blindly setting the clean bit... */
2348
2349 raidPtr->mod_counter++;
2350
2351 for (r = 0; r < raidPtr->numRow; r++) {
2352 for (c = 0; c < raidPtr->numCol; c++) {
2353 if (raidPtr->Disks[r][c].status == rf_ds_optimal) {
2354 raidread_component_label(
2355 raidPtr->Disks[r][c].dev,
2356 raidPtr->raid_cinfo[r][c].ci_vp,
2357 &clabel);
2358 /* make sure status is noted */
2359 clabel.status = rf_ds_optimal;
2360 /* bump the counter */
2361 clabel.mod_counter = raidPtr->mod_counter;
2362
2363 raidwrite_component_label(
2364 raidPtr->Disks[r][c].dev,
2365 raidPtr->raid_cinfo[r][c].ci_vp,
2366 &clabel);
2367 if (final == RF_FINAL_COMPONENT_UPDATE) {
2368 if (raidPtr->parity_good == RF_RAID_CLEAN) {
2369 raidmarkclean(
2370 raidPtr->Disks[r][c].dev,
2371 raidPtr->raid_cinfo[r][c].ci_vp,
2372 raidPtr->mod_counter);
2373 }
2374 }
2375 }
2376 /* else we don't touch it.. */
2377 }
2378 }
2379
2380 for( c = 0; c < raidPtr->numSpare ; c++) {
2381 sparecol = raidPtr->numCol + c;
2382 if (raidPtr->Disks[0][sparecol].status == rf_ds_used_spare) {
2383 /*
2384
2385 we claim this disk is "optimal" if it's
2386 rf_ds_used_spare, as that means it should be
2387 directly substitutable for the disk it replaced.
2388 We note that too...
2389
2390 */
2391
2392 for(i=0;i<raidPtr->numRow;i++) {
2393 for(j=0;j<raidPtr->numCol;j++) {
2394 if ((raidPtr->Disks[i][j].spareRow ==
2395 0) &&
2396 (raidPtr->Disks[i][j].spareCol ==
2397 sparecol)) {
2398 srow = i;
2399 scol = j;
2400 break;
2401 }
2402 }
2403 }
2404
2405 /* XXX shouldn't *really* need this... */
2406 raidread_component_label(
2407 raidPtr->Disks[0][sparecol].dev,
2408 raidPtr->raid_cinfo[0][sparecol].ci_vp,
2409 &clabel);
2410 /* make sure status is noted */
2411
2412 raid_init_component_label(raidPtr, &clabel);
2413
2414 clabel.mod_counter = raidPtr->mod_counter;
2415 clabel.row = srow;
2416 clabel.column = scol;
2417 clabel.status = rf_ds_optimal;
2418
2419 raidwrite_component_label(
2420 raidPtr->Disks[0][sparecol].dev,
2421 raidPtr->raid_cinfo[0][sparecol].ci_vp,
2422 &clabel);
2423 if (final == RF_FINAL_COMPONENT_UPDATE) {
2424 if (raidPtr->parity_good == RF_RAID_CLEAN) {
2425 raidmarkclean( raidPtr->Disks[0][sparecol].dev,
2426 raidPtr->raid_cinfo[0][sparecol].ci_vp,
2427 raidPtr->mod_counter);
2428 }
2429 }
2430 }
2431 }
2432 /* printf("Component labels updated\n"); */
2433 }
2434
2435 void
2436 rf_close_component(raidPtr, vp, auto_configured)
2437 RF_Raid_t *raidPtr;
2438 struct vnode *vp;
2439 int auto_configured;
2440 {
2441 struct proc *p;
2442
2443 p = raidPtr->engine_thread;
2444
2445 if (vp != NULL) {
2446 if (auto_configured == 1) {
2447 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
2448 VOP_CLOSE(vp, FREAD | FWRITE, NOCRED, 0);
2449 vput(vp);
2450
2451 } else {
2452 (void) vn_close(vp, FREAD | FWRITE, p->p_ucred, p);
2453 }
2454 } else {
2455 printf("vnode was NULL\n");
2456 }
2457 }
2458
2459
2460 void
2461 rf_UnconfigureVnodes(raidPtr)
2462 RF_Raid_t *raidPtr;
2463 {
2464 int r,c;
2465 struct proc *p;
2466 struct vnode *vp;
2467 int acd;
2468
2469
2470 /* We take this opportunity to close the vnodes like we should.. */
2471
2472 p = raidPtr->engine_thread;
2473
2474 for (r = 0; r < raidPtr->numRow; r++) {
2475 for (c = 0; c < raidPtr->numCol; c++) {
2476 printf("Closing vnode for row: %d col: %d\n", r, c);
2477 vp = raidPtr->raid_cinfo[r][c].ci_vp;
2478 acd = raidPtr->Disks[r][c].auto_configured;
2479 rf_close_component(raidPtr, vp, acd);
2480 raidPtr->raid_cinfo[r][c].ci_vp = NULL;
2481 raidPtr->Disks[r][c].auto_configured = 0;
2482 }
2483 }
2484 for (r = 0; r < raidPtr->numSpare; r++) {
2485 printf("Closing vnode for spare: %d\n", r);
2486 vp = raidPtr->raid_cinfo[0][raidPtr->numCol + r].ci_vp;
2487 acd = raidPtr->Disks[0][raidPtr->numCol + r].auto_configured;
2488 rf_close_component(raidPtr, vp, acd);
2489 raidPtr->raid_cinfo[0][raidPtr->numCol + r].ci_vp = NULL;
2490 raidPtr->Disks[0][raidPtr->numCol + r].auto_configured = 0;
2491 }
2492 }
2493
2494
2495 void
2496 rf_ReconThread(req)
2497 struct rf_recon_req *req;
2498 {
2499 int s;
2500 RF_Raid_t *raidPtr;
2501
2502 s = splbio();
2503 raidPtr = (RF_Raid_t *) req->raidPtr;
2504 raidPtr->recon_in_progress = 1;
2505
2506 rf_FailDisk((RF_Raid_t *) req->raidPtr, req->row, req->col,
2507 ((req->flags & RF_FDFLAGS_RECON) ? 1 : 0));
2508
2509 /* XXX get rid of this! we don't need it at all.. */
2510 RF_Free(req, sizeof(*req));
2511
2512 raidPtr->recon_in_progress = 0;
2513 splx(s);
2514
2515 /* That's all... */
2516 kthread_exit(0); /* does not return */
2517 }
2518
2519 void
2520 rf_RewriteParityThread(raidPtr)
2521 RF_Raid_t *raidPtr;
2522 {
2523 int retcode;
2524 int s;
2525
2526 raidPtr->parity_rewrite_in_progress = 1;
2527 s = splbio();
2528 retcode = rf_RewriteParity(raidPtr);
2529 splx(s);
2530 if (retcode) {
2531 printf("raid%d: Error re-writing parity!\n",raidPtr->raidid);
2532 } else {
2533 /* set the clean bit! If we shutdown correctly,
2534 the clean bit on each component label will get
2535 set */
2536 raidPtr->parity_good = RF_RAID_CLEAN;
2537 }
2538 raidPtr->parity_rewrite_in_progress = 0;
2539
2540 /* Anyone waiting for us to stop? If so, inform them... */
2541 if (raidPtr->waitShutdown) {
2542 wakeup(&raidPtr->parity_rewrite_in_progress);
2543 }
2544
2545 /* That's all... */
2546 kthread_exit(0); /* does not return */
2547 }
2548
2549
2550 void
2551 rf_CopybackThread(raidPtr)
2552 RF_Raid_t *raidPtr;
2553 {
2554 int s;
2555
2556 raidPtr->copyback_in_progress = 1;
2557 s = splbio();
2558 rf_CopybackReconstructedData(raidPtr);
2559 splx(s);
2560 raidPtr->copyback_in_progress = 0;
2561
2562 /* That's all... */
2563 kthread_exit(0); /* does not return */
2564 }
2565
2566
2567 void
2568 rf_ReconstructInPlaceThread(req)
2569 struct rf_recon_req *req;
2570 {
2571 int retcode;
2572 int s;
2573 RF_Raid_t *raidPtr;
2574
2575 s = splbio();
2576 raidPtr = req->raidPtr;
2577 raidPtr->recon_in_progress = 1;
2578 retcode = rf_ReconstructInPlace(raidPtr, req->row, req->col);
2579 RF_Free(req, sizeof(*req));
2580 raidPtr->recon_in_progress = 0;
2581 splx(s);
2582
2583 /* That's all... */
2584 kthread_exit(0); /* does not return */
2585 }
2586
2587 void
2588 rf_mountroot_hook(dev)
2589 struct device *dev;
2590 {
2591
2592 }
2593
2594
2595 RF_AutoConfig_t *
2596 rf_find_raid_components()
2597 {
2598 struct devnametobdevmaj *dtobdm;
2599 struct vnode *vp;
2600 struct disklabel label;
2601 struct device *dv;
2602 char *cd_name;
2603 dev_t dev;
2604 int error;
2605 int i;
2606 int good_one;
2607 RF_ComponentLabel_t *clabel;
2608 RF_AutoConfig_t *ac_list;
2609 RF_AutoConfig_t *ac;
2610
2611
2612 /* initialize the AutoConfig list */
2613 ac_list = NULL;
2614
2615 if (raidautoconfig) {
2616
2617 /* we begin by trolling through *all* the devices on the system */
2618
2619 for (dv = alldevs.tqh_first; dv != NULL;
2620 dv = dv->dv_list.tqe_next) {
2621
2622 /* we are only interested in disks... */
2623 if (dv->dv_class != DV_DISK)
2624 continue;
2625
2626 /* we don't care about floppies... */
2627 if (!strcmp(dv->dv_cfdata->cf_driver->cd_name,"fd")) {
2628 continue;
2629 }
2630
2631 /* need to find the device_name_to_block_device_major stuff */
2632 cd_name = dv->dv_cfdata->cf_driver->cd_name;
2633 dtobdm = dev_name2blk;
2634 while (dtobdm->d_name && strcmp(dtobdm->d_name, cd_name)) {
2635 dtobdm++;
2636 }
2637
2638 /* get a vnode for the raw partition of this disk */
2639
2640 dev = MAKEDISKDEV(dtobdm->d_maj, dv->dv_unit, RAW_PART);
2641 if (bdevvp(dev, &vp))
2642 panic("RAID can't alloc vnode");
2643
2644 error = VOP_OPEN(vp, FREAD, NOCRED, 0);
2645
2646 if (error) {
2647 /* "Who cares." Continue looking
2648 for something that exists*/
2649 vput(vp);
2650 continue;
2651 }
2652
2653 /* Ok, the disk exists. Go get the disklabel. */
2654 error = VOP_IOCTL(vp, DIOCGDINFO, (caddr_t)&label,
2655 FREAD, NOCRED, 0);
2656 if (error) {
2657 /*
2658 * XXX can't happen - open() would
2659 * have errored out (or faked up one)
2660 */
2661 printf("can't get label for dev %s%c (%d)!?!?\n",
2662 dv->dv_xname, 'a' + RAW_PART, error);
2663 }
2664
2665 /* don't need this any more. We'll allocate it again
2666 a little later if we really do... */
2667 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
2668 VOP_CLOSE(vp, FREAD | FWRITE, NOCRED, 0);
2669 vput(vp);
2670
2671 for (i=0; i < label.d_npartitions; i++) {
2672 /* We only support partitions marked as RAID */
2673 if (label.d_partitions[i].p_fstype != FS_RAID)
2674 continue;
2675
2676 dev = MAKEDISKDEV(dtobdm->d_maj, dv->dv_unit, i);
2677 if (bdevvp(dev, &vp))
2678 panic("RAID can't alloc vnode");
2679
2680 error = VOP_OPEN(vp, FREAD, NOCRED, 0);
2681 if (error) {
2682 /* Whatever... */
2683 vput(vp);
2684 continue;
2685 }
2686
2687 good_one = 0;
2688
2689 clabel = (RF_ComponentLabel_t *)
2690 malloc(sizeof(RF_ComponentLabel_t),
2691 M_RAIDFRAME, M_NOWAIT);
2692 if (clabel == NULL) {
2693 /* XXX CLEANUP HERE */
2694 printf("RAID auto config: out of memory!\n");
2695 return(NULL); /* XXX probably should panic? */
2696 }
2697
2698 if (!raidread_component_label(dev, vp, clabel)) {
2699 /* Got the label. Does it look reasonable? */
2700 if (rf_reasonable_label(clabel) &&
2701 (clabel->partitionSize <=
2702 label.d_partitions[i].p_size)) {
2703 #if DEBUG
2704 printf("Component on: %s%c: %d\n",
2705 dv->dv_xname, 'a'+i,
2706 label.d_partitions[i].p_size);
2707 rf_print_component_label(clabel);
2708 #endif
2709 /* if it's reasonable, add it,
2710 else ignore it. */
2711 ac = (RF_AutoConfig_t *)
2712 malloc(sizeof(RF_AutoConfig_t),
2713 M_RAIDFRAME,
2714 M_NOWAIT);
2715 if (ac == NULL) {
2716 /* XXX should panic?? */
2717 return(NULL);
2718 }
2719
2720 sprintf(ac->devname, "%s%c",
2721 dv->dv_xname, 'a'+i);
2722 ac->dev = dev;
2723 ac->vp = vp;
2724 ac->clabel = clabel;
2725 ac->next = ac_list;
2726 ac_list = ac;
2727 good_one = 1;
2728 }
2729 }
2730 if (!good_one) {
2731 /* cleanup */
2732 free(clabel, M_RAIDFRAME);
2733 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
2734 VOP_CLOSE(vp, FREAD | FWRITE, NOCRED, 0);
2735 vput(vp);
2736 }
2737 }
2738 }
2739 }
2740 return(ac_list);
2741 }
2742
2743 static int
2744 rf_reasonable_label(clabel)
2745 RF_ComponentLabel_t *clabel;
2746 {
2747
2748 if (((clabel->version==RF_COMPONENT_LABEL_VERSION_1) ||
2749 (clabel->version==RF_COMPONENT_LABEL_VERSION)) &&
2750 ((clabel->clean == RF_RAID_CLEAN) ||
2751 (clabel->clean == RF_RAID_DIRTY)) &&
2752 clabel->row >=0 &&
2753 clabel->column >= 0 &&
2754 clabel->num_rows > 0 &&
2755 clabel->num_columns > 0 &&
2756 clabel->row < clabel->num_rows &&
2757 clabel->column < clabel->num_columns &&
2758 clabel->blockSize > 0 &&
2759 clabel->numBlocks > 0) {
2760 /* label looks reasonable enough... */
2761 return(1);
2762 }
2763 return(0);
2764 }
2765
2766
2767 void
2768 rf_print_component_label(clabel)
2769 RF_ComponentLabel_t *clabel;
2770 {
2771 printf(" Row: %d Column: %d Num Rows: %d Num Columns: %d\n",
2772 clabel->row, clabel->column,
2773 clabel->num_rows, clabel->num_columns);
2774 printf(" Version: %d Serial Number: %d Mod Counter: %d\n",
2775 clabel->version, clabel->serial_number,
2776 clabel->mod_counter);
2777 printf(" Clean: %s Status: %d\n",
2778 clabel->clean ? "Yes" : "No", clabel->status );
2779 printf(" sectPerSU: %d SUsPerPU: %d SUsPerRU: %d\n",
2780 clabel->sectPerSU, clabel->SUsPerPU, clabel->SUsPerRU);
2781 printf(" RAID Level: %c blocksize: %d numBlocks: %d\n",
2782 (char) clabel->parityConfig, clabel->blockSize,
2783 clabel->numBlocks);
2784 printf(" Autoconfig: %s\n", clabel->autoconfigure ? "Yes" : "No" );
2785 printf(" Contains root partition: %s\n",
2786 clabel->root_partition ? "Yes" : "No" );
2787 printf(" Last configured as: raid%d\n", clabel->last_unit );
2788 #if 0
2789 printf(" Config order: %d\n", clabel->config_order);
2790 #endif
2791
2792 }
2793
2794 RF_ConfigSet_t *
2795 rf_create_auto_sets(ac_list)
2796 RF_AutoConfig_t *ac_list;
2797 {
2798 RF_AutoConfig_t *ac;
2799 RF_ConfigSet_t *config_sets;
2800 RF_ConfigSet_t *cset;
2801 RF_AutoConfig_t *ac_next;
2802
2803
2804 config_sets = NULL;
2805
2806 /* Go through the AutoConfig list, and figure out which components
2807 belong to what sets. */
2808 ac = ac_list;
2809 while(ac!=NULL) {
2810 /* we're going to putz with ac->next, so save it here
2811 for use at the end of the loop */
2812 ac_next = ac->next;
2813
2814 if (config_sets == NULL) {
2815 /* will need at least this one... */
2816 config_sets = (RF_ConfigSet_t *)
2817 malloc(sizeof(RF_ConfigSet_t),
2818 M_RAIDFRAME, M_NOWAIT);
2819 if (config_sets == NULL) {
2820 panic("rf_create_auto_sets: No memory!\n");
2821 }
2822 /* this one is easy :) */
2823 config_sets->ac = ac;
2824 config_sets->next = NULL;
2825 config_sets->rootable = 0;
2826 ac->next = NULL;
2827 } else {
2828 /* which set does this component fit into? */
2829 cset = config_sets;
2830 while(cset!=NULL) {
2831 if (rf_does_it_fit(cset, ac)) {
2832 /* looks like it matches... */
2833 ac->next = cset->ac;
2834 cset->ac = ac;
2835 break;
2836 }
2837 cset = cset->next;
2838 }
2839 if (cset==NULL) {
2840 /* didn't find a match above... new set..*/
2841 cset = (RF_ConfigSet_t *)
2842 malloc(sizeof(RF_ConfigSet_t),
2843 M_RAIDFRAME, M_NOWAIT);
2844 if (cset == NULL) {
2845 panic("rf_create_auto_sets: No memory!\n");
2846 }
2847 cset->ac = ac;
2848 ac->next = NULL;
2849 cset->next = config_sets;
2850 cset->rootable = 0;
2851 config_sets = cset;
2852 }
2853 }
2854 ac = ac_next;
2855 }
2856
2857
2858 return(config_sets);
2859 }
2860
2861 static int
2862 rf_does_it_fit(cset, ac)
2863 RF_ConfigSet_t *cset;
2864 RF_AutoConfig_t *ac;
2865 {
2866 RF_ComponentLabel_t *clabel1, *clabel2;
2867
2868 /* If this one matches the *first* one in the set, that's good
2869 enough, since the other members of the set would have been
2870 through here too... */
2871 /* note that we are not checking partitionSize here..
2872
2873 Note that we are also not checking the mod_counters here.
2874 If everything else matches execpt the mod_counter, that's
2875 good enough for this test. We will deal with the mod_counters
2876 a little later in the autoconfiguration process.
2877
2878 (clabel1->mod_counter == clabel2->mod_counter) &&
2879
2880 The reason we don't check for this is that failed disks
2881 will have lower modification counts. If those disks are
2882 not added to the set they used to belong to, then they will
2883 form their own set, which may result in 2 different sets,
2884 for example, competing to be configured at raid0, and
2885 perhaps competing to be the root filesystem set. If the
2886 wrong ones get configured, or both attempt to become /,
2887 weird behaviour and or serious lossage will occur. Thus we
2888 need to bring them into the fold here, and kick them out at
2889 a later point.
2890
2891 */
2892
2893 clabel1 = cset->ac->clabel;
2894 clabel2 = ac->clabel;
2895 if ((clabel1->version == clabel2->version) &&
2896 (clabel1->serial_number == clabel2->serial_number) &&
2897 (clabel1->num_rows == clabel2->num_rows) &&
2898 (clabel1->num_columns == clabel2->num_columns) &&
2899 (clabel1->sectPerSU == clabel2->sectPerSU) &&
2900 (clabel1->SUsPerPU == clabel2->SUsPerPU) &&
2901 (clabel1->SUsPerRU == clabel2->SUsPerRU) &&
2902 (clabel1->parityConfig == clabel2->parityConfig) &&
2903 (clabel1->maxOutstanding == clabel2->maxOutstanding) &&
2904 (clabel1->blockSize == clabel2->blockSize) &&
2905 (clabel1->numBlocks == clabel2->numBlocks) &&
2906 (clabel1->autoconfigure == clabel2->autoconfigure) &&
2907 (clabel1->root_partition == clabel2->root_partition) &&
2908 (clabel1->last_unit == clabel2->last_unit) &&
2909 (clabel1->config_order == clabel2->config_order)) {
2910 /* if it get's here, it almost *has* to be a match */
2911 } else {
2912 /* it's not consistent with somebody in the set..
2913 punt */
2914 return(0);
2915 }
2916 /* all was fine.. it must fit... */
2917 return(1);
2918 }
2919
2920 int
2921 rf_have_enough_components(cset)
2922 RF_ConfigSet_t *cset;
2923 {
2924 RF_AutoConfig_t *ac;
2925 RF_AutoConfig_t *auto_config;
2926 RF_ComponentLabel_t *clabel;
2927 int r,c;
2928 int num_rows;
2929 int num_cols;
2930 int num_missing;
2931 int mod_counter;
2932 int mod_counter_found;
2933 int even_pair_failed;
2934 char parity_type;
2935
2936
2937 /* check to see that we have enough 'live' components
2938 of this set. If so, we can configure it if necessary */
2939
2940 num_rows = cset->ac->clabel->num_rows;
2941 num_cols = cset->ac->clabel->num_columns;
2942 parity_type = cset->ac->clabel->parityConfig;
2943
2944 /* XXX Check for duplicate components!?!?!? */
2945
2946 /* Determine what the mod_counter is supposed to be for this set. */
2947
2948 mod_counter_found = 0;
2949 ac = cset->ac;
2950 while(ac!=NULL) {
2951 if (mod_counter_found==0) {
2952 mod_counter = ac->clabel->mod_counter;
2953 mod_counter_found = 1;
2954 } else {
2955 if (ac->clabel->mod_counter > mod_counter) {
2956 mod_counter = ac->clabel->mod_counter;
2957 }
2958 }
2959 ac = ac->next;
2960 }
2961
2962 num_missing = 0;
2963 auto_config = cset->ac;
2964
2965 for(r=0; r<num_rows; r++) {
2966 even_pair_failed = 0;
2967 for(c=0; c<num_cols; c++) {
2968 ac = auto_config;
2969 while(ac!=NULL) {
2970 if ((ac->clabel->row == r) &&
2971 (ac->clabel->column == c) &&
2972 (ac->clabel->mod_counter == mod_counter)) {
2973 /* it's this one... */
2974 #if DEBUG
2975 printf("Found: %s at %d,%d\n",
2976 ac->devname,r,c);
2977 #endif
2978 break;
2979 }
2980 ac=ac->next;
2981 }
2982 if (ac==NULL) {
2983 /* Didn't find one here! */
2984 /* special case for RAID 1, especially
2985 where there are more than 2
2986 components (where RAIDframe treats
2987 things a little differently :( ) */
2988 if (parity_type == '1') {
2989 if (c%2 == 0) { /* even component */
2990 even_pair_failed = 1;
2991 } else { /* odd component. If
2992 we're failed, and
2993 so is the even
2994 component, it's
2995 "Good Night, Charlie" */
2996 if (even_pair_failed == 1) {
2997 return(0);
2998 }
2999 }
3000 } else {
3001 /* normal accounting */
3002 num_missing++;
3003 }
3004 }
3005 if ((parity_type == '1') && (c%2 == 1)) {
3006 /* Just did an even component, and we didn't
3007 bail.. reset the even_pair_failed flag,
3008 and go on to the next component.... */
3009 even_pair_failed = 0;
3010 }
3011 }
3012 }
3013
3014 clabel = cset->ac->clabel;
3015
3016 if (((clabel->parityConfig == '0') && (num_missing > 0)) ||
3017 ((clabel->parityConfig == '4') && (num_missing > 1)) ||
3018 ((clabel->parityConfig == '5') && (num_missing > 1))) {
3019 /* XXX this needs to be made *much* more general */
3020 /* Too many failures */
3021 return(0);
3022 }
3023 /* otherwise, all is well, and we've got enough to take a kick
3024 at autoconfiguring this set */
3025 return(1);
3026 }
3027
3028 void
3029 rf_create_configuration(ac,config,raidPtr)
3030 RF_AutoConfig_t *ac;
3031 RF_Config_t *config;
3032 RF_Raid_t *raidPtr;
3033 {
3034 RF_ComponentLabel_t *clabel;
3035 int i;
3036
3037 clabel = ac->clabel;
3038
3039 /* 1. Fill in the common stuff */
3040 config->numRow = clabel->num_rows;
3041 config->numCol = clabel->num_columns;
3042 config->numSpare = 0; /* XXX should this be set here? */
3043 config->sectPerSU = clabel->sectPerSU;
3044 config->SUsPerPU = clabel->SUsPerPU;
3045 config->SUsPerRU = clabel->SUsPerRU;
3046 config->parityConfig = clabel->parityConfig;
3047 /* XXX... */
3048 strcpy(config->diskQueueType,"fifo");
3049 config->maxOutstandingDiskReqs = clabel->maxOutstanding;
3050 config->layoutSpecificSize = 0; /* XXX ?? */
3051
3052 while(ac!=NULL) {
3053 /* row/col values will be in range due to the checks
3054 in reasonable_label() */
3055 strcpy(config->devnames[ac->clabel->row][ac->clabel->column],
3056 ac->devname);
3057 ac = ac->next;
3058 }
3059
3060 for(i=0;i<RF_MAXDBGV;i++) {
3061 config->debugVars[i][0] = NULL;
3062 }
3063 }
3064
3065 int
3066 rf_set_autoconfig(raidPtr, new_value)
3067 RF_Raid_t *raidPtr;
3068 int new_value;
3069 {
3070 RF_ComponentLabel_t clabel;
3071 struct vnode *vp;
3072 dev_t dev;
3073 int row, column;
3074
3075 raidPtr->autoconfigure = new_value;
3076 for(row=0; row<raidPtr->numRow; row++) {
3077 for(column=0; column<raidPtr->numCol; column++) {
3078 if (raidPtr->Disks[row][column].status ==
3079 rf_ds_optimal) {
3080 dev = raidPtr->Disks[row][column].dev;
3081 vp = raidPtr->raid_cinfo[row][column].ci_vp;
3082 raidread_component_label(dev, vp, &clabel);
3083 clabel.autoconfigure = new_value;
3084 raidwrite_component_label(dev, vp, &clabel);
3085 }
3086 }
3087 }
3088 return(new_value);
3089 }
3090
3091 int
3092 rf_set_rootpartition(raidPtr, new_value)
3093 RF_Raid_t *raidPtr;
3094 int new_value;
3095 {
3096 RF_ComponentLabel_t clabel;
3097 struct vnode *vp;
3098 dev_t dev;
3099 int row, column;
3100
3101 raidPtr->root_partition = new_value;
3102 for(row=0; row<raidPtr->numRow; row++) {
3103 for(column=0; column<raidPtr->numCol; column++) {
3104 if (raidPtr->Disks[row][column].status ==
3105 rf_ds_optimal) {
3106 dev = raidPtr->Disks[row][column].dev;
3107 vp = raidPtr->raid_cinfo[row][column].ci_vp;
3108 raidread_component_label(dev, vp, &clabel);
3109 clabel.root_partition = new_value;
3110 raidwrite_component_label(dev, vp, &clabel);
3111 }
3112 }
3113 }
3114 return(new_value);
3115 }
3116
3117 void
3118 rf_release_all_vps(cset)
3119 RF_ConfigSet_t *cset;
3120 {
3121 RF_AutoConfig_t *ac;
3122
3123 ac = cset->ac;
3124 while(ac!=NULL) {
3125 /* Close the vp, and give it back */
3126 if (ac->vp) {
3127 vn_lock(ac->vp, LK_EXCLUSIVE | LK_RETRY);
3128 VOP_CLOSE(ac->vp, FREAD, NOCRED, 0);
3129 vput(ac->vp);
3130 ac->vp = NULL;
3131 }
3132 ac = ac->next;
3133 }
3134 }
3135
3136
3137 void
3138 rf_cleanup_config_set(cset)
3139 RF_ConfigSet_t *cset;
3140 {
3141 RF_AutoConfig_t *ac;
3142 RF_AutoConfig_t *next_ac;
3143
3144 ac = cset->ac;
3145 while(ac!=NULL) {
3146 next_ac = ac->next;
3147 /* nuke the label */
3148 free(ac->clabel, M_RAIDFRAME);
3149 /* cleanup the config structure */
3150 free(ac, M_RAIDFRAME);
3151 /* "next.." */
3152 ac = next_ac;
3153 }
3154 /* and, finally, nuke the config set */
3155 free(cset, M_RAIDFRAME);
3156 }
3157
3158
3159 void
3160 raid_init_component_label(raidPtr, clabel)
3161 RF_Raid_t *raidPtr;
3162 RF_ComponentLabel_t *clabel;
3163 {
3164 /* current version number */
3165 clabel->version = RF_COMPONENT_LABEL_VERSION;
3166 clabel->serial_number = raidPtr->serial_number;
3167 clabel->mod_counter = raidPtr->mod_counter;
3168 clabel->num_rows = raidPtr->numRow;
3169 clabel->num_columns = raidPtr->numCol;
3170 clabel->clean = RF_RAID_DIRTY; /* not clean */
3171 clabel->status = rf_ds_optimal; /* "It's good!" */
3172
3173 clabel->sectPerSU = raidPtr->Layout.sectorsPerStripeUnit;
3174 clabel->SUsPerPU = raidPtr->Layout.SUsPerPU;
3175 clabel->SUsPerRU = raidPtr->Layout.SUsPerRU;
3176
3177 clabel->blockSize = raidPtr->bytesPerSector;
3178 clabel->numBlocks = raidPtr->sectorsPerDisk;
3179
3180 /* XXX not portable */
3181 clabel->parityConfig = raidPtr->Layout.map->parityConfig;
3182 clabel->maxOutstanding = raidPtr->maxOutstanding;
3183 clabel->autoconfigure = raidPtr->autoconfigure;
3184 clabel->root_partition = raidPtr->root_partition;
3185 clabel->last_unit = raidPtr->raidid;
3186 clabel->config_order = raidPtr->config_order;
3187 }
3188
3189 int
3190 rf_auto_config_set(cset,unit)
3191 RF_ConfigSet_t *cset;
3192 int *unit;
3193 {
3194 RF_Raid_t *raidPtr;
3195 RF_Config_t *config;
3196 int raidID;
3197 int retcode;
3198
3199 printf("RAID autoconfigure\n");
3200
3201 retcode = 0;
3202 *unit = -1;
3203
3204 /* 1. Create a config structure */
3205
3206 config = (RF_Config_t *)malloc(sizeof(RF_Config_t),
3207 M_RAIDFRAME,
3208 M_NOWAIT);
3209 if (config==NULL) {
3210 printf("Out of mem!?!?\n");
3211 /* XXX do something more intelligent here. */
3212 return(1);
3213 }
3214
3215 memset(config, 0, sizeof(RF_Config_t));
3216
3217 /* XXX raidID needs to be set correctly.. */
3218
3219 /*
3220 2. Figure out what RAID ID this one is supposed to live at
3221 See if we can get the same RAID dev that it was configured
3222 on last time..
3223 */
3224
3225 raidID = cset->ac->clabel->last_unit;
3226 if ((raidID < 0) || (raidID >= numraid)) {
3227 /* let's not wander off into lala land. */
3228 raidID = numraid - 1;
3229 }
3230 if (raidPtrs[raidID]->valid != 0) {
3231
3232 /*
3233 Nope... Go looking for an alternative...
3234 Start high so we don't immediately use raid0 if that's
3235 not taken.
3236 */
3237
3238 for(raidID = numraid; raidID >= 0; raidID--) {
3239 if (raidPtrs[raidID]->valid == 0) {
3240 /* can use this one! */
3241 break;
3242 }
3243 }
3244 }
3245
3246 if (raidID < 0) {
3247 /* punt... */
3248 printf("Unable to auto configure this set!\n");
3249 printf("(Out of RAID devs!)\n");
3250 return(1);
3251 }
3252 printf("Configuring raid%d:\n",raidID);
3253 raidPtr = raidPtrs[raidID];
3254
3255 /* XXX all this stuff should be done SOMEWHERE ELSE! */
3256 raidPtr->raidid = raidID;
3257 raidPtr->openings = RAIDOUTSTANDING;
3258
3259 /* 3. Build the configuration structure */
3260 rf_create_configuration(cset->ac, config, raidPtr);
3261
3262 /* 4. Do the configuration */
3263 retcode = rf_Configure(raidPtr, config, cset->ac);
3264
3265 if (retcode == 0) {
3266
3267 raidinit(raidPtrs[raidID]);
3268
3269 rf_markalldirty(raidPtrs[raidID]);
3270 raidPtrs[raidID]->autoconfigure = 1; /* XXX do this here? */
3271 if (cset->ac->clabel->root_partition==1) {
3272 /* everything configured just fine. Make a note
3273 that this set is eligible to be root. */
3274 cset->rootable = 1;
3275 /* XXX do this here? */
3276 raidPtrs[raidID]->root_partition = 1;
3277 }
3278 }
3279
3280 /* 5. Cleanup */
3281 free(config, M_RAIDFRAME);
3282
3283 *unit = raidID;
3284 return(retcode);
3285 }
3286
3287 void
3288 rf_disk_unbusy(desc)
3289 RF_RaidAccessDesc_t *desc;
3290 {
3291 struct buf *bp;
3292
3293 bp = (struct buf *)desc->bp;
3294 disk_unbusy(&raid_softc[desc->raidPtr->raidid].sc_dkdev,
3295 (bp->b_bcount - bp->b_resid));
3296 }
3297