Thu Jul 23 21:58:06 2009 UTC ()
Move the RAID shutdown to the raid(4) detachment routine, and use
config_detach(9) to shutdown a RAID.

Detach raid(4) units at shutdown.

Ok by oster@.


(dyoung)
diff -r1.265 -r1.266 src/sys/dev/raidframe/rf_netbsdkintf.c

cvs diff -r1.265 -r1.266 src/sys/dev/raidframe/rf_netbsdkintf.c (switch to unified diff)

--- src/sys/dev/raidframe/rf_netbsdkintf.c 2009/06/10 14:17:13 1.265
+++ src/sys/dev/raidframe/rf_netbsdkintf.c 2009/07/23 21:58:06 1.266
@@ -1,2209 +1,2226 @@ @@ -1,2209 +1,2226 @@
1/* $NetBSD: rf_netbsdkintf.c,v 1.265 2009/06/10 14:17:13 pooka Exp $ */ 1/* $NetBSD: rf_netbsdkintf.c,v 1.266 2009/07/23 21:58:06 dyoung Exp $ */
2/*- 2/*-
3 * Copyright (c) 1996, 1997, 1998, 2008 The NetBSD Foundation, Inc. 3 * Copyright (c) 1996, 1997, 1998, 2008 The NetBSD Foundation, Inc.
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * This code is derived from software contributed to The NetBSD Foundation 6 * This code is derived from software contributed to The NetBSD Foundation
7 * by Greg Oster; Jason R. Thorpe. 7 * by Greg Oster; Jason R. Thorpe.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
17 * 17 *
18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 18 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE. 28 * POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 30
31/* 31/*
32 * Copyright (c) 1990, 1993 32 * Copyright (c) 1990, 1993
33 * The Regents of the University of California. All rights reserved. 33 * The Regents of the University of California. All rights reserved.
34 * 34 *
35 * This code is derived from software contributed to Berkeley by 35 * This code is derived from software contributed to Berkeley by
36 * the Systems Programming Group of the University of Utah Computer 36 * the Systems Programming Group of the University of Utah Computer
37 * Science Department. 37 * Science Department.
38 * 38 *
39 * Redistribution and use in source and binary forms, with or without 39 * Redistribution and use in source and binary forms, with or without
40 * modification, are permitted provided that the following conditions 40 * modification, are permitted provided that the following conditions
41 * are met: 41 * are met:
42 * 1. Redistributions of source code must retain the above copyright 42 * 1. Redistributions of source code must retain the above copyright
43 * notice, this list of conditions and the following disclaimer. 43 * notice, this list of conditions and the following disclaimer.
44 * 2. Redistributions in binary form must reproduce the above copyright 44 * 2. Redistributions in binary form must reproduce the above copyright
45 * notice, this list of conditions and the following disclaimer in the 45 * notice, this list of conditions and the following disclaimer in the
46 * documentation and/or other materials provided with the distribution. 46 * documentation and/or other materials provided with the distribution.
47 * 3. Neither the name of the University nor the names of its contributors 47 * 3. Neither the name of the University nor the names of its contributors
48 * may be used to endorse or promote products derived from this software 48 * may be used to endorse or promote products derived from this software
49 * without specific prior written permission. 49 * without specific prior written permission.
50 * 50 *
51 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 51 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 54 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61 * SUCH DAMAGE. 61 * SUCH DAMAGE.
62 * 62 *
63 * from: Utah $Hdr: cd.c 1.6 90/11/28$ 63 * from: Utah $Hdr: cd.c 1.6 90/11/28$
64 * 64 *
65 * @(#)cd.c 8.2 (Berkeley) 11/16/93 65 * @(#)cd.c 8.2 (Berkeley) 11/16/93
66 */ 66 */
67 67
68/* 68/*
69 * Copyright (c) 1988 University of Utah. 69 * Copyright (c) 1988 University of Utah.
70 * 70 *
71 * This code is derived from software contributed to Berkeley by 71 * This code is derived from software contributed to Berkeley by
72 * the Systems Programming Group of the University of Utah Computer 72 * the Systems Programming Group of the University of Utah Computer
73 * Science Department. 73 * Science Department.
74 * 74 *
75 * Redistribution and use in source and binary forms, with or without 75 * Redistribution and use in source and binary forms, with or without
76 * modification, are permitted provided that the following conditions 76 * modification, are permitted provided that the following conditions
77 * are met: 77 * are met:
78 * 1. Redistributions of source code must retain the above copyright 78 * 1. Redistributions of source code must retain the above copyright
79 * notice, this list of conditions and the following disclaimer. 79 * notice, this list of conditions and the following disclaimer.
80 * 2. Redistributions in binary form must reproduce the above copyright 80 * 2. Redistributions in binary form must reproduce the above copyright
81 * notice, this list of conditions and the following disclaimer in the 81 * notice, this list of conditions and the following disclaimer in the
82 * documentation and/or other materials provided with the distribution. 82 * documentation and/or other materials provided with the distribution.
83 * 3. All advertising materials mentioning features or use of this software 83 * 3. All advertising materials mentioning features or use of this software
84 * must display the following acknowledgement: 84 * must display the following acknowledgement:
85 * This product includes software developed by the University of 85 * This product includes software developed by the University of
86 * California, Berkeley and its contributors. 86 * California, Berkeley and its contributors.
87 * 4. Neither the name of the University nor the names of its contributors 87 * 4. Neither the name of the University nor the names of its contributors
88 * may be used to endorse or promote products derived from this software 88 * may be used to endorse or promote products derived from this software
89 * without specific prior written permission. 89 * without specific prior written permission.
90 * 90 *
91 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 91 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
92 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 92 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 93 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
94 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 94 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
95 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 95 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
96 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 96 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
97 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 97 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
98 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 98 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
99 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 99 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
100 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 100 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
101 * SUCH DAMAGE. 101 * SUCH DAMAGE.
102 * 102 *
103 * from: Utah $Hdr: cd.c 1.6 90/11/28$ 103 * from: Utah $Hdr: cd.c 1.6 90/11/28$
104 * 104 *
105 * @(#)cd.c 8.2 (Berkeley) 11/16/93 105 * @(#)cd.c 8.2 (Berkeley) 11/16/93
106 */ 106 */
107 107
108/* 108/*
109 * Copyright (c) 1995 Carnegie-Mellon University. 109 * Copyright (c) 1995 Carnegie-Mellon University.
110 * All rights reserved. 110 * All rights reserved.
111 * 111 *
112 * Authors: Mark Holland, Jim Zelenka 112 * Authors: Mark Holland, Jim Zelenka
113 * 113 *
114 * Permission to use, copy, modify and distribute this software and 114 * Permission to use, copy, modify and distribute this software and
115 * its documentation is hereby granted, provided that both the copyright 115 * its documentation is hereby granted, provided that both the copyright
116 * notice and this permission notice appear in all copies of the 116 * notice and this permission notice appear in all copies of the
117 * software, derivative works or modified versions, and any portions 117 * software, derivative works or modified versions, and any portions
118 * thereof, and that both notices appear in supporting documentation. 118 * thereof, and that both notices appear in supporting documentation.
119 * 119 *
120 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 120 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
121 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 121 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
122 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 122 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
123 * 123 *
124 * Carnegie Mellon requests users of this software to return to 124 * Carnegie Mellon requests users of this software to return to
125 * 125 *
126 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 126 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
127 * School of Computer Science 127 * School of Computer Science
128 * Carnegie Mellon University 128 * Carnegie Mellon University
129 * Pittsburgh PA 15213-3890 129 * Pittsburgh PA 15213-3890
130 * 130 *
131 * any improvements or extensions that they make and grant Carnegie the 131 * any improvements or extensions that they make and grant Carnegie the
132 * rights to redistribute these changes. 132 * rights to redistribute these changes.
133 */ 133 */
134 134
135/*********************************************************** 135/***********************************************************
136 * 136 *
137 * rf_kintf.c -- the kernel interface routines for RAIDframe 137 * rf_kintf.c -- the kernel interface routines for RAIDframe
138 * 138 *
139 ***********************************************************/ 139 ***********************************************************/
140 140
141#include <sys/cdefs.h> 141#include <sys/cdefs.h>
142__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.265 2009/06/10 14:17:13 pooka Exp $"); 142__KERNEL_RCSID(0, "$NetBSD: rf_netbsdkintf.c,v 1.266 2009/07/23 21:58:06 dyoung Exp $");
143 143
144#ifdef _KERNEL_OPT 144#ifdef _KERNEL_OPT
145#include "opt_compat_netbsd.h" 145#include "opt_compat_netbsd.h"
146#include "opt_raid_autoconfig.h" 146#include "opt_raid_autoconfig.h"
147#include "raid.h" 147#include "raid.h"
148#endif 148#endif
149 149
150#include <sys/param.h> 150#include <sys/param.h>
151#include <sys/errno.h> 151#include <sys/errno.h>
152#include <sys/pool.h> 152#include <sys/pool.h>
153#include <sys/proc.h> 153#include <sys/proc.h>
154#include <sys/queue.h> 154#include <sys/queue.h>
155#include <sys/disk.h> 155#include <sys/disk.h>
156#include <sys/device.h> 156#include <sys/device.h>
157#include <sys/stat.h> 157#include <sys/stat.h>
158#include <sys/ioctl.h> 158#include <sys/ioctl.h>
159#include <sys/fcntl.h> 159#include <sys/fcntl.h>
160#include <sys/systm.h> 160#include <sys/systm.h>
161#include <sys/vnode.h> 161#include <sys/vnode.h>
162#include <sys/disklabel.h> 162#include <sys/disklabel.h>
163#include <sys/conf.h> 163#include <sys/conf.h>
164#include <sys/buf.h> 164#include <sys/buf.h>
165#include <sys/bufq.h> 165#include <sys/bufq.h>
166#include <sys/user.h> 166#include <sys/user.h>
167#include <sys/reboot.h> 167#include <sys/reboot.h>
168#include <sys/kauth.h> 168#include <sys/kauth.h>
169 169
170#include <prop/proplib.h> 170#include <prop/proplib.h>
171 171
172#include <dev/raidframe/raidframevar.h> 172#include <dev/raidframe/raidframevar.h>
173#include <dev/raidframe/raidframeio.h> 173#include <dev/raidframe/raidframeio.h>
174 174
175#include "rf_raid.h" 175#include "rf_raid.h"
176#include "rf_copyback.h" 176#include "rf_copyback.h"
177#include "rf_dag.h" 177#include "rf_dag.h"
178#include "rf_dagflags.h" 178#include "rf_dagflags.h"
179#include "rf_desc.h" 179#include "rf_desc.h"
180#include "rf_diskqueue.h" 180#include "rf_diskqueue.h"
181#include "rf_etimer.h" 181#include "rf_etimer.h"
182#include "rf_general.h" 182#include "rf_general.h"
183#include "rf_kintf.h" 183#include "rf_kintf.h"
184#include "rf_options.h" 184#include "rf_options.h"
185#include "rf_driver.h" 185#include "rf_driver.h"
186#include "rf_parityscan.h" 186#include "rf_parityscan.h"
187#include "rf_threadstuff.h" 187#include "rf_threadstuff.h"
188 188
189#ifdef COMPAT_50 189#ifdef COMPAT_50
190#include "rf_compat50.h" 190#include "rf_compat50.h"
191#endif 191#endif
192 192
193#ifdef DEBUG 193#ifdef DEBUG
194int rf_kdebug_level = 0; 194int rf_kdebug_level = 0;
195#define db1_printf(a) if (rf_kdebug_level > 0) printf a 195#define db1_printf(a) if (rf_kdebug_level > 0) printf a
196#else /* DEBUG */ 196#else /* DEBUG */
197#define db1_printf(a) { } 197#define db1_printf(a) { }
198#endif /* DEBUG */ 198#endif /* DEBUG */
199 199
200static RF_Raid_t **raidPtrs; /* global raid device descriptors */ 200static RF_Raid_t **raidPtrs; /* global raid device descriptors */
201 201
202#if (RF_INCLUDE_PARITY_DECLUSTERING_DS > 0) 202#if (RF_INCLUDE_PARITY_DECLUSTERING_DS > 0)
203RF_DECLARE_STATIC_MUTEX(rf_sparet_wait_mutex) 203RF_DECLARE_STATIC_MUTEX(rf_sparet_wait_mutex)
204 204
205static RF_SparetWait_t *rf_sparet_wait_queue; /* requests to install a 205static RF_SparetWait_t *rf_sparet_wait_queue; /* requests to install a
206 * spare table */ 206 * spare table */
207static RF_SparetWait_t *rf_sparet_resp_queue; /* responses from 207static RF_SparetWait_t *rf_sparet_resp_queue; /* responses from
208 * installation process */ 208 * installation process */
209#endif 209#endif
210 210
211MALLOC_DEFINE(M_RAIDFRAME, "RAIDframe", "RAIDframe structures"); 211MALLOC_DEFINE(M_RAIDFRAME, "RAIDframe", "RAIDframe structures");
212 212
213/* prototypes */ 213/* prototypes */
214static void KernelWakeupFunc(struct buf *); 214static void KernelWakeupFunc(struct buf *);
215static void InitBP(struct buf *, struct vnode *, unsigned, 215static void InitBP(struct buf *, struct vnode *, unsigned,
216 dev_t, RF_SectorNum_t, RF_SectorCount_t, void *, void (*) (struct buf *), 216 dev_t, RF_SectorNum_t, RF_SectorCount_t, void *, void (*) (struct buf *),
217 void *, int, struct proc *); 217 void *, int, struct proc *);
218static void raidinit(RF_Raid_t *); 218static void raidinit(RF_Raid_t *);
219 219
220void raidattach(int); 220void raidattach(int);
221static int raid_match(device_t, cfdata_t, void *); 221static int raid_match(device_t, cfdata_t, void *);
222static void raid_attach(device_t, device_t, void *); 222static void raid_attach(device_t, device_t, void *);
223static int raid_detach(device_t, int); 223static int raid_detach(device_t, int);
224 224
225dev_type_open(raidopen); 225dev_type_open(raidopen);
226dev_type_close(raidclose); 226dev_type_close(raidclose);
227dev_type_read(raidread); 227dev_type_read(raidread);
228dev_type_write(raidwrite); 228dev_type_write(raidwrite);
229dev_type_ioctl(raidioctl); 229dev_type_ioctl(raidioctl);
230dev_type_strategy(raidstrategy); 230dev_type_strategy(raidstrategy);
231dev_type_dump(raiddump); 231dev_type_dump(raiddump);
232dev_type_size(raidsize); 232dev_type_size(raidsize);
233 233
234const struct bdevsw raid_bdevsw = { 234const struct bdevsw raid_bdevsw = {
235 raidopen, raidclose, raidstrategy, raidioctl, 235 raidopen, raidclose, raidstrategy, raidioctl,
236 raiddump, raidsize, D_DISK 236 raiddump, raidsize, D_DISK
237}; 237};
238 238
239const struct cdevsw raid_cdevsw = { 239const struct cdevsw raid_cdevsw = {
240 raidopen, raidclose, raidread, raidwrite, raidioctl, 240 raidopen, raidclose, raidread, raidwrite, raidioctl,
241 nostop, notty, nopoll, nommap, nokqfilter, D_DISK 241 nostop, notty, nopoll, nommap, nokqfilter, D_DISK
242}; 242};
243 243
244static struct dkdriver rf_dkdriver = { raidstrategy, minphys }; 244static struct dkdriver rf_dkdriver = { raidstrategy, minphys };
245 245
246/* XXX Not sure if the following should be replacing the raidPtrs above, 246/* XXX Not sure if the following should be replacing the raidPtrs above,
247 or if it should be used in conjunction with that... 247 or if it should be used in conjunction with that...
248*/ 248*/
249 249
250struct raid_softc { 250struct raid_softc {
251 device_t sc_dev; 251 device_t sc_dev;
252 int sc_flags; /* flags */ 252 int sc_flags; /* flags */
253 int sc_cflags; /* configuration flags */ 253 int sc_cflags; /* configuration flags */
254 uint64_t sc_size; /* size of the raid device */ 254 uint64_t sc_size; /* size of the raid device */
255 char sc_xname[20]; /* XXX external name */ 255 char sc_xname[20]; /* XXX external name */
256 struct disk sc_dkdev; /* generic disk device info */ 256 struct disk sc_dkdev; /* generic disk device info */
257 struct bufq_state *buf_queue; /* used for the device queue */ 257 struct bufq_state *buf_queue; /* used for the device queue */
258}; 258};
259/* sc_flags */ 259/* sc_flags */
260#define RAIDF_INITED 0x01 /* unit has been initialized */ 260#define RAIDF_INITED 0x01 /* unit has been initialized */
261#define RAIDF_WLABEL 0x02 /* label area is writable */ 261#define RAIDF_WLABEL 0x02 /* label area is writable */
262#define RAIDF_LABELLING 0x04 /* unit is currently being labelled */ 262#define RAIDF_LABELLING 0x04 /* unit is currently being labelled */
 263#define RAIDF_SHUTDOWN 0x08 /* unit is being shutdown */
263#define RAIDF_WANTED 0x40 /* someone is waiting to obtain a lock */ 264#define RAIDF_WANTED 0x40 /* someone is waiting to obtain a lock */
264#define RAIDF_LOCKED 0x80 /* unit is locked */ 265#define RAIDF_LOCKED 0x80 /* unit is locked */
265 266
266#define raidunit(x) DISKUNIT(x) 267#define raidunit(x) DISKUNIT(x)
267int numraid = 0; 268int numraid = 0;
268 269
269extern struct cfdriver raid_cd; 270extern struct cfdriver raid_cd;
270CFATTACH_DECL_NEW(raid, sizeof(struct raid_softc), 271CFATTACH_DECL3_NEW(raid, sizeof(struct raid_softc),
271 raid_match, raid_attach, raid_detach, NULL); 272 raid_match, raid_attach, raid_detach, NULL, NULL, NULL,
 273 DVF_DETACH_SHUTDOWN);
272 274
273/* 275/*
274 * Allow RAIDOUTSTANDING number of simultaneous IO's to this RAID device. 276 * Allow RAIDOUTSTANDING number of simultaneous IO's to this RAID device.
275 * Be aware that large numbers can allow the driver to consume a lot of 277 * Be aware that large numbers can allow the driver to consume a lot of
276 * kernel memory, especially on writes, and in degraded mode reads. 278 * kernel memory, especially on writes, and in degraded mode reads.
277 * 279 *
278 * For example: with a stripe width of 64 blocks (32k) and 5 disks, 280 * For example: with a stripe width of 64 blocks (32k) and 5 disks,
279 * a single 64K write will typically require 64K for the old data, 281 * a single 64K write will typically require 64K for the old data,
280 * 64K for the old parity, and 64K for the new parity, for a total 282 * 64K for the old parity, and 64K for the new parity, for a total
281 * of 192K (if the parity buffer is not re-used immediately). 283 * of 192K (if the parity buffer is not re-used immediately).
282 * Even it if is used immediately, that's still 128K, which when multiplied 284 * Even it if is used immediately, that's still 128K, which when multiplied
283 * by say 10 requests, is 1280K, *on top* of the 640K of incoming data. 285 * by say 10 requests, is 1280K, *on top* of the 640K of incoming data.
284 * 286 *
285 * Now in degraded mode, for example, a 64K read on the above setup may 287 * Now in degraded mode, for example, a 64K read on the above setup may
286 * require data reconstruction, which will require *all* of the 4 remaining 288 * require data reconstruction, which will require *all* of the 4 remaining
287 * disks to participate -- 4 * 32K/disk == 128K again. 289 * disks to participate -- 4 * 32K/disk == 128K again.
288 */ 290 */
289 291
290#ifndef RAIDOUTSTANDING 292#ifndef RAIDOUTSTANDING
291#define RAIDOUTSTANDING 6 293#define RAIDOUTSTANDING 6
292#endif 294#endif
293 295
294#define RAIDLABELDEV(dev) \ 296#define RAIDLABELDEV(dev) \
295 (MAKEDISKDEV(major((dev)), raidunit((dev)), RAW_PART)) 297 (MAKEDISKDEV(major((dev)), raidunit((dev)), RAW_PART))
296 298
297/* declared here, and made public, for the benefit of KVM stuff.. */ 299/* declared here, and made public, for the benefit of KVM stuff.. */
298struct raid_softc *raid_softc; 300struct raid_softc *raid_softc;
299 301
300static void raidgetdefaultlabel(RF_Raid_t *, struct raid_softc *, 302static void raidgetdefaultlabel(RF_Raid_t *, struct raid_softc *,
301 struct disklabel *); 303 struct disklabel *);
302static void raidgetdisklabel(dev_t); 304static void raidgetdisklabel(dev_t);
303static void raidmakedisklabel(struct raid_softc *); 305static void raidmakedisklabel(struct raid_softc *);
304 306
305static int raidlock(struct raid_softc *); 307static int raidlock(struct raid_softc *);
306static void raidunlock(struct raid_softc *); 308static void raidunlock(struct raid_softc *);
307 309
 310static int raid_detach_unlocked(struct raid_softc *);
 311
308static void rf_markalldirty(RF_Raid_t *); 312static void rf_markalldirty(RF_Raid_t *);
309static void rf_set_properties(struct raid_softc *, RF_Raid_t *); 313static void rf_set_properties(struct raid_softc *, RF_Raid_t *);
310 314
311void rf_ReconThread(struct rf_recon_req *); 315void rf_ReconThread(struct rf_recon_req *);
312void rf_RewriteParityThread(RF_Raid_t *raidPtr); 316void rf_RewriteParityThread(RF_Raid_t *raidPtr);
313void rf_CopybackThread(RF_Raid_t *raidPtr); 317void rf_CopybackThread(RF_Raid_t *raidPtr);
314void rf_ReconstructInPlaceThread(struct rf_recon_req *); 318void rf_ReconstructInPlaceThread(struct rf_recon_req *);
315int rf_autoconfig(device_t); 319int rf_autoconfig(device_t);
316void rf_buildroothack(RF_ConfigSet_t *); 320void rf_buildroothack(RF_ConfigSet_t *);
317 321
318RF_AutoConfig_t *rf_find_raid_components(void); 322RF_AutoConfig_t *rf_find_raid_components(void);
319RF_ConfigSet_t *rf_create_auto_sets(RF_AutoConfig_t *); 323RF_ConfigSet_t *rf_create_auto_sets(RF_AutoConfig_t *);
320static int rf_does_it_fit(RF_ConfigSet_t *,RF_AutoConfig_t *); 324static int rf_does_it_fit(RF_ConfigSet_t *,RF_AutoConfig_t *);
321static int rf_reasonable_label(RF_ComponentLabel_t *); 325static int rf_reasonable_label(RF_ComponentLabel_t *);
322void rf_create_configuration(RF_AutoConfig_t *,RF_Config_t *, RF_Raid_t *); 326void rf_create_configuration(RF_AutoConfig_t *,RF_Config_t *, RF_Raid_t *);
323int rf_set_autoconfig(RF_Raid_t *, int); 327int rf_set_autoconfig(RF_Raid_t *, int);
324int rf_set_rootpartition(RF_Raid_t *, int); 328int rf_set_rootpartition(RF_Raid_t *, int);
325void rf_release_all_vps(RF_ConfigSet_t *); 329void rf_release_all_vps(RF_ConfigSet_t *);
326void rf_cleanup_config_set(RF_ConfigSet_t *); 330void rf_cleanup_config_set(RF_ConfigSet_t *);
327int rf_have_enough_components(RF_ConfigSet_t *); 331int rf_have_enough_components(RF_ConfigSet_t *);
328int rf_auto_config_set(RF_ConfigSet_t *, int *); 332int rf_auto_config_set(RF_ConfigSet_t *, int *);
329static int rf_sync_component_caches(RF_Raid_t *raidPtr); 333static int rf_sync_component_caches(RF_Raid_t *raidPtr);
330 334
331static int raidautoconfig = 0; /* Debugging, mostly. Set to 0 to not 335static int raidautoconfig = 0; /* Debugging, mostly. Set to 0 to not
332 allow autoconfig to take place. 336 allow autoconfig to take place.
333 Note that this is overridden by having 337 Note that this is overridden by having
334 RAID_AUTOCONFIG as an option in the 338 RAID_AUTOCONFIG as an option in the
335 kernel config file. */ 339 kernel config file. */
336 340
337struct RF_Pools_s rf_pools; 341struct RF_Pools_s rf_pools;
338 342
339void 343void
340raidattach(int num) 344raidattach(int num)
341{ 345{
342 int raidID; 346 int raidID;
343 int i, rc; 347 int i, rc;
344 348
345 aprint_debug("raidattach: Asked for %d units\n", num); 349 aprint_debug("raidattach: Asked for %d units\n", num);
346 350
347 if (num <= 0) { 351 if (num <= 0) {
348#ifdef DIAGNOSTIC 352#ifdef DIAGNOSTIC
349 panic("raidattach: count <= 0"); 353 panic("raidattach: count <= 0");
350#endif 354#endif
351 return; 355 return;
352 } 356 }
353 /* This is where all the initialization stuff gets done. */ 357 /* This is where all the initialization stuff gets done. */
354 358
355 numraid = num; 359 numraid = num;
356 360
357 /* Make some space for requested number of units... */ 361 /* Make some space for requested number of units... */
358 362
359 RF_Malloc(raidPtrs, num * sizeof(RF_Raid_t *), (RF_Raid_t **)); 363 RF_Malloc(raidPtrs, num * sizeof(RF_Raid_t *), (RF_Raid_t **));
360 if (raidPtrs == NULL) { 364 if (raidPtrs == NULL) {
361 panic("raidPtrs is NULL!!"); 365 panic("raidPtrs is NULL!!");
362 } 366 }
363 367
364#if (RF_INCLUDE_PARITY_DECLUSTERING_DS > 0) 368#if (RF_INCLUDE_PARITY_DECLUSTERING_DS > 0)
365 rf_mutex_init(&rf_sparet_wait_mutex); 369 rf_mutex_init(&rf_sparet_wait_mutex);
366 370
367 rf_sparet_wait_queue = rf_sparet_resp_queue = NULL; 371 rf_sparet_wait_queue = rf_sparet_resp_queue = NULL;
368#endif 372#endif
369 373
370 for (i = 0; i < num; i++) 374 for (i = 0; i < num; i++)
371 raidPtrs[i] = NULL; 375 raidPtrs[i] = NULL;
372 rc = rf_BootRaidframe(); 376 rc = rf_BootRaidframe();
373 if (rc == 0) 377 if (rc == 0)
374 aprint_normal("Kernelized RAIDframe activated\n"); 378 aprint_normal("Kernelized RAIDframe activated\n");
375 else 379 else
376 panic("Serious error booting RAID!!"); 380 panic("Serious error booting RAID!!");
377 381
378 /* put together some datastructures like the CCD device does.. This 382 /* put together some datastructures like the CCD device does.. This
379 * lets us lock the device and what-not when it gets opened. */ 383 * lets us lock the device and what-not when it gets opened. */
380 384
381 raid_softc = (struct raid_softc *) 385 raid_softc = (struct raid_softc *)
382 malloc(num * sizeof(struct raid_softc), 386 malloc(num * sizeof(struct raid_softc),
383 M_RAIDFRAME, M_NOWAIT); 387 M_RAIDFRAME, M_NOWAIT);
384 if (raid_softc == NULL) { 388 if (raid_softc == NULL) {
385 aprint_error("WARNING: no memory for RAIDframe driver\n"); 389 aprint_error("WARNING: no memory for RAIDframe driver\n");
386 return; 390 return;
387 } 391 }
388 392
389 memset(raid_softc, 0, num * sizeof(struct raid_softc)); 393 memset(raid_softc, 0, num * sizeof(struct raid_softc));
390 394
391 for (raidID = 0; raidID < num; raidID++) { 395 for (raidID = 0; raidID < num; raidID++) {
392 bufq_alloc(&raid_softc[raidID].buf_queue, "fcfs", 0); 396 bufq_alloc(&raid_softc[raidID].buf_queue, "fcfs", 0);
393 397
394 RF_Malloc(raidPtrs[raidID], sizeof(RF_Raid_t), 398 RF_Malloc(raidPtrs[raidID], sizeof(RF_Raid_t),
395 (RF_Raid_t *)); 399 (RF_Raid_t *));
396 if (raidPtrs[raidID] == NULL) { 400 if (raidPtrs[raidID] == NULL) {
397 aprint_error("WARNING: raidPtrs[%d] is NULL\n", raidID); 401 aprint_error("WARNING: raidPtrs[%d] is NULL\n", raidID);
398 numraid = raidID; 402 numraid = raidID;
399 return; 403 return;
400 } 404 }
401 } 405 }
402 406
403 if (config_cfattach_attach(raid_cd.cd_name, &raid_ca)) { 407 if (config_cfattach_attach(raid_cd.cd_name, &raid_ca)) {
404 aprint_error("raidattach: config_cfattach_attach failed?\n"); 408 aprint_error("raidattach: config_cfattach_attach failed?\n");
405 } 409 }
406 410
407#ifdef RAID_AUTOCONFIG 411#ifdef RAID_AUTOCONFIG
408 raidautoconfig = 1; 412 raidautoconfig = 1;
409#endif 413#endif
410 414
411 /* 415 /*
412 * Register a finalizer which will be used to auto-config RAID 416 * Register a finalizer which will be used to auto-config RAID
413 * sets once all real hardware devices have been found. 417 * sets once all real hardware devices have been found.
414 */ 418 */
415 if (config_finalize_register(NULL, rf_autoconfig) != 0) 419 if (config_finalize_register(NULL, rf_autoconfig) != 0)
416 aprint_error("WARNING: unable to register RAIDframe finalizer\n"); 420 aprint_error("WARNING: unable to register RAIDframe finalizer\n");
417} 421}
418 422
419int 423int
420rf_autoconfig(device_t self) 424rf_autoconfig(device_t self)
421{ 425{
422 RF_AutoConfig_t *ac_list; 426 RF_AutoConfig_t *ac_list;
423 RF_ConfigSet_t *config_sets; 427 RF_ConfigSet_t *config_sets;
424 428
425 if (raidautoconfig == 0) 429 if (raidautoconfig == 0)
426 return (0); 430 return (0);
427 431
428 /* XXX This code can only be run once. */ 432 /* XXX This code can only be run once. */
429 raidautoconfig = 0; 433 raidautoconfig = 0;
430 434
431 /* 1. locate all RAID components on the system */ 435 /* 1. locate all RAID components on the system */
432 aprint_debug("Searching for RAID components...\n"); 436 aprint_debug("Searching for RAID components...\n");
433 ac_list = rf_find_raid_components(); 437 ac_list = rf_find_raid_components();
434 438
435 /* 2. Sort them into their respective sets. */ 439 /* 2. Sort them into their respective sets. */
436 config_sets = rf_create_auto_sets(ac_list); 440 config_sets = rf_create_auto_sets(ac_list);
437 441
438 /* 442 /*
439 * 3. Evaluate each set andconfigure the valid ones. 443 * 3. Evaluate each set andconfigure the valid ones.
440 * This gets done in rf_buildroothack(). 444 * This gets done in rf_buildroothack().
441 */ 445 */
442 rf_buildroothack(config_sets); 446 rf_buildroothack(config_sets);
443 447
444 return 1; 448 return 1;
445} 449}
446 450
447void 451void
448rf_buildroothack(RF_ConfigSet_t *config_sets) 452rf_buildroothack(RF_ConfigSet_t *config_sets)
449{ 453{
450 RF_ConfigSet_t *cset; 454 RF_ConfigSet_t *cset;
451 RF_ConfigSet_t *next_cset; 455 RF_ConfigSet_t *next_cset;
452 int retcode; 456 int retcode;
453 int raidID; 457 int raidID;
454 int rootID; 458 int rootID;
455 int col; 459 int col;
456 int num_root; 460 int num_root;
457 char *devname; 461 char *devname;
458 462
459 rootID = 0; 463 rootID = 0;
460 num_root = 0; 464 num_root = 0;
461 cset = config_sets; 465 cset = config_sets;
462 while(cset != NULL ) { 466 while(cset != NULL ) {
463 next_cset = cset->next; 467 next_cset = cset->next;
464 if (rf_have_enough_components(cset) && 468 if (rf_have_enough_components(cset) &&
465 cset->ac->clabel->autoconfigure==1) { 469 cset->ac->clabel->autoconfigure==1) {
466 retcode = rf_auto_config_set(cset,&raidID); 470 retcode = rf_auto_config_set(cset,&raidID);
467 if (!retcode) { 471 if (!retcode) {
468 aprint_debug("raid%d: configured ok\n", raidID); 472 aprint_debug("raid%d: configured ok\n", raidID);
469 if (cset->rootable) { 473 if (cset->rootable) {
470 rootID = raidID; 474 rootID = raidID;
471 num_root++; 475 num_root++;
472 } 476 }
473 } else { 477 } else {
474 /* The autoconfig didn't work :( */ 478 /* The autoconfig didn't work :( */
475 aprint_debug("Autoconfig failed with code %d for raid%d\n", retcode, raidID); 479 aprint_debug("Autoconfig failed with code %d for raid%d\n", retcode, raidID);
476 rf_release_all_vps(cset); 480 rf_release_all_vps(cset);
477 } 481 }
478 } else { 482 } else {
479 /* we're not autoconfiguring this set... 483 /* we're not autoconfiguring this set...
480 release the associated resources */ 484 release the associated resources */
481 rf_release_all_vps(cset); 485 rf_release_all_vps(cset);
482 } 486 }
483 /* cleanup */ 487 /* cleanup */
484 rf_cleanup_config_set(cset); 488 rf_cleanup_config_set(cset);
485 cset = next_cset; 489 cset = next_cset;
486 } 490 }
487 491
488 /* if the user has specified what the root device should be 492 /* if the user has specified what the root device should be
489 then we don't touch booted_device or boothowto... */ 493 then we don't touch booted_device or boothowto... */
490 494
491 if (rootspec != NULL) 495 if (rootspec != NULL)
492 return; 496 return;
493 497
494 /* we found something bootable... */ 498 /* we found something bootable... */
495 499
496 if (num_root == 1) { 500 if (num_root == 1) {
497 booted_device = raid_softc[rootID].sc_dev; 501 booted_device = raid_softc[rootID].sc_dev;
498 } else if (num_root > 1) { 502 } else if (num_root > 1) {
499 503
500 /*  504 /*
501 * Maybe the MD code can help. If it cannot, then 505 * Maybe the MD code can help. If it cannot, then
502 * setroot() will discover that we have no 506 * setroot() will discover that we have no
503 * booted_device and will ask the user if nothing was 507 * booted_device and will ask the user if nothing was
504 * hardwired in the kernel config file  508 * hardwired in the kernel config file
505 */ 509 */
506 510
507 if (booted_device == NULL) 511 if (booted_device == NULL)
508 cpu_rootconf(); 512 cpu_rootconf();
509 if (booted_device == NULL)  513 if (booted_device == NULL)
510 return; 514 return;
511 515
512 num_root = 0; 516 num_root = 0;
513 for (raidID = 0; raidID < numraid; raidID++) { 517 for (raidID = 0; raidID < numraid; raidID++) {
514 if (raidPtrs[raidID]->valid == 0) 518 if (raidPtrs[raidID]->valid == 0)
515 continue; 519 continue;
516 520
517 if (raidPtrs[raidID]->root_partition == 0) 521 if (raidPtrs[raidID]->root_partition == 0)
518 continue; 522 continue;
519 523
520 for (col = 0; col < raidPtrs[raidID]->numCol; col++) { 524 for (col = 0; col < raidPtrs[raidID]->numCol; col++) {
521 devname = raidPtrs[raidID]->Disks[col].devname; 525 devname = raidPtrs[raidID]->Disks[col].devname;
522 devname += sizeof("/dev/") - 1; 526 devname += sizeof("/dev/") - 1;
523 if (strncmp(devname, device_xname(booted_device),  527 if (strncmp(devname, device_xname(booted_device),
524 strlen(device_xname(booted_device))) != 0) 528 strlen(device_xname(booted_device))) != 0)
525 continue; 529 continue;
526 aprint_debug("raid%d includes boot device %s\n", 530 aprint_debug("raid%d includes boot device %s\n",
527 raidID, devname); 531 raidID, devname);
528 num_root++; 532 num_root++;
529 rootID = raidID; 533 rootID = raidID;
530 } 534 }
531 } 535 }
532  536
533 if (num_root == 1) { 537 if (num_root == 1) {
534 booted_device = raid_softc[rootID].sc_dev; 538 booted_device = raid_softc[rootID].sc_dev;
535 } else { 539 } else {
536 /* we can't guess.. require the user to answer... */ 540 /* we can't guess.. require the user to answer... */
537 boothowto |= RB_ASKNAME; 541 boothowto |= RB_ASKNAME;
538 } 542 }
539 } 543 }
540} 544}
541 545
542 546
543int 547int
544raidsize(dev_t dev) 548raidsize(dev_t dev)
545{ 549{
546 struct raid_softc *rs; 550 struct raid_softc *rs;
547 struct disklabel *lp; 551 struct disklabel *lp;
548 int part, unit, omask, size; 552 int part, unit, omask, size;
549 553
550 unit = raidunit(dev); 554 unit = raidunit(dev);
551 if (unit >= numraid) 555 if (unit >= numraid)
552 return (-1); 556 return (-1);
553 rs = &raid_softc[unit]; 557 rs = &raid_softc[unit];
554 558
555 if ((rs->sc_flags & RAIDF_INITED) == 0) 559 if ((rs->sc_flags & RAIDF_INITED) == 0)
556 return (-1); 560 return (-1);
557 561
558 part = DISKPART(dev); 562 part = DISKPART(dev);
559 omask = rs->sc_dkdev.dk_openmask & (1 << part); 563 omask = rs->sc_dkdev.dk_openmask & (1 << part);
560 lp = rs->sc_dkdev.dk_label; 564 lp = rs->sc_dkdev.dk_label;
561 565
562 if (omask == 0 && raidopen(dev, 0, S_IFBLK, curlwp)) 566 if (omask == 0 && raidopen(dev, 0, S_IFBLK, curlwp))
563 return (-1); 567 return (-1);
564 568
565 if (lp->d_partitions[part].p_fstype != FS_SWAP) 569 if (lp->d_partitions[part].p_fstype != FS_SWAP)
566 size = -1; 570 size = -1;
567 else 571 else
568 size = lp->d_partitions[part].p_size * 572 size = lp->d_partitions[part].p_size *
569 (lp->d_secsize / DEV_BSIZE); 573 (lp->d_secsize / DEV_BSIZE);
570 574
571 if (omask == 0 && raidclose(dev, 0, S_IFBLK, curlwp)) 575 if (omask == 0 && raidclose(dev, 0, S_IFBLK, curlwp))
572 return (-1); 576 return (-1);
573 577
574 return (size); 578 return (size);
575 579
576} 580}
577 581
578int 582int
579raiddump(dev_t dev, daddr_t blkno, void *va, size_t size) 583raiddump(dev_t dev, daddr_t blkno, void *va, size_t size)
580{ 584{
581 int unit = raidunit(dev); 585 int unit = raidunit(dev);
582 struct raid_softc *rs; 586 struct raid_softc *rs;
583 const struct bdevsw *bdev; 587 const struct bdevsw *bdev;
584 struct disklabel *lp; 588 struct disklabel *lp;
585 RF_Raid_t *raidPtr; 589 RF_Raid_t *raidPtr;
586 daddr_t offset; 590 daddr_t offset;
587 int part, c, sparecol, j, scol, dumpto; 591 int part, c, sparecol, j, scol, dumpto;
588 int error = 0; 592 int error = 0;
589 593
590 if (unit >= numraid) 594 if (unit >= numraid)
591 return (ENXIO); 595 return (ENXIO);
592 596
593 rs = &raid_softc[unit]; 597 rs = &raid_softc[unit];
594 raidPtr = raidPtrs[unit]; 598 raidPtr = raidPtrs[unit];
595 599
596 if ((rs->sc_flags & RAIDF_INITED) == 0) 600 if ((rs->sc_flags & RAIDF_INITED) == 0)
597 return ENXIO; 601 return ENXIO;
598 602
599 /* we only support dumping to RAID 1 sets */ 603 /* we only support dumping to RAID 1 sets */
600 if (raidPtr->Layout.numDataCol != 1 ||  604 if (raidPtr->Layout.numDataCol != 1 ||
601 raidPtr->Layout.numParityCol != 1) 605 raidPtr->Layout.numParityCol != 1)
602 return EINVAL; 606 return EINVAL;
603 607
604 608
605 if ((error = raidlock(rs)) != 0) 609 if ((error = raidlock(rs)) != 0)
606 return error; 610 return error;
607 611
608 if (size % DEV_BSIZE != 0) { 612 if (size % DEV_BSIZE != 0) {
609 error = EINVAL; 613 error = EINVAL;
610 goto out; 614 goto out;
611 } 615 }
612 616
613 if (blkno + size / DEV_BSIZE > rs->sc_size) { 617 if (blkno + size / DEV_BSIZE > rs->sc_size) {
614 printf("%s: blkno (%" PRIu64 ") + size / DEV_BSIZE (%zu) > " 618 printf("%s: blkno (%" PRIu64 ") + size / DEV_BSIZE (%zu) > "
615 "sc->sc_size (%" PRIu64 ")\n", __func__, blkno, 619 "sc->sc_size (%" PRIu64 ")\n", __func__, blkno,
616 size / DEV_BSIZE, rs->sc_size); 620 size / DEV_BSIZE, rs->sc_size);
617 error = EINVAL; 621 error = EINVAL;
618 goto out; 622 goto out;
619 } 623 }
620 624
621 part = DISKPART(dev); 625 part = DISKPART(dev);
622 lp = rs->sc_dkdev.dk_label; 626 lp = rs->sc_dkdev.dk_label;
623 offset = lp->d_partitions[part].p_offset + RF_PROTECTED_SECTORS; 627 offset = lp->d_partitions[part].p_offset + RF_PROTECTED_SECTORS;
624 628
625 /* figure out what device is alive.. */ 629 /* figure out what device is alive.. */
626 630
627 /*  631 /*
628 Look for a component to dump to. The preference for the 632 Look for a component to dump to. The preference for the
629 component to dump to is as follows: 633 component to dump to is as follows:
630 1) the master 634 1) the master
631 2) a used_spare of the master 635 2) a used_spare of the master
632 3) the slave 636 3) the slave
633 4) a used_spare of the slave 637 4) a used_spare of the slave
634 */ 638 */
635 639
636 dumpto = -1; 640 dumpto = -1;
637 for (c = 0; c < raidPtr->numCol; c++) { 641 for (c = 0; c < raidPtr->numCol; c++) {
638 if (raidPtr->Disks[c].status == rf_ds_optimal) { 642 if (raidPtr->Disks[c].status == rf_ds_optimal) {
639 /* this might be the one */ 643 /* this might be the one */
640 dumpto = c; 644 dumpto = c;
641 break; 645 break;
642 } 646 }
643 } 647 }
644  648
645 /*  649 /*
646 At this point we have possibly selected a live master or a 650 At this point we have possibly selected a live master or a
647 live slave. We now check to see if there is a spared 651 live slave. We now check to see if there is a spared
648 master (or a spared slave), if we didn't find a live master 652 master (or a spared slave), if we didn't find a live master
649 or a live slave.  653 or a live slave.
650 */ 654 */
651 655
652 for (c = 0; c < raidPtr->numSpare; c++) { 656 for (c = 0; c < raidPtr->numSpare; c++) {
653 sparecol = raidPtr->numCol + c; 657 sparecol = raidPtr->numCol + c;
654 if (raidPtr->Disks[sparecol].status == rf_ds_used_spare) { 658 if (raidPtr->Disks[sparecol].status == rf_ds_used_spare) {
655 /* How about this one? */ 659 /* How about this one? */
656 scol = -1; 660 scol = -1;
657 for(j=0;j<raidPtr->numCol;j++) { 661 for(j=0;j<raidPtr->numCol;j++) {
658 if (raidPtr->Disks[j].spareCol == sparecol) { 662 if (raidPtr->Disks[j].spareCol == sparecol) {
659 scol = j; 663 scol = j;
660 break; 664 break;
661 } 665 }
662 } 666 }
663 if (scol == 0) { 667 if (scol == 0) {
664 /*  668 /*
665 We must have found a spared master! 669 We must have found a spared master!
666 We'll take that over anything else 670 We'll take that over anything else
667 found so far. (We couldn't have 671 found so far. (We couldn't have
668 found a real master before, since 672 found a real master before, since
669 this is a used spare, and it's 673 this is a used spare, and it's
670 saying that it's replacing the 674 saying that it's replacing the
671 master.) On reboot (with 675 master.) On reboot (with
672 autoconfiguration turned on) 676 autoconfiguration turned on)
673 sparecol will become the 1st 677 sparecol will become the 1st
674 component (component0) of this set.  678 component (component0) of this set.
675 */ 679 */
676 dumpto = sparecol; 680 dumpto = sparecol;
677 break; 681 break;
678 } else if (scol != -1) { 682 } else if (scol != -1) {
679 /*  683 /*
680 Must be a spared slave. We'll dump 684 Must be a spared slave. We'll dump
681 to that if we havn't found anything 685 to that if we havn't found anything
682 else so far.  686 else so far.
683 */ 687 */
684 if (dumpto == -1) 688 if (dumpto == -1)
685 dumpto = sparecol; 689 dumpto = sparecol;
686 } 690 }
687 } 691 }
688 } 692 }
689  693
690 if (dumpto == -1) { 694 if (dumpto == -1) {
691 /* we couldn't find any live components to dump to!?!? 695 /* we couldn't find any live components to dump to!?!?
692 */ 696 */
693 error = EINVAL; 697 error = EINVAL;
694 goto out; 698 goto out;
695 } 699 }
696 700
697 bdev = bdevsw_lookup(raidPtr->Disks[dumpto].dev); 701 bdev = bdevsw_lookup(raidPtr->Disks[dumpto].dev);
698 702
699 /*  703 /*
700 Note that blkno is relative to this particular partition. 704 Note that blkno is relative to this particular partition.
701 By adding the offset of this partition in the RAID 705 By adding the offset of this partition in the RAID
702 set, and also adding RF_PROTECTED_SECTORS, we get a 706 set, and also adding RF_PROTECTED_SECTORS, we get a
703 value that is relative to the partition used for the 707 value that is relative to the partition used for the
704 underlying component. 708 underlying component.
705 */ 709 */
706  710
707 error = (*bdev->d_dump)(raidPtr->Disks[dumpto].dev,  711 error = (*bdev->d_dump)(raidPtr->Disks[dumpto].dev,
708 blkno + offset, va, size); 712 blkno + offset, va, size);
709  713
710out: 714out:
711 raidunlock(rs); 715 raidunlock(rs);
712  716
713 return error; 717 return error;
714} 718}
715/* ARGSUSED */ 719/* ARGSUSED */
716int 720int
717raidopen(dev_t dev, int flags, int fmt, 721raidopen(dev_t dev, int flags, int fmt,
718 struct lwp *l) 722 struct lwp *l)
719{ 723{
720 int unit = raidunit(dev); 724 int unit = raidunit(dev);
721 struct raid_softc *rs; 725 struct raid_softc *rs;
722 struct disklabel *lp; 726 struct disklabel *lp;
723 int part, pmask; 727 int part, pmask;
724 int error = 0; 728 int error = 0;
725 729
726 if (unit >= numraid) 730 if (unit >= numraid)
727 return (ENXIO); 731 return (ENXIO);
728 rs = &raid_softc[unit]; 732 rs = &raid_softc[unit];
729 733
730 if ((error = raidlock(rs)) != 0) 734 if ((error = raidlock(rs)) != 0)
731 return (error); 735 return (error);
 736
 737 if ((rs->sc_flags & RAIDF_SHUTDOWN) != 0) {
 738 error = EBUSY;
 739 goto bad;
 740 }
 741
732 lp = rs->sc_dkdev.dk_label; 742 lp = rs->sc_dkdev.dk_label;
733 743
734 part = DISKPART(dev); 744 part = DISKPART(dev);
735 745
736 /* 746 /*
737 * If there are wedges, and this is not RAW_PART, then we 747 * If there are wedges, and this is not RAW_PART, then we
738 * need to fail. 748 * need to fail.
739 */ 749 */
740 if (rs->sc_dkdev.dk_nwedges != 0 && part != RAW_PART) { 750 if (rs->sc_dkdev.dk_nwedges != 0 && part != RAW_PART) {
741 error = EBUSY; 751 error = EBUSY;
742 goto bad; 752 goto bad;
743 } 753 }
744 pmask = (1 << part); 754 pmask = (1 << part);
745 755
746 if ((rs->sc_flags & RAIDF_INITED) && 756 if ((rs->sc_flags & RAIDF_INITED) &&
747 (rs->sc_dkdev.dk_openmask == 0)) 757 (rs->sc_dkdev.dk_openmask == 0))
748 raidgetdisklabel(dev); 758 raidgetdisklabel(dev);
749 759
750 /* make sure that this partition exists */ 760 /* make sure that this partition exists */
751 761
752 if (part != RAW_PART) { 762 if (part != RAW_PART) {
753 if (((rs->sc_flags & RAIDF_INITED) == 0) || 763 if (((rs->sc_flags & RAIDF_INITED) == 0) ||
754 ((part >= lp->d_npartitions) || 764 ((part >= lp->d_npartitions) ||
755 (lp->d_partitions[part].p_fstype == FS_UNUSED))) { 765 (lp->d_partitions[part].p_fstype == FS_UNUSED))) {
756 error = ENXIO; 766 error = ENXIO;
757 goto bad; 767 goto bad;
758 } 768 }
759 } 769 }
760 /* Prevent this unit from being unconfigured while open. */ 770 /* Prevent this unit from being unconfigured while open. */
761 switch (fmt) { 771 switch (fmt) {
762 case S_IFCHR: 772 case S_IFCHR:
763 rs->sc_dkdev.dk_copenmask |= pmask; 773 rs->sc_dkdev.dk_copenmask |= pmask;
764 break; 774 break;
765 775
766 case S_IFBLK: 776 case S_IFBLK:
767 rs->sc_dkdev.dk_bopenmask |= pmask; 777 rs->sc_dkdev.dk_bopenmask |= pmask;
768 break; 778 break;
769 } 779 }
770 780
771 if ((rs->sc_dkdev.dk_openmask == 0) && 781 if ((rs->sc_dkdev.dk_openmask == 0) &&
772 ((rs->sc_flags & RAIDF_INITED) != 0)) { 782 ((rs->sc_flags & RAIDF_INITED) != 0)) {
773 /* First one... mark things as dirty... Note that we *MUST* 783 /* First one... mark things as dirty... Note that we *MUST*
774 have done a configure before this. I DO NOT WANT TO BE 784 have done a configure before this. I DO NOT WANT TO BE
775 SCRIBBLING TO RANDOM COMPONENTS UNTIL IT'S BEEN DETERMINED 785 SCRIBBLING TO RANDOM COMPONENTS UNTIL IT'S BEEN DETERMINED
776 THAT THEY BELONG TOGETHER!!!!! */ 786 THAT THEY BELONG TOGETHER!!!!! */
777 /* XXX should check to see if we're only open for reading 787 /* XXX should check to see if we're only open for reading
778 here... If so, we needn't do this, but then need some 788 here... If so, we needn't do this, but then need some
779 other way of keeping track of what's happened.. */ 789 other way of keeping track of what's happened.. */
780 790
781 rf_markalldirty( raidPtrs[unit] ); 791 rf_markalldirty( raidPtrs[unit] );
782 } 792 }
783 793
784 794
785 rs->sc_dkdev.dk_openmask = 795 rs->sc_dkdev.dk_openmask =
786 rs->sc_dkdev.dk_copenmask | rs->sc_dkdev.dk_bopenmask; 796 rs->sc_dkdev.dk_copenmask | rs->sc_dkdev.dk_bopenmask;
787 797
788bad: 798bad:
789 raidunlock(rs); 799 raidunlock(rs);
790 800
791 return (error); 801 return (error);
792 802
793 803
794} 804}
795/* ARGSUSED */ 805/* ARGSUSED */
796int 806int
797raidclose(dev_t dev, int flags, int fmt, struct lwp *l) 807raidclose(dev_t dev, int flags, int fmt, struct lwp *l)
798{ 808{
799 int unit = raidunit(dev); 809 int unit = raidunit(dev);
800 cfdata_t cf; 
801 struct raid_softc *rs; 810 struct raid_softc *rs;
802 int error = 0; 811 int error = 0;
803 int part; 812 int part;
804 813
805 if (unit >= numraid) 814 if (unit >= numraid)
806 return (ENXIO); 815 return (ENXIO);
807 rs = &raid_softc[unit]; 816 rs = &raid_softc[unit];
808 817
809 if ((error = raidlock(rs)) != 0) 818 if ((error = raidlock(rs)) != 0)
810 return (error); 819 return (error);
811 820
812 part = DISKPART(dev); 821 part = DISKPART(dev);
813 822
814 /* ...that much closer to allowing unconfiguration... */ 823 /* ...that much closer to allowing unconfiguration... */
815 switch (fmt) { 824 switch (fmt) {
816 case S_IFCHR: 825 case S_IFCHR:
817 rs->sc_dkdev.dk_copenmask &= ~(1 << part); 826 rs->sc_dkdev.dk_copenmask &= ~(1 << part);
818 break; 827 break;
819 828
820 case S_IFBLK: 829 case S_IFBLK:
821 rs->sc_dkdev.dk_bopenmask &= ~(1 << part); 830 rs->sc_dkdev.dk_bopenmask &= ~(1 << part);
822 break; 831 break;
823 } 832 }
824 rs->sc_dkdev.dk_openmask = 833 rs->sc_dkdev.dk_openmask =
825 rs->sc_dkdev.dk_copenmask | rs->sc_dkdev.dk_bopenmask; 834 rs->sc_dkdev.dk_copenmask | rs->sc_dkdev.dk_bopenmask;
826 835
827 if ((rs->sc_dkdev.dk_openmask == 0) && 836 if ((rs->sc_dkdev.dk_openmask == 0) &&
828 ((rs->sc_flags & RAIDF_INITED) != 0)) { 837 ((rs->sc_flags & RAIDF_INITED) != 0)) {
829 /* Last one... device is not unconfigured yet. 838 /* Last one... device is not unconfigured yet.
830 Device shutdown has taken care of setting the 839 Device shutdown has taken care of setting the
831 clean bits if RAIDF_INITED is not set 840 clean bits if RAIDF_INITED is not set
832 mark things as clean... */ 841 mark things as clean... */
833 842
834 rf_update_component_labels(raidPtrs[unit], 843 rf_update_component_labels(raidPtrs[unit],
835 RF_FINAL_COMPONENT_UPDATE); 844 RF_FINAL_COMPONENT_UPDATE);
836 if (doing_shutdown) { 
837 /* last one, and we're going down, so 
838 lights out for this RAID set too. */ 
839 error = rf_Shutdown(raidPtrs[unit]); 
840 
841 /* It's no longer initialized... */ 
842 rs->sc_flags &= ~RAIDF_INITED; 
843 845
844 /* detach the device */ 846 /* If the kernel is shutting down, it will detach
845  847 * this RAID set soon enough.
846 cf = device_cfdata(rs->sc_dev); 848 */
847 error = config_detach(rs->sc_dev, DETACH_QUIET); 
848 free(cf, M_RAIDFRAME); 
849  
850 /* Detach the disk. */ 
851 disk_detach(&rs->sc_dkdev); 
852 disk_destroy(&rs->sc_dkdev); 
853 } 
854 } 849 }
855 850
856 raidunlock(rs); 851 raidunlock(rs);
857 return (0); 852 return (0);
858 853
859} 854}
860 855
861void 856void
862raidstrategy(struct buf *bp) 857raidstrategy(struct buf *bp)
863{ 858{
864 int s; 859 int s;
865 860
866 unsigned int raidID = raidunit(bp->b_dev); 861 unsigned int raidID = raidunit(bp->b_dev);
867 RF_Raid_t *raidPtr; 862 RF_Raid_t *raidPtr;
868 struct raid_softc *rs = &raid_softc[raidID]; 863 struct raid_softc *rs = &raid_softc[raidID];
869 int wlabel; 864 int wlabel;
870 865
871 if ((rs->sc_flags & RAIDF_INITED) ==0) { 866 if ((rs->sc_flags & RAIDF_INITED) ==0) {
872 bp->b_error = ENXIO; 867 bp->b_error = ENXIO;
873 goto done; 868 goto done;
874 } 869 }
875 if (raidID >= numraid || !raidPtrs[raidID]) { 870 if (raidID >= numraid || !raidPtrs[raidID]) {
876 bp->b_error = ENODEV; 871 bp->b_error = ENODEV;
877 goto done; 872 goto done;
878 } 873 }
879 raidPtr = raidPtrs[raidID]; 874 raidPtr = raidPtrs[raidID];
880 if (!raidPtr->valid) { 875 if (!raidPtr->valid) {
881 bp->b_error = ENODEV; 876 bp->b_error = ENODEV;
882 goto done; 877 goto done;
883 } 878 }
884 if (bp->b_bcount == 0) { 879 if (bp->b_bcount == 0) {
885 db1_printf(("b_bcount is zero..\n")); 880 db1_printf(("b_bcount is zero..\n"));
886 goto done; 881 goto done;
887 } 882 }
888 883
889 /* 884 /*
890 * Do bounds checking and adjust transfer. If there's an 885 * Do bounds checking and adjust transfer. If there's an
891 * error, the bounds check will flag that for us. 886 * error, the bounds check will flag that for us.
892 */ 887 */
893 888
894 wlabel = rs->sc_flags & (RAIDF_WLABEL | RAIDF_LABELLING); 889 wlabel = rs->sc_flags & (RAIDF_WLABEL | RAIDF_LABELLING);
895 if (DISKPART(bp->b_dev) == RAW_PART) { 890 if (DISKPART(bp->b_dev) == RAW_PART) {
896 uint64_t size; /* device size in DEV_BSIZE unit */ 891 uint64_t size; /* device size in DEV_BSIZE unit */
897 892
898 if (raidPtr->logBytesPerSector > DEV_BSHIFT) { 893 if (raidPtr->logBytesPerSector > DEV_BSHIFT) {
899 size = raidPtr->totalSectors << 894 size = raidPtr->totalSectors <<
900 (raidPtr->logBytesPerSector - DEV_BSHIFT); 895 (raidPtr->logBytesPerSector - DEV_BSHIFT);
901 } else { 896 } else {
902 size = raidPtr->totalSectors >> 897 size = raidPtr->totalSectors >>
903 (DEV_BSHIFT - raidPtr->logBytesPerSector); 898 (DEV_BSHIFT - raidPtr->logBytesPerSector);
904 } 899 }
905 if (bounds_check_with_mediasize(bp, DEV_BSIZE, size) <= 0) { 900 if (bounds_check_with_mediasize(bp, DEV_BSIZE, size) <= 0) {
906 goto done; 901 goto done;
907 } 902 }
908 } else { 903 } else {
909 if (bounds_check_with_label(&rs->sc_dkdev, bp, wlabel) <= 0) { 904 if (bounds_check_with_label(&rs->sc_dkdev, bp, wlabel) <= 0) {
910 db1_printf(("Bounds check failed!!:%d %d\n", 905 db1_printf(("Bounds check failed!!:%d %d\n",
911 (int) bp->b_blkno, (int) wlabel)); 906 (int) bp->b_blkno, (int) wlabel));
912 goto done; 907 goto done;
913 } 908 }
914 } 909 }
915 s = splbio(); 910 s = splbio();
916 911
917 bp->b_resid = 0; 912 bp->b_resid = 0;
918 913
919 /* stuff it onto our queue */ 914 /* stuff it onto our queue */
920 bufq_put(rs->buf_queue, bp); 915 bufq_put(rs->buf_queue, bp);
921 916
922 /* scheduled the IO to happen at the next convenient time */ 917 /* scheduled the IO to happen at the next convenient time */
923 wakeup(&(raidPtrs[raidID]->iodone)); 918 wakeup(&(raidPtrs[raidID]->iodone));
924 919
925 splx(s); 920 splx(s);
926 return; 921 return;
927 922
928done: 923done:
929 bp->b_resid = bp->b_bcount; 924 bp->b_resid = bp->b_bcount;
930 biodone(bp); 925 biodone(bp);
931} 926}
932/* ARGSUSED */ 927/* ARGSUSED */
933int 928int
934raidread(dev_t dev, struct uio *uio, int flags) 929raidread(dev_t dev, struct uio *uio, int flags)
935{ 930{
936 int unit = raidunit(dev); 931 int unit = raidunit(dev);
937 struct raid_softc *rs; 932 struct raid_softc *rs;
938 933
939 if (unit >= numraid) 934 if (unit >= numraid)
940 return (ENXIO); 935 return (ENXIO);
941 rs = &raid_softc[unit]; 936 rs = &raid_softc[unit];
942 937
943 if ((rs->sc_flags & RAIDF_INITED) == 0) 938 if ((rs->sc_flags & RAIDF_INITED) == 0)
944 return (ENXIO); 939 return (ENXIO);
945 940
946 return (physio(raidstrategy, NULL, dev, B_READ, minphys, uio)); 941 return (physio(raidstrategy, NULL, dev, B_READ, minphys, uio));
947 942
948} 943}
949/* ARGSUSED */ 944/* ARGSUSED */
950int 945int
951raidwrite(dev_t dev, struct uio *uio, int flags) 946raidwrite(dev_t dev, struct uio *uio, int flags)
952{ 947{
953 int unit = raidunit(dev); 948 int unit = raidunit(dev);
954 struct raid_softc *rs; 949 struct raid_softc *rs;
955 950
956 if (unit >= numraid) 951 if (unit >= numraid)
957 return (ENXIO); 952 return (ENXIO);
958 rs = &raid_softc[unit]; 953 rs = &raid_softc[unit];
959 954
960 if ((rs->sc_flags & RAIDF_INITED) == 0) 955 if ((rs->sc_flags & RAIDF_INITED) == 0)
961 return (ENXIO); 956 return (ENXIO);
962 957
963 return (physio(raidstrategy, NULL, dev, B_WRITE, minphys, uio)); 958 return (physio(raidstrategy, NULL, dev, B_WRITE, minphys, uio));
964 959
965} 960}
966 961
 962static int
 963raid_detach_unlocked(struct raid_softc *rs)
 964{
 965 int error;
 966 RF_Raid_t *raidPtr;
 967
 968 raidPtr = raidPtrs[device_unit(rs->sc_dev)];
 969
 970 /*
 971 * If somebody has a partition mounted, we shouldn't
 972 * shutdown.
 973 */
 974 if (rs->sc_dkdev.dk_openmask != 0)
 975 return EBUSY;
 976
 977 if ((rs->sc_flags & RAIDF_INITED) == 0)
 978 ; /* not initialized: nothing to do */
 979 else if ((error = rf_Shutdown(raidPtr)) != 0)
 980 return error;
 981 else
 982 rs->sc_flags &= ~(RAIDF_INITED|RAIDF_SHUTDOWN);
 983
 984 /* Detach the disk. */
 985 disk_detach(&rs->sc_dkdev);
 986 disk_destroy(&rs->sc_dkdev);
 987
 988 return 0;
 989}
 990
967int 991int
968raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) 992raidioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
969{ 993{
970 int unit = raidunit(dev); 994 int unit = raidunit(dev);
971 int error = 0; 995 int error = 0;
972 int part, pmask; 996 int part, pmask;
973 cfdata_t cf; 997 cfdata_t cf;
974 struct raid_softc *rs; 998 struct raid_softc *rs;
975 RF_Config_t *k_cfg, *u_cfg; 999 RF_Config_t *k_cfg, *u_cfg;
976 RF_Raid_t *raidPtr; 1000 RF_Raid_t *raidPtr;
977 RF_RaidDisk_t *diskPtr; 1001 RF_RaidDisk_t *diskPtr;
978 RF_AccTotals_t *totals; 1002 RF_AccTotals_t *totals;
979 RF_DeviceConfig_t *d_cfg, **ucfgp; 1003 RF_DeviceConfig_t *d_cfg, **ucfgp;
980 u_char *specific_buf; 1004 u_char *specific_buf;
981 int retcode = 0; 1005 int retcode = 0;
982 int column; 1006 int column;
983 int raidid; 1007 int raidid;
984 struct rf_recon_req *rrcopy, *rr; 1008 struct rf_recon_req *rrcopy, *rr;
985 RF_ComponentLabel_t *clabel; 1009 RF_ComponentLabel_t *clabel;
986 RF_ComponentLabel_t *ci_label; 1010 RF_ComponentLabel_t *ci_label;
987 RF_ComponentLabel_t **clabel_ptr; 1011 RF_ComponentLabel_t **clabel_ptr;
988 RF_SingleComponent_t *sparePtr,*componentPtr; 1012 RF_SingleComponent_t *sparePtr,*componentPtr;
989 RF_SingleComponent_t component; 1013 RF_SingleComponent_t component;
990 RF_ProgressInfo_t progressInfo, **progressInfoPtr; 1014 RF_ProgressInfo_t progressInfo, **progressInfoPtr;
991 int i, j, d; 1015 int i, j, d;
992#ifdef __HAVE_OLD_DISKLABEL 1016#ifdef __HAVE_OLD_DISKLABEL
993 struct disklabel newlabel; 1017 struct disklabel newlabel;
994#endif 1018#endif
995 struct dkwedge_info *dkw; 1019 struct dkwedge_info *dkw;
996 1020
997 if (unit >= numraid) 1021 if (unit >= numraid)
998 return (ENXIO); 1022 return (ENXIO);
999 rs = &raid_softc[unit]; 1023 rs = &raid_softc[unit];
1000 raidPtr = raidPtrs[unit]; 1024 raidPtr = raidPtrs[unit];
1001 1025
1002 db1_printf(("raidioctl: %d %d %d %d\n", (int) dev, 1026 db1_printf(("raidioctl: %d %d %d %d\n", (int) dev,
1003 (int) DISKPART(dev), (int) unit, (int) cmd)); 1027 (int) DISKPART(dev), (int) unit, (int) cmd));
1004 1028
1005 /* Must be open for writes for these commands... */ 1029 /* Must be open for writes for these commands... */
1006 switch (cmd) { 1030 switch (cmd) {
1007#ifdef DIOCGSECTORSIZE 1031#ifdef DIOCGSECTORSIZE
1008 case DIOCGSECTORSIZE: 1032 case DIOCGSECTORSIZE:
1009 *(u_int *)data = raidPtr->bytesPerSector; 1033 *(u_int *)data = raidPtr->bytesPerSector;
1010 return 0; 1034 return 0;
1011 case DIOCGMEDIASIZE: 1035 case DIOCGMEDIASIZE:
1012 *(off_t *)data = 1036 *(off_t *)data =
1013 (off_t)raidPtr->totalSectors * raidPtr->bytesPerSector; 1037 (off_t)raidPtr->totalSectors * raidPtr->bytesPerSector;
1014 return 0; 1038 return 0;
1015#endif 1039#endif
1016 case DIOCSDINFO: 1040 case DIOCSDINFO:
1017 case DIOCWDINFO: 1041 case DIOCWDINFO:
1018#ifdef __HAVE_OLD_DISKLABEL 1042#ifdef __HAVE_OLD_DISKLABEL
1019 case ODIOCWDINFO: 1043 case ODIOCWDINFO:
1020 case ODIOCSDINFO: 1044 case ODIOCSDINFO:
1021#endif 1045#endif
1022 case DIOCWLABEL: 1046 case DIOCWLABEL:
1023 case DIOCAWEDGE: 1047 case DIOCAWEDGE:
1024 case DIOCDWEDGE: 1048 case DIOCDWEDGE:
1025 if ((flag & FWRITE) == 0) 1049 if ((flag & FWRITE) == 0)
1026 return (EBADF); 1050 return (EBADF);
1027 } 1051 }
1028 1052
1029 /* Must be initialized for these... */ 1053 /* Must be initialized for these... */
1030 switch (cmd) { 1054 switch (cmd) {
1031 case DIOCGDINFO: 1055 case DIOCGDINFO:
1032 case DIOCSDINFO: 1056 case DIOCSDINFO:
1033 case DIOCWDINFO: 1057 case DIOCWDINFO:
1034#ifdef __HAVE_OLD_DISKLABEL 1058#ifdef __HAVE_OLD_DISKLABEL
1035 case ODIOCGDINFO: 1059 case ODIOCGDINFO:
1036 case ODIOCWDINFO: 1060 case ODIOCWDINFO:
1037 case ODIOCSDINFO: 1061 case ODIOCSDINFO:
1038 case ODIOCGDEFLABEL: 1062 case ODIOCGDEFLABEL:
1039#endif 1063#endif
1040 case DIOCGPART: 1064 case DIOCGPART:
1041 case DIOCWLABEL: 1065 case DIOCWLABEL:
1042 case DIOCGDEFLABEL: 1066 case DIOCGDEFLABEL:
1043 case DIOCAWEDGE: 1067 case DIOCAWEDGE:
1044 case DIOCDWEDGE: 1068 case DIOCDWEDGE:
1045 case DIOCLWEDGES: 1069 case DIOCLWEDGES:
1046 case DIOCCACHESYNC: 1070 case DIOCCACHESYNC:
1047 case RAIDFRAME_SHUTDOWN: 1071 case RAIDFRAME_SHUTDOWN:
1048 case RAIDFRAME_REWRITEPARITY: 1072 case RAIDFRAME_REWRITEPARITY:
1049 case RAIDFRAME_GET_INFO: 1073 case RAIDFRAME_GET_INFO:
1050 case RAIDFRAME_RESET_ACCTOTALS: 1074 case RAIDFRAME_RESET_ACCTOTALS:
1051 case RAIDFRAME_GET_ACCTOTALS: 1075 case RAIDFRAME_GET_ACCTOTALS:
1052 case RAIDFRAME_KEEP_ACCTOTALS: 1076 case RAIDFRAME_KEEP_ACCTOTALS:
1053 case RAIDFRAME_GET_SIZE: 1077 case RAIDFRAME_GET_SIZE:
1054 case RAIDFRAME_FAIL_DISK: 1078 case RAIDFRAME_FAIL_DISK:
1055 case RAIDFRAME_COPYBACK: 1079 case RAIDFRAME_COPYBACK:
1056 case RAIDFRAME_CHECK_RECON_STATUS: 1080 case RAIDFRAME_CHECK_RECON_STATUS:
1057 case RAIDFRAME_CHECK_RECON_STATUS_EXT: 1081 case RAIDFRAME_CHECK_RECON_STATUS_EXT:
1058 case RAIDFRAME_GET_COMPONENT_LABEL: 1082 case RAIDFRAME_GET_COMPONENT_LABEL:
1059 case RAIDFRAME_SET_COMPONENT_LABEL: 1083 case RAIDFRAME_SET_COMPONENT_LABEL:
1060 case RAIDFRAME_ADD_HOT_SPARE: 1084 case RAIDFRAME_ADD_HOT_SPARE:
1061 case RAIDFRAME_REMOVE_HOT_SPARE: 1085 case RAIDFRAME_REMOVE_HOT_SPARE:
1062 case RAIDFRAME_INIT_LABELS: 1086 case RAIDFRAME_INIT_LABELS:
1063 case RAIDFRAME_REBUILD_IN_PLACE: 1087 case RAIDFRAME_REBUILD_IN_PLACE:
1064 case RAIDFRAME_CHECK_PARITY: 1088 case RAIDFRAME_CHECK_PARITY:
1065 case RAIDFRAME_CHECK_PARITYREWRITE_STATUS: 1089 case RAIDFRAME_CHECK_PARITYREWRITE_STATUS:
1066 case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT: 1090 case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT:
1067 case RAIDFRAME_CHECK_COPYBACK_STATUS: 1091 case RAIDFRAME_CHECK_COPYBACK_STATUS:
1068 case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT: 1092 case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT:
1069 case RAIDFRAME_SET_AUTOCONFIG: 1093 case RAIDFRAME_SET_AUTOCONFIG:
1070 case RAIDFRAME_SET_ROOT: 1094 case RAIDFRAME_SET_ROOT:
1071 case RAIDFRAME_DELETE_COMPONENT: 1095 case RAIDFRAME_DELETE_COMPONENT:
1072 case RAIDFRAME_INCORPORATE_HOT_SPARE: 1096 case RAIDFRAME_INCORPORATE_HOT_SPARE:
1073 if ((rs->sc_flags & RAIDF_INITED) == 0) 1097 if ((rs->sc_flags & RAIDF_INITED) == 0)
1074 return (ENXIO); 1098 return (ENXIO);
1075 } 1099 }
1076 1100
1077 switch (cmd) { 1101 switch (cmd) {
1078#ifdef COMPAT_50 1102#ifdef COMPAT_50
1079 case RAIDFRAME_GET_INFO50: 1103 case RAIDFRAME_GET_INFO50:
1080 return rf_get_info50(raidPtr, data); 1104 return rf_get_info50(raidPtr, data);
1081 1105
1082 case RAIDFRAME_CONFIGURE50: 1106 case RAIDFRAME_CONFIGURE50:
1083 if ((retcode = rf_config50(raidPtr, unit, data, &k_cfg)) != 0) 1107 if ((retcode = rf_config50(raidPtr, unit, data, &k_cfg)) != 0)
1084 return retcode; 1108 return retcode;
1085 goto config; 1109 goto config;
1086#endif 1110#endif
1087 /* configure the system */ 1111 /* configure the system */
1088 case RAIDFRAME_CONFIGURE: 1112 case RAIDFRAME_CONFIGURE:
1089 1113
1090 if (raidPtr->valid) { 1114 if (raidPtr->valid) {
1091 /* There is a valid RAID set running on this unit! */ 1115 /* There is a valid RAID set running on this unit! */
1092 printf("raid%d: Device already configured!\n",unit); 1116 printf("raid%d: Device already configured!\n",unit);
1093 return(EINVAL); 1117 return(EINVAL);
1094 } 1118 }
1095 1119
1096 /* copy-in the configuration information */ 1120 /* copy-in the configuration information */
1097 /* data points to a pointer to the configuration structure */ 1121 /* data points to a pointer to the configuration structure */
1098 1122
1099 u_cfg = *((RF_Config_t **) data); 1123 u_cfg = *((RF_Config_t **) data);
1100 RF_Malloc(k_cfg, sizeof(RF_Config_t), (RF_Config_t *)); 1124 RF_Malloc(k_cfg, sizeof(RF_Config_t), (RF_Config_t *));
1101 if (k_cfg == NULL) { 1125 if (k_cfg == NULL) {
1102 return (ENOMEM); 1126 return (ENOMEM);
1103 } 1127 }
1104 retcode = copyin(u_cfg, k_cfg, sizeof(RF_Config_t)); 1128 retcode = copyin(u_cfg, k_cfg, sizeof(RF_Config_t));
1105 if (retcode) { 1129 if (retcode) {
1106 RF_Free(k_cfg, sizeof(RF_Config_t)); 1130 RF_Free(k_cfg, sizeof(RF_Config_t));
1107 db1_printf(("rf_ioctl: retcode=%d copyin.1\n", 1131 db1_printf(("rf_ioctl: retcode=%d copyin.1\n",
1108 retcode)); 1132 retcode));
1109 return (retcode); 1133 return (retcode);
1110 } 1134 }
1111 goto config; 1135 goto config;
1112 config: 1136 config:
1113 /* allocate a buffer for the layout-specific data, and copy it 1137 /* allocate a buffer for the layout-specific data, and copy it
1114 * in */ 1138 * in */
1115 if (k_cfg->layoutSpecificSize) { 1139 if (k_cfg->layoutSpecificSize) {
1116 if (k_cfg->layoutSpecificSize > 10000) { 1140 if (k_cfg->layoutSpecificSize > 10000) {
1117 /* sanity check */ 1141 /* sanity check */
1118 RF_Free(k_cfg, sizeof(RF_Config_t)); 1142 RF_Free(k_cfg, sizeof(RF_Config_t));
1119 return (EINVAL); 1143 return (EINVAL);
1120 } 1144 }
1121 RF_Malloc(specific_buf, k_cfg->layoutSpecificSize, 1145 RF_Malloc(specific_buf, k_cfg->layoutSpecificSize,
1122 (u_char *)); 1146 (u_char *));
1123 if (specific_buf == NULL) { 1147 if (specific_buf == NULL) {
1124 RF_Free(k_cfg, sizeof(RF_Config_t)); 1148 RF_Free(k_cfg, sizeof(RF_Config_t));
1125 return (ENOMEM); 1149 return (ENOMEM);
1126 } 1150 }
1127 retcode = copyin(k_cfg->layoutSpecific, specific_buf, 1151 retcode = copyin(k_cfg->layoutSpecific, specific_buf,
1128 k_cfg->layoutSpecificSize); 1152 k_cfg->layoutSpecificSize);
1129 if (retcode) { 1153 if (retcode) {
1130 RF_Free(k_cfg, sizeof(RF_Config_t)); 1154 RF_Free(k_cfg, sizeof(RF_Config_t));
1131 RF_Free(specific_buf, 1155 RF_Free(specific_buf,
1132 k_cfg->layoutSpecificSize); 1156 k_cfg->layoutSpecificSize);
1133 db1_printf(("rf_ioctl: retcode=%d copyin.2\n", 1157 db1_printf(("rf_ioctl: retcode=%d copyin.2\n",
1134 retcode)); 1158 retcode));
1135 return (retcode); 1159 return (retcode);
1136 } 1160 }
1137 } else 1161 } else
1138 specific_buf = NULL; 1162 specific_buf = NULL;
1139 k_cfg->layoutSpecific = specific_buf; 1163 k_cfg->layoutSpecific = specific_buf;
1140 1164
1141 /* should do some kind of sanity check on the configuration. 1165 /* should do some kind of sanity check on the configuration.
1142 * Store the sum of all the bytes in the last byte? */ 1166 * Store the sum of all the bytes in the last byte? */
1143 1167
1144 /* configure the system */ 1168 /* configure the system */
1145 1169
1146 /* 1170 /*
1147 * Clear the entire RAID descriptor, just to make sure 1171 * Clear the entire RAID descriptor, just to make sure
1148 * there is no stale data left in the case of a 1172 * there is no stale data left in the case of a
1149 * reconfiguration 1173 * reconfiguration
1150 */ 1174 */
1151 memset((char *) raidPtr, 0, sizeof(RF_Raid_t)); 1175 memset((char *) raidPtr, 0, sizeof(RF_Raid_t));
1152 raidPtr->raidid = unit; 1176 raidPtr->raidid = unit;
1153 1177
1154 retcode = rf_Configure(raidPtr, k_cfg, NULL); 1178 retcode = rf_Configure(raidPtr, k_cfg, NULL);
1155 1179
1156 if (retcode == 0) { 1180 if (retcode == 0) {
1157 1181
1158 /* allow this many simultaneous IO's to 1182 /* allow this many simultaneous IO's to
1159 this RAID device */ 1183 this RAID device */
1160 raidPtr->openings = RAIDOUTSTANDING; 1184 raidPtr->openings = RAIDOUTSTANDING;
1161 1185
1162 raidinit(raidPtr); 1186 raidinit(raidPtr);
1163 rf_markalldirty(raidPtr); 1187 rf_markalldirty(raidPtr);
1164 } 1188 }
1165 /* free the buffers. No return code here. */ 1189 /* free the buffers. No return code here. */
1166 if (k_cfg->layoutSpecificSize) { 1190 if (k_cfg->layoutSpecificSize) {
1167 RF_Free(specific_buf, k_cfg->layoutSpecificSize); 1191 RF_Free(specific_buf, k_cfg->layoutSpecificSize);
1168 } 1192 }
1169 RF_Free(k_cfg, sizeof(RF_Config_t)); 1193 RF_Free(k_cfg, sizeof(RF_Config_t));
1170 1194
1171 return (retcode); 1195 return (retcode);
1172 1196
1173 /* shutdown the system */ 1197 /* shutdown the system */
1174 case RAIDFRAME_SHUTDOWN: 1198 case RAIDFRAME_SHUTDOWN:
1175 1199
 1200 part = DISKPART(dev);
 1201 pmask = (1 << part);
 1202
1176 if ((error = raidlock(rs)) != 0) 1203 if ((error = raidlock(rs)) != 0)
1177 return (error); 1204 return (error);
1178 1205
1179 /* 
1180 * If somebody has a partition mounted, we shouldn't 
1181 * shutdown. 
1182 */ 
1183 
1184 part = DISKPART(dev); 
1185 pmask = (1 << part); 
1186 if ((rs->sc_dkdev.dk_openmask & ~pmask) || 1206 if ((rs->sc_dkdev.dk_openmask & ~pmask) ||
1187 ((rs->sc_dkdev.dk_bopenmask & pmask) && 1207 ((rs->sc_dkdev.dk_bopenmask & pmask) &&
1188 (rs->sc_dkdev.dk_copenmask & pmask))) { 1208 (rs->sc_dkdev.dk_copenmask & pmask)))
1189 raidunlock(rs); 1209 retcode = EBUSY;
1190 return (EBUSY); 1210 else {
 1211 rs->sc_flags |= RAIDF_SHUTDOWN;
 1212 rs->sc_dkdev.dk_copenmask &= ~pmask;
 1213 rs->sc_dkdev.dk_bopenmask &= ~pmask;
 1214 rs->sc_dkdev.dk_openmask &= ~pmask;
 1215 retcode = 0;
1191 } 1216 }
1192 1217
1193 retcode = rf_Shutdown(raidPtr); 1218 raidunlock(rs);
1194 1219
1195 /* It's no longer initialized... */ 1220 if (retcode != 0)
1196 rs->sc_flags &= ~RAIDF_INITED; 1221 return retcode;
1197 1222
1198 /* free the pseudo device attach bits */ 1223 /* free the pseudo device attach bits */
1199 1224
1200 cf = device_cfdata(rs->sc_dev); 1225 cf = device_cfdata(rs->sc_dev);
1201 /* XXX this causes us to not return any errors 1226 if ((retcode = config_detach(rs->sc_dev, DETACH_QUIET)) == 0)
1202 from the above call to rf_Shutdown() */ 1227 free(cf, M_RAIDFRAME);
1203 retcode = config_detach(rs->sc_dev, DETACH_QUIET); 
1204 free(cf, M_RAIDFRAME); 
1205 
1206 /* Detach the disk. */ 
1207 disk_detach(&rs->sc_dkdev); 
1208 disk_destroy(&rs->sc_dkdev); 
1209 
1210 raidunlock(rs); 
1211 1228
1212 return (retcode); 1229 return (retcode);
1213 case RAIDFRAME_GET_COMPONENT_LABEL: 1230 case RAIDFRAME_GET_COMPONENT_LABEL:
1214 clabel_ptr = (RF_ComponentLabel_t **) data; 1231 clabel_ptr = (RF_ComponentLabel_t **) data;
1215 /* need to read the component label for the disk indicated 1232 /* need to read the component label for the disk indicated
1216 by row,column in clabel */ 1233 by row,column in clabel */
1217 1234
1218 /* For practice, let's get it directly fromdisk, rather 1235 /* For practice, let's get it directly fromdisk, rather
1219 than from the in-core copy */ 1236 than from the in-core copy */
1220 RF_Malloc( clabel, sizeof( RF_ComponentLabel_t ), 1237 RF_Malloc( clabel, sizeof( RF_ComponentLabel_t ),
1221 (RF_ComponentLabel_t *)); 1238 (RF_ComponentLabel_t *));
1222 if (clabel == NULL) 1239 if (clabel == NULL)
1223 return (ENOMEM); 1240 return (ENOMEM);
1224 1241
1225 retcode = copyin( *clabel_ptr, clabel, 1242 retcode = copyin( *clabel_ptr, clabel,
1226 sizeof(RF_ComponentLabel_t)); 1243 sizeof(RF_ComponentLabel_t));
1227 1244
1228 if (retcode) { 1245 if (retcode) {
1229 RF_Free( clabel, sizeof(RF_ComponentLabel_t)); 1246 RF_Free( clabel, sizeof(RF_ComponentLabel_t));
1230 return(retcode); 1247 return(retcode);
1231 } 1248 }
1232 1249
1233 clabel->row = 0; /* Don't allow looking at anything else.*/ 1250 clabel->row = 0; /* Don't allow looking at anything else.*/
1234 1251
1235 column = clabel->column; 1252 column = clabel->column;
1236 1253
1237 if ((column < 0) || (column >= raidPtr->numCol + 1254 if ((column < 0) || (column >= raidPtr->numCol +
1238 raidPtr->numSpare)) { 1255 raidPtr->numSpare)) {
1239 RF_Free( clabel, sizeof(RF_ComponentLabel_t)); 1256 RF_Free( clabel, sizeof(RF_ComponentLabel_t));
1240 return(EINVAL); 1257 return(EINVAL);
1241 } 1258 }
1242 1259
1243 retcode = raidread_component_label(raidPtr->Disks[column].dev, 1260 retcode = raidread_component_label(raidPtr->Disks[column].dev,
1244 raidPtr->raid_cinfo[column].ci_vp, 1261 raidPtr->raid_cinfo[column].ci_vp,
1245 clabel ); 1262 clabel );
1246 1263
1247 if (retcode == 0) { 1264 if (retcode == 0) {
1248 retcode = copyout(clabel, *clabel_ptr, 1265 retcode = copyout(clabel, *clabel_ptr,
1249 sizeof(RF_ComponentLabel_t)); 1266 sizeof(RF_ComponentLabel_t));
1250 } 1267 }
1251 RF_Free(clabel, sizeof(RF_ComponentLabel_t)); 1268 RF_Free(clabel, sizeof(RF_ComponentLabel_t));
1252 return (retcode); 1269 return (retcode);
1253 1270
1254 case RAIDFRAME_SET_COMPONENT_LABEL: 1271 case RAIDFRAME_SET_COMPONENT_LABEL:
1255 clabel = (RF_ComponentLabel_t *) data; 1272 clabel = (RF_ComponentLabel_t *) data;
1256 1273
1257 /* XXX check the label for valid stuff... */ 1274 /* XXX check the label for valid stuff... */
1258 /* Note that some things *should not* get modified -- 1275 /* Note that some things *should not* get modified --
1259 the user should be re-initing the labels instead of 1276 the user should be re-initing the labels instead of
1260 trying to patch things. 1277 trying to patch things.
1261 */ 1278 */
1262 1279
1263 raidid = raidPtr->raidid; 1280 raidid = raidPtr->raidid;
1264#ifdef DEBUG 1281#ifdef DEBUG
1265 printf("raid%d: Got component label:\n", raidid); 1282 printf("raid%d: Got component label:\n", raidid);
1266 printf("raid%d: Version: %d\n", raidid, clabel->version); 1283 printf("raid%d: Version: %d\n", raidid, clabel->version);
1267 printf("raid%d: Serial Number: %d\n", raidid, clabel->serial_number); 1284 printf("raid%d: Serial Number: %d\n", raidid, clabel->serial_number);
1268 printf("raid%d: Mod counter: %d\n", raidid, clabel->mod_counter); 1285 printf("raid%d: Mod counter: %d\n", raidid, clabel->mod_counter);
1269 printf("raid%d: Column: %d\n", raidid, clabel->column); 1286 printf("raid%d: Column: %d\n", raidid, clabel->column);
1270 printf("raid%d: Num Columns: %d\n", raidid, clabel->num_columns); 1287 printf("raid%d: Num Columns: %d\n", raidid, clabel->num_columns);
1271 printf("raid%d: Clean: %d\n", raidid, clabel->clean); 1288 printf("raid%d: Clean: %d\n", raidid, clabel->clean);
1272 printf("raid%d: Status: %d\n", raidid, clabel->status); 1289 printf("raid%d: Status: %d\n", raidid, clabel->status);
1273#endif 1290#endif
1274 clabel->row = 0; 1291 clabel->row = 0;
1275 column = clabel->column; 1292 column = clabel->column;
1276 1293
1277 if ((column < 0) || (column >= raidPtr->numCol)) { 1294 if ((column < 0) || (column >= raidPtr->numCol)) {
1278 return(EINVAL); 1295 return(EINVAL);
1279 } 1296 }
1280 1297
1281 /* XXX this isn't allowed to do anything for now :-) */ 1298 /* XXX this isn't allowed to do anything for now :-) */
1282 1299
1283 /* XXX and before it is, we need to fill in the rest 1300 /* XXX and before it is, we need to fill in the rest
1284 of the fields!?!?!?! */ 1301 of the fields!?!?!?! */
1285#if 0 1302#if 0
1286 raidwrite_component_label( 1303 raidwrite_component_label(
1287 raidPtr->Disks[column].dev, 1304 raidPtr->Disks[column].dev,
1288 raidPtr->raid_cinfo[column].ci_vp, 1305 raidPtr->raid_cinfo[column].ci_vp,
1289 clabel ); 1306 clabel );
1290#endif 1307#endif
1291 return (0); 1308 return (0);
1292 1309
1293 case RAIDFRAME_INIT_LABELS: 1310 case RAIDFRAME_INIT_LABELS:
1294 clabel = (RF_ComponentLabel_t *) data; 1311 clabel = (RF_ComponentLabel_t *) data;
1295 /* 1312 /*
1296 we only want the serial number from 1313 we only want the serial number from
1297 the above. We get all the rest of the information 1314 the above. We get all the rest of the information
1298 from the config that was used to create this RAID 1315 from the config that was used to create this RAID
1299 set. 1316 set.
1300 */ 1317 */
1301 1318
1302 raidPtr->serial_number = clabel->serial_number; 1319 raidPtr->serial_number = clabel->serial_number;
1303 1320
1304 RF_Malloc(ci_label, sizeof(RF_ComponentLabel_t),  1321 RF_Malloc(ci_label, sizeof(RF_ComponentLabel_t),
1305 (RF_ComponentLabel_t *)); 1322 (RF_ComponentLabel_t *));
1306 if (ci_label == NULL) 1323 if (ci_label == NULL)
1307 return (ENOMEM); 1324 return (ENOMEM);
1308 1325
1309 raid_init_component_label(raidPtr, ci_label); 1326 raid_init_component_label(raidPtr, ci_label);
1310 ci_label->serial_number = clabel->serial_number; 1327 ci_label->serial_number = clabel->serial_number;
1311 ci_label->row = 0; /* we dont' pretend to support more */ 1328 ci_label->row = 0; /* we dont' pretend to support more */
1312 1329
1313 for(column=0;column<raidPtr->numCol;column++) { 1330 for(column=0;column<raidPtr->numCol;column++) {
1314 diskPtr = &raidPtr->Disks[column]; 1331 diskPtr = &raidPtr->Disks[column];
1315 if (!RF_DEAD_DISK(diskPtr->status)) { 1332 if (!RF_DEAD_DISK(diskPtr->status)) {
1316 ci_label->partitionSize = diskPtr->partitionSize; 1333 ci_label->partitionSize = diskPtr->partitionSize;
1317 ci_label->column = column; 1334 ci_label->column = column;
1318 raidwrite_component_label( 1335 raidwrite_component_label(
1319 raidPtr->Disks[column].dev, 1336 raidPtr->Disks[column].dev,
1320 raidPtr->raid_cinfo[column].ci_vp, 1337 raidPtr->raid_cinfo[column].ci_vp,
1321 ci_label ); 1338 ci_label );
1322 } 1339 }
1323 } 1340 }
1324 RF_Free(ci_label, sizeof(RF_ComponentLabel_t)); 1341 RF_Free(ci_label, sizeof(RF_ComponentLabel_t));
1325  1342
1326 return (retcode); 1343 return (retcode);
1327 case RAIDFRAME_SET_AUTOCONFIG: 1344 case RAIDFRAME_SET_AUTOCONFIG:
1328 d = rf_set_autoconfig(raidPtr, *(int *) data); 1345 d = rf_set_autoconfig(raidPtr, *(int *) data);
1329 printf("raid%d: New autoconfig value is: %d\n", 1346 printf("raid%d: New autoconfig value is: %d\n",
1330 raidPtr->raidid, d); 1347 raidPtr->raidid, d);
1331 *(int *) data = d; 1348 *(int *) data = d;
1332 return (retcode); 1349 return (retcode);
1333 1350
1334 case RAIDFRAME_SET_ROOT: 1351 case RAIDFRAME_SET_ROOT:
1335 d = rf_set_rootpartition(raidPtr, *(int *) data); 1352 d = rf_set_rootpartition(raidPtr, *(int *) data);
1336 printf("raid%d: New rootpartition value is: %d\n", 1353 printf("raid%d: New rootpartition value is: %d\n",
1337 raidPtr->raidid, d); 1354 raidPtr->raidid, d);
1338 *(int *) data = d; 1355 *(int *) data = d;
1339 return (retcode); 1356 return (retcode);
1340 1357
1341 /* initialize all parity */ 1358 /* initialize all parity */
1342 case RAIDFRAME_REWRITEPARITY: 1359 case RAIDFRAME_REWRITEPARITY:
1343 1360
1344 if (raidPtr->Layout.map->faultsTolerated == 0) { 1361 if (raidPtr->Layout.map->faultsTolerated == 0) {
1345 /* Parity for RAID 0 is trivially correct */ 1362 /* Parity for RAID 0 is trivially correct */
1346 raidPtr->parity_good = RF_RAID_CLEAN; 1363 raidPtr->parity_good = RF_RAID_CLEAN;
1347 return(0); 1364 return(0);
1348 } 1365 }
1349 1366
1350 if (raidPtr->parity_rewrite_in_progress == 1) { 1367 if (raidPtr->parity_rewrite_in_progress == 1) {
1351 /* Re-write is already in progress! */ 1368 /* Re-write is already in progress! */
1352 return(EINVAL); 1369 return(EINVAL);
1353 } 1370 }
1354 1371
1355 retcode = RF_CREATE_THREAD(raidPtr->parity_rewrite_thread, 1372 retcode = RF_CREATE_THREAD(raidPtr->parity_rewrite_thread,
1356 rf_RewriteParityThread, 1373 rf_RewriteParityThread,
1357 raidPtr,"raid_parity"); 1374 raidPtr,"raid_parity");
1358 return (retcode); 1375 return (retcode);
1359 1376
1360 1377
1361 case RAIDFRAME_ADD_HOT_SPARE: 1378 case RAIDFRAME_ADD_HOT_SPARE:
1362 sparePtr = (RF_SingleComponent_t *) data; 1379 sparePtr = (RF_SingleComponent_t *) data;
1363 memcpy( &component, sparePtr, sizeof(RF_SingleComponent_t)); 1380 memcpy( &component, sparePtr, sizeof(RF_SingleComponent_t));
1364 retcode = rf_add_hot_spare(raidPtr, &component); 1381 retcode = rf_add_hot_spare(raidPtr, &component);
1365 return(retcode); 1382 return(retcode);
1366 1383
1367 case RAIDFRAME_REMOVE_HOT_SPARE: 1384 case RAIDFRAME_REMOVE_HOT_SPARE:
1368 return(retcode); 1385 return(retcode);
1369 1386
1370 case RAIDFRAME_DELETE_COMPONENT: 1387 case RAIDFRAME_DELETE_COMPONENT:
1371 componentPtr = (RF_SingleComponent_t *)data; 1388 componentPtr = (RF_SingleComponent_t *)data;
1372 memcpy( &component, componentPtr, 1389 memcpy( &component, componentPtr,
1373 sizeof(RF_SingleComponent_t)); 1390 sizeof(RF_SingleComponent_t));
1374 retcode = rf_delete_component(raidPtr, &component); 1391 retcode = rf_delete_component(raidPtr, &component);
1375 return(retcode); 1392 return(retcode);
1376 1393
1377 case RAIDFRAME_INCORPORATE_HOT_SPARE: 1394 case RAIDFRAME_INCORPORATE_HOT_SPARE:
1378 componentPtr = (RF_SingleComponent_t *)data; 1395 componentPtr = (RF_SingleComponent_t *)data;
1379 memcpy( &component, componentPtr, 1396 memcpy( &component, componentPtr,
1380 sizeof(RF_SingleComponent_t)); 1397 sizeof(RF_SingleComponent_t));
1381 retcode = rf_incorporate_hot_spare(raidPtr, &component); 1398 retcode = rf_incorporate_hot_spare(raidPtr, &component);
1382 return(retcode); 1399 return(retcode);
1383 1400
1384 case RAIDFRAME_REBUILD_IN_PLACE: 1401 case RAIDFRAME_REBUILD_IN_PLACE:
1385 1402
1386 if (raidPtr->Layout.map->faultsTolerated == 0) { 1403 if (raidPtr->Layout.map->faultsTolerated == 0) {
1387 /* Can't do this on a RAID 0!! */ 1404 /* Can't do this on a RAID 0!! */
1388 return(EINVAL); 1405 return(EINVAL);
1389 } 1406 }
1390 1407
1391 if (raidPtr->recon_in_progress == 1) { 1408 if (raidPtr->recon_in_progress == 1) {
1392 /* a reconstruct is already in progress! */ 1409 /* a reconstruct is already in progress! */
1393 return(EINVAL); 1410 return(EINVAL);
1394 } 1411 }
1395 1412
1396 componentPtr = (RF_SingleComponent_t *) data; 1413 componentPtr = (RF_SingleComponent_t *) data;
1397 memcpy( &component, componentPtr, 1414 memcpy( &component, componentPtr,
1398 sizeof(RF_SingleComponent_t)); 1415 sizeof(RF_SingleComponent_t));
1399 component.row = 0; /* we don't support any more */ 1416 component.row = 0; /* we don't support any more */
1400 column = component.column; 1417 column = component.column;
1401 1418
1402 if ((column < 0) || (column >= raidPtr->numCol)) { 1419 if ((column < 0) || (column >= raidPtr->numCol)) {
1403 return(EINVAL); 1420 return(EINVAL);
1404 } 1421 }
1405 1422
1406 RF_LOCK_MUTEX(raidPtr->mutex); 1423 RF_LOCK_MUTEX(raidPtr->mutex);
1407 if ((raidPtr->Disks[column].status == rf_ds_optimal) && 1424 if ((raidPtr->Disks[column].status == rf_ds_optimal) &&
1408 (raidPtr->numFailures > 0)) { 1425 (raidPtr->numFailures > 0)) {
1409 /* XXX 0 above shouldn't be constant!!! */ 1426 /* XXX 0 above shouldn't be constant!!! */
1410 /* some component other than this has failed. 1427 /* some component other than this has failed.
1411 Let's not make things worse than they already 1428 Let's not make things worse than they already
1412 are... */ 1429 are... */
1413 printf("raid%d: Unable to reconstruct to disk at:\n", 1430 printf("raid%d: Unable to reconstruct to disk at:\n",
1414 raidPtr->raidid); 1431 raidPtr->raidid);
1415 printf("raid%d: Col: %d Too many failures.\n", 1432 printf("raid%d: Col: %d Too many failures.\n",
1416 raidPtr->raidid, column); 1433 raidPtr->raidid, column);
1417 RF_UNLOCK_MUTEX(raidPtr->mutex); 1434 RF_UNLOCK_MUTEX(raidPtr->mutex);
1418 return (EINVAL); 1435 return (EINVAL);
1419 } 1436 }
1420 if (raidPtr->Disks[column].status == 1437 if (raidPtr->Disks[column].status ==
1421 rf_ds_reconstructing) { 1438 rf_ds_reconstructing) {
1422 printf("raid%d: Unable to reconstruct to disk at:\n", 1439 printf("raid%d: Unable to reconstruct to disk at:\n",
1423 raidPtr->raidid); 1440 raidPtr->raidid);
1424 printf("raid%d: Col: %d Reconstruction already occuring!\n", raidPtr->raidid, column); 1441 printf("raid%d: Col: %d Reconstruction already occuring!\n", raidPtr->raidid, column);
1425 1442
1426 RF_UNLOCK_MUTEX(raidPtr->mutex); 1443 RF_UNLOCK_MUTEX(raidPtr->mutex);
1427 return (EINVAL); 1444 return (EINVAL);
1428 } 1445 }
1429 if (raidPtr->Disks[column].status == rf_ds_spared) { 1446 if (raidPtr->Disks[column].status == rf_ds_spared) {
1430 RF_UNLOCK_MUTEX(raidPtr->mutex); 1447 RF_UNLOCK_MUTEX(raidPtr->mutex);
1431 return (EINVAL); 1448 return (EINVAL);
1432 } 1449 }
1433 RF_UNLOCK_MUTEX(raidPtr->mutex); 1450 RF_UNLOCK_MUTEX(raidPtr->mutex);
1434 1451
1435 RF_Malloc(rrcopy, sizeof(*rrcopy), (struct rf_recon_req *)); 1452 RF_Malloc(rrcopy, sizeof(*rrcopy), (struct rf_recon_req *));
1436 if (rrcopy == NULL) 1453 if (rrcopy == NULL)
1437 return(ENOMEM); 1454 return(ENOMEM);
1438 1455
1439 rrcopy->raidPtr = (void *) raidPtr; 1456 rrcopy->raidPtr = (void *) raidPtr;
1440 rrcopy->col = column; 1457 rrcopy->col = column;
1441 1458
1442 retcode = RF_CREATE_THREAD(raidPtr->recon_thread, 1459 retcode = RF_CREATE_THREAD(raidPtr->recon_thread,
1443 rf_ReconstructInPlaceThread, 1460 rf_ReconstructInPlaceThread,
1444 rrcopy,"raid_reconip"); 1461 rrcopy,"raid_reconip");
1445 return(retcode); 1462 return(retcode);
1446 1463
1447 case RAIDFRAME_GET_INFO: 1464 case RAIDFRAME_GET_INFO:
1448 if (!raidPtr->valid) 1465 if (!raidPtr->valid)
1449 return (ENODEV); 1466 return (ENODEV);
1450 ucfgp = (RF_DeviceConfig_t **) data; 1467 ucfgp = (RF_DeviceConfig_t **) data;
1451 RF_Malloc(d_cfg, sizeof(RF_DeviceConfig_t), 1468 RF_Malloc(d_cfg, sizeof(RF_DeviceConfig_t),
1452 (RF_DeviceConfig_t *)); 1469 (RF_DeviceConfig_t *));
1453 if (d_cfg == NULL) 1470 if (d_cfg == NULL)
1454 return (ENOMEM); 1471 return (ENOMEM);
1455 d_cfg->rows = 1; /* there is only 1 row now */ 1472 d_cfg->rows = 1; /* there is only 1 row now */
1456 d_cfg->cols = raidPtr->numCol; 1473 d_cfg->cols = raidPtr->numCol;
1457 d_cfg->ndevs = raidPtr->numCol; 1474 d_cfg->ndevs = raidPtr->numCol;
1458 if (d_cfg->ndevs >= RF_MAX_DISKS) { 1475 if (d_cfg->ndevs >= RF_MAX_DISKS) {
1459 RF_Free(d_cfg, sizeof(RF_DeviceConfig_t)); 1476 RF_Free(d_cfg, sizeof(RF_DeviceConfig_t));
1460 return (ENOMEM); 1477 return (ENOMEM);
1461 } 1478 }
1462 d_cfg->nspares = raidPtr->numSpare; 1479 d_cfg->nspares = raidPtr->numSpare;
1463 if (d_cfg->nspares >= RF_MAX_DISKS) { 1480 if (d_cfg->nspares >= RF_MAX_DISKS) {
1464 RF_Free(d_cfg, sizeof(RF_DeviceConfig_t)); 1481 RF_Free(d_cfg, sizeof(RF_DeviceConfig_t));
1465 return (ENOMEM); 1482 return (ENOMEM);
1466 } 1483 }
1467 d_cfg->maxqdepth = raidPtr->maxQueueDepth; 1484 d_cfg->maxqdepth = raidPtr->maxQueueDepth;
1468 d = 0; 1485 d = 0;
1469 for (j = 0; j < d_cfg->cols; j++) { 1486 for (j = 0; j < d_cfg->cols; j++) {
1470 d_cfg->devs[d] = raidPtr->Disks[j]; 1487 d_cfg->devs[d] = raidPtr->Disks[j];
1471 d++; 1488 d++;
1472 } 1489 }
1473 for (j = d_cfg->cols, i = 0; i < d_cfg->nspares; i++, j++) { 1490 for (j = d_cfg->cols, i = 0; i < d_cfg->nspares; i++, j++) {
1474 d_cfg->spares[i] = raidPtr->Disks[j]; 1491 d_cfg->spares[i] = raidPtr->Disks[j];
1475 } 1492 }
1476 retcode = copyout(d_cfg, *ucfgp, sizeof(RF_DeviceConfig_t)); 1493 retcode = copyout(d_cfg, *ucfgp, sizeof(RF_DeviceConfig_t));
1477 RF_Free(d_cfg, sizeof(RF_DeviceConfig_t)); 1494 RF_Free(d_cfg, sizeof(RF_DeviceConfig_t));
1478 1495
1479 return (retcode); 1496 return (retcode);
1480 1497
1481 case RAIDFRAME_CHECK_PARITY: 1498 case RAIDFRAME_CHECK_PARITY:
1482 *(int *) data = raidPtr->parity_good; 1499 *(int *) data = raidPtr->parity_good;
1483 return (0); 1500 return (0);
1484 1501
1485 case RAIDFRAME_RESET_ACCTOTALS: 1502 case RAIDFRAME_RESET_ACCTOTALS:
1486 memset(&raidPtr->acc_totals, 0, sizeof(raidPtr->acc_totals)); 1503 memset(&raidPtr->acc_totals, 0, sizeof(raidPtr->acc_totals));
1487 return (0); 1504 return (0);
1488 1505
1489 case RAIDFRAME_GET_ACCTOTALS: 1506 case RAIDFRAME_GET_ACCTOTALS:
1490 totals = (RF_AccTotals_t *) data; 1507 totals = (RF_AccTotals_t *) data;
1491 *totals = raidPtr->acc_totals; 1508 *totals = raidPtr->acc_totals;
1492 return (0); 1509 return (0);
1493 1510
1494 case RAIDFRAME_KEEP_ACCTOTALS: 1511 case RAIDFRAME_KEEP_ACCTOTALS:
1495 raidPtr->keep_acc_totals = *(int *)data; 1512 raidPtr->keep_acc_totals = *(int *)data;
1496 return (0); 1513 return (0);
1497 1514
1498 case RAIDFRAME_GET_SIZE: 1515 case RAIDFRAME_GET_SIZE:
1499 *(int *) data = raidPtr->totalSectors; 1516 *(int *) data = raidPtr->totalSectors;
1500 return (0); 1517 return (0);
1501 1518
1502 /* fail a disk & optionally start reconstruction */ 1519 /* fail a disk & optionally start reconstruction */
1503 case RAIDFRAME_FAIL_DISK: 1520 case RAIDFRAME_FAIL_DISK:
1504 1521
1505 if (raidPtr->Layout.map->faultsTolerated == 0) { 1522 if (raidPtr->Layout.map->faultsTolerated == 0) {
1506 /* Can't do this on a RAID 0!! */ 1523 /* Can't do this on a RAID 0!! */
1507 return(EINVAL); 1524 return(EINVAL);
1508 } 1525 }
1509 1526
1510 rr = (struct rf_recon_req *) data; 1527 rr = (struct rf_recon_req *) data;
1511 rr->row = 0; 1528 rr->row = 0;
1512 if (rr->col < 0 || rr->col >= raidPtr->numCol) 1529 if (rr->col < 0 || rr->col >= raidPtr->numCol)
1513 return (EINVAL); 1530 return (EINVAL);
1514 1531
1515 1532
1516 RF_LOCK_MUTEX(raidPtr->mutex); 1533 RF_LOCK_MUTEX(raidPtr->mutex);
1517 if (raidPtr->status == rf_rs_reconstructing) { 1534 if (raidPtr->status == rf_rs_reconstructing) {
1518 /* you can't fail a disk while we're reconstructing! */ 1535 /* you can't fail a disk while we're reconstructing! */
1519 /* XXX wrong for RAID6 */ 1536 /* XXX wrong for RAID6 */
1520 RF_UNLOCK_MUTEX(raidPtr->mutex); 1537 RF_UNLOCK_MUTEX(raidPtr->mutex);
1521 return (EINVAL); 1538 return (EINVAL);
1522 } 1539 }
1523 if ((raidPtr->Disks[rr->col].status == 1540 if ((raidPtr->Disks[rr->col].status ==
1524 rf_ds_optimal) && (raidPtr->numFailures > 0)) { 1541 rf_ds_optimal) && (raidPtr->numFailures > 0)) {
1525 /* some other component has failed. Let's not make 1542 /* some other component has failed. Let's not make
1526 things worse. XXX wrong for RAID6 */ 1543 things worse. XXX wrong for RAID6 */
1527 RF_UNLOCK_MUTEX(raidPtr->mutex); 1544 RF_UNLOCK_MUTEX(raidPtr->mutex);
1528 return (EINVAL); 1545 return (EINVAL);
1529 } 1546 }
1530 if (raidPtr->Disks[rr->col].status == rf_ds_spared) { 1547 if (raidPtr->Disks[rr->col].status == rf_ds_spared) {
1531 /* Can't fail a spared disk! */ 1548 /* Can't fail a spared disk! */
1532 RF_UNLOCK_MUTEX(raidPtr->mutex); 1549 RF_UNLOCK_MUTEX(raidPtr->mutex);
1533 return (EINVAL); 1550 return (EINVAL);
1534 } 1551 }
1535 RF_UNLOCK_MUTEX(raidPtr->mutex); 1552 RF_UNLOCK_MUTEX(raidPtr->mutex);
1536 1553
1537 /* make a copy of the recon request so that we don't rely on 1554 /* make a copy of the recon request so that we don't rely on
1538 * the user's buffer */ 1555 * the user's buffer */
1539 RF_Malloc(rrcopy, sizeof(*rrcopy), (struct rf_recon_req *)); 1556 RF_Malloc(rrcopy, sizeof(*rrcopy), (struct rf_recon_req *));
1540 if (rrcopy == NULL) 1557 if (rrcopy == NULL)
1541 return(ENOMEM); 1558 return(ENOMEM);
1542 memcpy(rrcopy, rr, sizeof(*rr)); 1559 memcpy(rrcopy, rr, sizeof(*rr));
1543 rrcopy->raidPtr = (void *) raidPtr; 1560 rrcopy->raidPtr = (void *) raidPtr;
1544 1561
1545 retcode = RF_CREATE_THREAD(raidPtr->recon_thread, 1562 retcode = RF_CREATE_THREAD(raidPtr->recon_thread,
1546 rf_ReconThread, 1563 rf_ReconThread,
1547 rrcopy,"raid_recon"); 1564 rrcopy,"raid_recon");
1548 return (0); 1565 return (0);
1549 1566
1550 /* invoke a copyback operation after recon on whatever disk 1567 /* invoke a copyback operation after recon on whatever disk
1551 * needs it, if any */ 1568 * needs it, if any */
1552 case RAIDFRAME_COPYBACK: 1569 case RAIDFRAME_COPYBACK:
1553 1570
1554 if (raidPtr->Layout.map->faultsTolerated == 0) { 1571 if (raidPtr->Layout.map->faultsTolerated == 0) {
1555 /* This makes no sense on a RAID 0!! */ 1572 /* This makes no sense on a RAID 0!! */
1556 return(EINVAL); 1573 return(EINVAL);
1557 } 1574 }
1558 1575
1559 if (raidPtr->copyback_in_progress == 1) { 1576 if (raidPtr->copyback_in_progress == 1) {
1560 /* Copyback is already in progress! */ 1577 /* Copyback is already in progress! */
1561 return(EINVAL); 1578 return(EINVAL);
1562 } 1579 }
1563 1580
1564 retcode = RF_CREATE_THREAD(raidPtr->copyback_thread, 1581 retcode = RF_CREATE_THREAD(raidPtr->copyback_thread,
1565 rf_CopybackThread, 1582 rf_CopybackThread,
1566 raidPtr,"raid_copyback"); 1583 raidPtr,"raid_copyback");
1567 return (retcode); 1584 return (retcode);
1568 1585
1569 /* return the percentage completion of reconstruction */ 1586 /* return the percentage completion of reconstruction */
1570 case RAIDFRAME_CHECK_RECON_STATUS: 1587 case RAIDFRAME_CHECK_RECON_STATUS:
1571 if (raidPtr->Layout.map->faultsTolerated == 0) { 1588 if (raidPtr->Layout.map->faultsTolerated == 0) {
1572 /* This makes no sense on a RAID 0, so tell the 1589 /* This makes no sense on a RAID 0, so tell the
1573 user it's done. */ 1590 user it's done. */
1574 *(int *) data = 100; 1591 *(int *) data = 100;
1575 return(0); 1592 return(0);
1576 } 1593 }
1577 if (raidPtr->status != rf_rs_reconstructing) 1594 if (raidPtr->status != rf_rs_reconstructing)
1578 *(int *) data = 100; 1595 *(int *) data = 100;
1579 else { 1596 else {
1580 if (raidPtr->reconControl->numRUsTotal > 0) { 1597 if (raidPtr->reconControl->numRUsTotal > 0) {
1581 *(int *) data = (raidPtr->reconControl->numRUsComplete * 100 / raidPtr->reconControl->numRUsTotal); 1598 *(int *) data = (raidPtr->reconControl->numRUsComplete * 100 / raidPtr->reconControl->numRUsTotal);
1582 } else { 1599 } else {
1583 *(int *) data = 0; 1600 *(int *) data = 0;
1584 } 1601 }
1585 } 1602 }
1586 return (0); 1603 return (0);
1587 case RAIDFRAME_CHECK_RECON_STATUS_EXT: 1604 case RAIDFRAME_CHECK_RECON_STATUS_EXT:
1588 progressInfoPtr = (RF_ProgressInfo_t **) data; 1605 progressInfoPtr = (RF_ProgressInfo_t **) data;
1589 if (raidPtr->status != rf_rs_reconstructing) { 1606 if (raidPtr->status != rf_rs_reconstructing) {
1590 progressInfo.remaining = 0; 1607 progressInfo.remaining = 0;
1591 progressInfo.completed = 100; 1608 progressInfo.completed = 100;
1592 progressInfo.total = 100; 1609 progressInfo.total = 100;
1593 } else { 1610 } else {
1594 progressInfo.total = 1611 progressInfo.total =
1595 raidPtr->reconControl->numRUsTotal; 1612 raidPtr->reconControl->numRUsTotal;
1596 progressInfo.completed = 1613 progressInfo.completed =
1597 raidPtr->reconControl->numRUsComplete; 1614 raidPtr->reconControl->numRUsComplete;
1598 progressInfo.remaining = progressInfo.total - 1615 progressInfo.remaining = progressInfo.total -
1599 progressInfo.completed; 1616 progressInfo.completed;
1600 } 1617 }
1601 retcode = copyout(&progressInfo, *progressInfoPtr, 1618 retcode = copyout(&progressInfo, *progressInfoPtr,
1602 sizeof(RF_ProgressInfo_t)); 1619 sizeof(RF_ProgressInfo_t));
1603 return (retcode); 1620 return (retcode);
1604 1621
1605 case RAIDFRAME_CHECK_PARITYREWRITE_STATUS: 1622 case RAIDFRAME_CHECK_PARITYREWRITE_STATUS:
1606 if (raidPtr->Layout.map->faultsTolerated == 0) { 1623 if (raidPtr->Layout.map->faultsTolerated == 0) {
1607 /* This makes no sense on a RAID 0, so tell the 1624 /* This makes no sense on a RAID 0, so tell the
1608 user it's done. */ 1625 user it's done. */
1609 *(int *) data = 100; 1626 *(int *) data = 100;
1610 return(0); 1627 return(0);
1611 } 1628 }
1612 if (raidPtr->parity_rewrite_in_progress == 1) { 1629 if (raidPtr->parity_rewrite_in_progress == 1) {
1613 *(int *) data = 100 * 1630 *(int *) data = 100 *
1614 raidPtr->parity_rewrite_stripes_done / 1631 raidPtr->parity_rewrite_stripes_done /
1615 raidPtr->Layout.numStripe; 1632 raidPtr->Layout.numStripe;
1616 } else { 1633 } else {
1617 *(int *) data = 100; 1634 *(int *) data = 100;
1618 } 1635 }
1619 return (0); 1636 return (0);
1620 1637
1621 case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT: 1638 case RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT:
1622 progressInfoPtr = (RF_ProgressInfo_t **) data; 1639 progressInfoPtr = (RF_ProgressInfo_t **) data;
1623 if (raidPtr->parity_rewrite_in_progress == 1) { 1640 if (raidPtr->parity_rewrite_in_progress == 1) {
1624 progressInfo.total = raidPtr->Layout.numStripe; 1641 progressInfo.total = raidPtr->Layout.numStripe;
1625 progressInfo.completed = 1642 progressInfo.completed =
1626 raidPtr->parity_rewrite_stripes_done; 1643 raidPtr->parity_rewrite_stripes_done;
1627 progressInfo.remaining = progressInfo.total - 1644 progressInfo.remaining = progressInfo.total -
1628 progressInfo.completed; 1645 progressInfo.completed;
1629 } else { 1646 } else {
1630 progressInfo.remaining = 0; 1647 progressInfo.remaining = 0;
1631 progressInfo.completed = 100; 1648 progressInfo.completed = 100;
1632 progressInfo.total = 100; 1649 progressInfo.total = 100;
1633 } 1650 }
1634 retcode = copyout(&progressInfo, *progressInfoPtr, 1651 retcode = copyout(&progressInfo, *progressInfoPtr,
1635 sizeof(RF_ProgressInfo_t)); 1652 sizeof(RF_ProgressInfo_t));
1636 return (retcode); 1653 return (retcode);
1637 1654
1638 case RAIDFRAME_CHECK_COPYBACK_STATUS: 1655 case RAIDFRAME_CHECK_COPYBACK_STATUS:
1639 if (raidPtr->Layout.map->faultsTolerated == 0) { 1656 if (raidPtr->Layout.map->faultsTolerated == 0) {
1640 /* This makes no sense on a RAID 0 */ 1657 /* This makes no sense on a RAID 0 */
1641 *(int *) data = 100; 1658 *(int *) data = 100;
1642 return(0); 1659 return(0);
1643 } 1660 }
1644 if (raidPtr->copyback_in_progress == 1) { 1661 if (raidPtr->copyback_in_progress == 1) {
1645 *(int *) data = 100 * raidPtr->copyback_stripes_done / 1662 *(int *) data = 100 * raidPtr->copyback_stripes_done /
1646 raidPtr->Layout.numStripe; 1663 raidPtr->Layout.numStripe;
1647 } else { 1664 } else {
1648 *(int *) data = 100; 1665 *(int *) data = 100;
1649 } 1666 }
1650 return (0); 1667 return (0);
1651 1668
1652 case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT: 1669 case RAIDFRAME_CHECK_COPYBACK_STATUS_EXT:
1653 progressInfoPtr = (RF_ProgressInfo_t **) data; 1670 progressInfoPtr = (RF_ProgressInfo_t **) data;
1654 if (raidPtr->copyback_in_progress == 1) { 1671 if (raidPtr->copyback_in_progress == 1) {
1655 progressInfo.total = raidPtr->Layout.numStripe; 1672 progressInfo.total = raidPtr->Layout.numStripe;
1656 progressInfo.completed = 1673 progressInfo.completed =
1657 raidPtr->copyback_stripes_done; 1674 raidPtr->copyback_stripes_done;
1658 progressInfo.remaining = progressInfo.total - 1675 progressInfo.remaining = progressInfo.total -
1659 progressInfo.completed; 1676 progressInfo.completed;
1660 } else { 1677 } else {
1661 progressInfo.remaining = 0; 1678 progressInfo.remaining = 0;
1662 progressInfo.completed = 100; 1679 progressInfo.completed = 100;
1663 progressInfo.total = 100; 1680 progressInfo.total = 100;
1664 } 1681 }
1665 retcode = copyout(&progressInfo, *progressInfoPtr, 1682 retcode = copyout(&progressInfo, *progressInfoPtr,
1666 sizeof(RF_ProgressInfo_t)); 1683 sizeof(RF_ProgressInfo_t));
1667 return (retcode); 1684 return (retcode);
1668 1685
1669 /* the sparetable daemon calls this to wait for the kernel to 1686 /* the sparetable daemon calls this to wait for the kernel to
1670 * need a spare table. this ioctl does not return until a 1687 * need a spare table. this ioctl does not return until a
1671 * spare table is needed. XXX -- calling mpsleep here in the 1688 * spare table is needed. XXX -- calling mpsleep here in the
1672 * ioctl code is almost certainly wrong and evil. -- XXX XXX 1689 * ioctl code is almost certainly wrong and evil. -- XXX XXX
1673 * -- I should either compute the spare table in the kernel, 1690 * -- I should either compute the spare table in the kernel,
1674 * or have a different -- XXX XXX -- interface (a different 1691 * or have a different -- XXX XXX -- interface (a different
1675 * character device) for delivering the table -- XXX */ 1692 * character device) for delivering the table -- XXX */
1676#if 0 1693#if 0
1677 case RAIDFRAME_SPARET_WAIT: 1694 case RAIDFRAME_SPARET_WAIT:
1678 RF_LOCK_MUTEX(rf_sparet_wait_mutex); 1695 RF_LOCK_MUTEX(rf_sparet_wait_mutex);
1679 while (!rf_sparet_wait_queue) 1696 while (!rf_sparet_wait_queue)
1680 mpsleep(&rf_sparet_wait_queue, (PZERO + 1) | PCATCH, "sparet wait", 0, (void *) simple_lock_addr(rf_sparet_wait_mutex), MS_LOCK_SIMPLE); 1697 mpsleep(&rf_sparet_wait_queue, (PZERO + 1) | PCATCH, "sparet wait", 0, (void *) simple_lock_addr(rf_sparet_wait_mutex), MS_LOCK_SIMPLE);
1681 waitreq = rf_sparet_wait_queue; 1698 waitreq = rf_sparet_wait_queue;
1682 rf_sparet_wait_queue = rf_sparet_wait_queue->next; 1699 rf_sparet_wait_queue = rf_sparet_wait_queue->next;
1683 RF_UNLOCK_MUTEX(rf_sparet_wait_mutex); 1700 RF_UNLOCK_MUTEX(rf_sparet_wait_mutex);
1684 1701
1685 /* structure assignment */ 1702 /* structure assignment */
1686 *((RF_SparetWait_t *) data) = *waitreq; 1703 *((RF_SparetWait_t *) data) = *waitreq;
1687 1704
1688 RF_Free(waitreq, sizeof(*waitreq)); 1705 RF_Free(waitreq, sizeof(*waitreq));
1689 return (0); 1706 return (0);
1690 1707
1691 /* wakes up a process waiting on SPARET_WAIT and puts an error 1708 /* wakes up a process waiting on SPARET_WAIT and puts an error
1692 * code in it that will cause the dameon to exit */ 1709 * code in it that will cause the dameon to exit */
1693 case RAIDFRAME_ABORT_SPARET_WAIT: 1710 case RAIDFRAME_ABORT_SPARET_WAIT:
1694 RF_Malloc(waitreq, sizeof(*waitreq), (RF_SparetWait_t *)); 1711 RF_Malloc(waitreq, sizeof(*waitreq), (RF_SparetWait_t *));
1695 waitreq->fcol = -1; 1712 waitreq->fcol = -1;
1696 RF_LOCK_MUTEX(rf_sparet_wait_mutex); 1713 RF_LOCK_MUTEX(rf_sparet_wait_mutex);
1697 waitreq->next = rf_sparet_wait_queue; 1714 waitreq->next = rf_sparet_wait_queue;
1698 rf_sparet_wait_queue = waitreq; 1715 rf_sparet_wait_queue = waitreq;
1699 RF_UNLOCK_MUTEX(rf_sparet_wait_mutex); 1716 RF_UNLOCK_MUTEX(rf_sparet_wait_mutex);
1700 wakeup(&rf_sparet_wait_queue); 1717 wakeup(&rf_sparet_wait_queue);
1701 return (0); 1718 return (0);
1702 1719
1703 /* used by the spare table daemon to deliver a spare table 1720 /* used by the spare table daemon to deliver a spare table
1704 * into the kernel */ 1721 * into the kernel */
1705 case RAIDFRAME_SEND_SPARET: 1722 case RAIDFRAME_SEND_SPARET:
1706 1723
1707 /* install the spare table */ 1724 /* install the spare table */
1708 retcode = rf_SetSpareTable(raidPtr, *(void **) data); 1725 retcode = rf_SetSpareTable(raidPtr, *(void **) data);
1709 1726
1710 /* respond to the requestor. the return status of the spare 1727 /* respond to the requestor. the return status of the spare
1711 * table installation is passed in the "fcol" field */ 1728 * table installation is passed in the "fcol" field */
1712 RF_Malloc(waitreq, sizeof(*waitreq), (RF_SparetWait_t *)); 1729 RF_Malloc(waitreq, sizeof(*waitreq), (RF_SparetWait_t *));
1713 waitreq->fcol = retcode; 1730 waitreq->fcol = retcode;
1714 RF_LOCK_MUTEX(rf_sparet_wait_mutex); 1731 RF_LOCK_MUTEX(rf_sparet_wait_mutex);
1715 waitreq->next = rf_sparet_resp_queue; 1732 waitreq->next = rf_sparet_resp_queue;
1716 rf_sparet_resp_queue = waitreq; 1733 rf_sparet_resp_queue = waitreq;
1717 wakeup(&rf_sparet_resp_queue); 1734 wakeup(&rf_sparet_resp_queue);
1718 RF_UNLOCK_MUTEX(rf_sparet_wait_mutex); 1735 RF_UNLOCK_MUTEX(rf_sparet_wait_mutex);
1719 1736
1720 return (retcode); 1737 return (retcode);
1721#endif 1738#endif
1722 1739
1723 default: 1740 default:
1724 break; /* fall through to the os-specific code below */ 1741 break; /* fall through to the os-specific code below */
1725 1742
1726 } 1743 }
1727 1744
1728 if (!raidPtr->valid) 1745 if (!raidPtr->valid)
1729 return (EINVAL); 1746 return (EINVAL);
1730 1747
1731 /* 1748 /*
1732 * Add support for "regular" device ioctls here. 1749 * Add support for "regular" device ioctls here.
1733 */ 1750 */
1734  1751
1735 error = disk_ioctl(&rs->sc_dkdev, cmd, data, flag, l);  1752 error = disk_ioctl(&rs->sc_dkdev, cmd, data, flag, l);
1736 if (error != EPASSTHROUGH) 1753 if (error != EPASSTHROUGH)
1737 return (error); 1754 return (error);
1738 1755
1739 switch (cmd) { 1756 switch (cmd) {
1740 case DIOCGDINFO: 1757 case DIOCGDINFO:
1741 *(struct disklabel *) data = *(rs->sc_dkdev.dk_label); 1758 *(struct disklabel *) data = *(rs->sc_dkdev.dk_label);
1742 break; 1759 break;
1743#ifdef __HAVE_OLD_DISKLABEL 1760#ifdef __HAVE_OLD_DISKLABEL
1744 case ODIOCGDINFO: 1761 case ODIOCGDINFO:
1745 newlabel = *(rs->sc_dkdev.dk_label); 1762 newlabel = *(rs->sc_dkdev.dk_label);
1746 if (newlabel.d_npartitions > OLDMAXPARTITIONS) 1763 if (newlabel.d_npartitions > OLDMAXPARTITIONS)
1747 return ENOTTY; 1764 return ENOTTY;
1748 memcpy(data, &newlabel, sizeof (struct olddisklabel)); 1765 memcpy(data, &newlabel, sizeof (struct olddisklabel));
1749 break; 1766 break;
1750#endif 1767#endif
1751 1768
1752 case DIOCGPART: 1769 case DIOCGPART:
1753 ((struct partinfo *) data)->disklab = rs->sc_dkdev.dk_label; 1770 ((struct partinfo *) data)->disklab = rs->sc_dkdev.dk_label;
1754 ((struct partinfo *) data)->part = 1771 ((struct partinfo *) data)->part =
1755 &rs->sc_dkdev.dk_label->d_partitions[DISKPART(dev)]; 1772 &rs->sc_dkdev.dk_label->d_partitions[DISKPART(dev)];
1756 break; 1773 break;
1757 1774
1758 case DIOCWDINFO: 1775 case DIOCWDINFO:
1759 case DIOCSDINFO: 1776 case DIOCSDINFO:
1760#ifdef __HAVE_OLD_DISKLABEL 1777#ifdef __HAVE_OLD_DISKLABEL
1761 case ODIOCWDINFO: 1778 case ODIOCWDINFO:
1762 case ODIOCSDINFO: 1779 case ODIOCSDINFO:
1763#endif 1780#endif
1764 { 1781 {
1765 struct disklabel *lp; 1782 struct disklabel *lp;
1766#ifdef __HAVE_OLD_DISKLABEL 1783#ifdef __HAVE_OLD_DISKLABEL
1767 if (cmd == ODIOCSDINFO || cmd == ODIOCWDINFO) { 1784 if (cmd == ODIOCSDINFO || cmd == ODIOCWDINFO) {
1768 memset(&newlabel, 0, sizeof newlabel); 1785 memset(&newlabel, 0, sizeof newlabel);
1769 memcpy(&newlabel, data, sizeof (struct olddisklabel)); 1786 memcpy(&newlabel, data, sizeof (struct olddisklabel));
1770 lp = &newlabel; 1787 lp = &newlabel;
1771 } else 1788 } else
1772#endif 1789#endif
1773 lp = (struct disklabel *)data; 1790 lp = (struct disklabel *)data;
1774 1791
1775 if ((error = raidlock(rs)) != 0) 1792 if ((error = raidlock(rs)) != 0)
1776 return (error); 1793 return (error);
1777 1794
1778 rs->sc_flags |= RAIDF_LABELLING; 1795 rs->sc_flags |= RAIDF_LABELLING;
1779 1796
1780 error = setdisklabel(rs->sc_dkdev.dk_label, 1797 error = setdisklabel(rs->sc_dkdev.dk_label,
1781 lp, 0, rs->sc_dkdev.dk_cpulabel); 1798 lp, 0, rs->sc_dkdev.dk_cpulabel);
1782 if (error == 0) { 1799 if (error == 0) {
1783 if (cmd == DIOCWDINFO 1800 if (cmd == DIOCWDINFO
1784#ifdef __HAVE_OLD_DISKLABEL 1801#ifdef __HAVE_OLD_DISKLABEL
1785 || cmd == ODIOCWDINFO 1802 || cmd == ODIOCWDINFO
1786#endif 1803#endif
1787 ) 1804 )
1788 error = writedisklabel(RAIDLABELDEV(dev), 1805 error = writedisklabel(RAIDLABELDEV(dev),
1789 raidstrategy, rs->sc_dkdev.dk_label, 1806 raidstrategy, rs->sc_dkdev.dk_label,
1790 rs->sc_dkdev.dk_cpulabel); 1807 rs->sc_dkdev.dk_cpulabel);
1791 } 1808 }
1792 rs->sc_flags &= ~RAIDF_LABELLING; 1809 rs->sc_flags &= ~RAIDF_LABELLING;
1793 1810
1794 raidunlock(rs); 1811 raidunlock(rs);
1795 1812
1796 if (error) 1813 if (error)
1797 return (error); 1814 return (error);
1798 break; 1815 break;
1799 } 1816 }
1800 1817
1801 case DIOCWLABEL: 1818 case DIOCWLABEL:
1802 if (*(int *) data != 0) 1819 if (*(int *) data != 0)
1803 rs->sc_flags |= RAIDF_WLABEL; 1820 rs->sc_flags |= RAIDF_WLABEL;
1804 else 1821 else
1805 rs->sc_flags &= ~RAIDF_WLABEL; 1822 rs->sc_flags &= ~RAIDF_WLABEL;
1806 break; 1823 break;
1807 1824
1808 case DIOCGDEFLABEL: 1825 case DIOCGDEFLABEL:
1809 raidgetdefaultlabel(raidPtr, rs, (struct disklabel *) data); 1826 raidgetdefaultlabel(raidPtr, rs, (struct disklabel *) data);
1810 break; 1827 break;
1811 1828
1812#ifdef __HAVE_OLD_DISKLABEL 1829#ifdef __HAVE_OLD_DISKLABEL
1813 case ODIOCGDEFLABEL: 1830 case ODIOCGDEFLABEL:
1814 raidgetdefaultlabel(raidPtr, rs, &newlabel); 1831 raidgetdefaultlabel(raidPtr, rs, &newlabel);
1815 if (newlabel.d_npartitions > OLDMAXPARTITIONS) 1832 if (newlabel.d_npartitions > OLDMAXPARTITIONS)
1816 return ENOTTY; 1833 return ENOTTY;
1817 memcpy(data, &newlabel, sizeof (struct olddisklabel)); 1834 memcpy(data, &newlabel, sizeof (struct olddisklabel));
1818 break; 1835 break;
1819#endif 1836#endif
1820 1837
1821 case DIOCAWEDGE: 1838 case DIOCAWEDGE:
1822 case DIOCDWEDGE: 1839 case DIOCDWEDGE:
1823 dkw = (void *)data; 1840 dkw = (void *)data;
1824 1841
1825 /* If the ioctl happens here, the parent is us. */ 1842 /* If the ioctl happens here, the parent is us. */
1826 (void)strcpy(dkw->dkw_parent, rs->sc_xname); 1843 (void)strcpy(dkw->dkw_parent, rs->sc_xname);
1827 return cmd == DIOCAWEDGE ? dkwedge_add(dkw) : dkwedge_del(dkw); 1844 return cmd == DIOCAWEDGE ? dkwedge_add(dkw) : dkwedge_del(dkw);
1828 1845
1829 case DIOCLWEDGES: 1846 case DIOCLWEDGES:
1830 return dkwedge_list(&rs->sc_dkdev, 1847 return dkwedge_list(&rs->sc_dkdev,
1831 (struct dkwedge_list *)data, l); 1848 (struct dkwedge_list *)data, l);
1832 case DIOCCACHESYNC: 1849 case DIOCCACHESYNC:
1833 return rf_sync_component_caches(raidPtr); 1850 return rf_sync_component_caches(raidPtr);
1834 default: 1851 default:
1835 retcode = ENOTTY; 1852 retcode = ENOTTY;
1836 } 1853 }
1837 return (retcode); 1854 return (retcode);
1838 1855
1839} 1856}
1840 1857
1841 1858
1842/* raidinit -- complete the rest of the initialization for the 1859/* raidinit -- complete the rest of the initialization for the
1843 RAIDframe device. */ 1860 RAIDframe device. */
1844 1861
1845 1862
1846static void 1863static void
1847raidinit(RF_Raid_t *raidPtr) 1864raidinit(RF_Raid_t *raidPtr)
1848{ 1865{
1849 cfdata_t cf; 1866 cfdata_t cf;
1850 struct raid_softc *rs; 1867 struct raid_softc *rs;
1851 int unit; 1868 int unit;
1852 1869
1853 unit = raidPtr->raidid; 1870 unit = raidPtr->raidid;
1854 1871
1855 rs = &raid_softc[unit]; 1872 rs = &raid_softc[unit];
1856 1873
1857 /* XXX should check return code first... */ 1874 /* XXX should check return code first... */
1858 rs->sc_flags |= RAIDF_INITED; 1875 rs->sc_flags |= RAIDF_INITED;
1859 1876
1860 /* XXX doesn't check bounds. */ 1877 /* XXX doesn't check bounds. */
1861 snprintf(rs->sc_xname, sizeof(rs->sc_xname), "raid%d", unit); 1878 snprintf(rs->sc_xname, sizeof(rs->sc_xname), "raid%d", unit);
1862 1879
1863 /* attach the pseudo device */ 1880 /* attach the pseudo device */
1864 cf = malloc(sizeof(*cf), M_RAIDFRAME, M_WAITOK); 1881 cf = malloc(sizeof(*cf), M_RAIDFRAME, M_WAITOK);
1865 cf->cf_name = raid_cd.cd_name; 1882 cf->cf_name = raid_cd.cd_name;
1866 cf->cf_atname = raid_cd.cd_name; 1883 cf->cf_atname = raid_cd.cd_name;
1867 cf->cf_unit = unit; 1884 cf->cf_unit = unit;
1868 cf->cf_fstate = FSTATE_STAR; 1885 cf->cf_fstate = FSTATE_STAR;
1869 1886
1870 rs->sc_dev = config_attach_pseudo(cf); 1887 rs->sc_dev = config_attach_pseudo(cf);
1871 1888
1872 if (rs->sc_dev==NULL) { 1889 if (rs->sc_dev==NULL) {
1873 printf("raid%d: config_attach_pseudo failed\n", 1890 printf("raid%d: config_attach_pseudo failed\n",
1874 raidPtr->raidid); 1891 raidPtr->raidid);
1875 rs->sc_flags &= ~RAIDF_INITED; 1892 rs->sc_flags &= ~RAIDF_INITED;
1876 free(cf, M_RAIDFRAME); 1893 free(cf, M_RAIDFRAME);
1877 return; 1894 return;
1878 } 1895 }
1879 1896
1880 /* disk_attach actually creates space for the CPU disklabel, among 1897 /* disk_attach actually creates space for the CPU disklabel, among
1881 * other things, so it's critical to call this *BEFORE* we try putzing 1898 * other things, so it's critical to call this *BEFORE* we try putzing
1882 * with disklabels. */ 1899 * with disklabels. */
1883 1900
1884 disk_init(&rs->sc_dkdev, rs->sc_xname, &rf_dkdriver); 1901 disk_init(&rs->sc_dkdev, rs->sc_xname, &rf_dkdriver);
1885 disk_attach(&rs->sc_dkdev); 1902 disk_attach(&rs->sc_dkdev);
1886 1903
1887 /* XXX There may be a weird interaction here between this, and 1904 /* XXX There may be a weird interaction here between this, and
1888 * protectedSectors, as used in RAIDframe. */ 1905 * protectedSectors, as used in RAIDframe. */
1889 1906
1890 rs->sc_size = raidPtr->totalSectors; 1907 rs->sc_size = raidPtr->totalSectors;
1891 1908
1892 dkwedge_discover(&rs->sc_dkdev); 1909 dkwedge_discover(&rs->sc_dkdev);
1893 1910
1894 rf_set_properties(rs, raidPtr); 1911 rf_set_properties(rs, raidPtr);
1895 1912
1896} 1913}
1897#if (RF_INCLUDE_PARITY_DECLUSTERING_DS > 0) 1914#if (RF_INCLUDE_PARITY_DECLUSTERING_DS > 0)
1898/* wake up the daemon & tell it to get us a spare table 1915/* wake up the daemon & tell it to get us a spare table
1899 * XXX 1916 * XXX
1900 * the entries in the queues should be tagged with the raidPtr 1917 * the entries in the queues should be tagged with the raidPtr
1901 * so that in the extremely rare case that two recons happen at once, 1918 * so that in the extremely rare case that two recons happen at once,
1902 * we know for which device were requesting a spare table 1919 * we know for which device were requesting a spare table
1903 * XXX 1920 * XXX
1904 * 1921 *
1905 * XXX This code is not currently used. GO 1922 * XXX This code is not currently used. GO
1906 */ 1923 */
1907int 1924int
1908rf_GetSpareTableFromDaemon(RF_SparetWait_t *req) 1925rf_GetSpareTableFromDaemon(RF_SparetWait_t *req)
1909{ 1926{
1910 int retcode; 1927 int retcode;
1911 1928
1912 RF_LOCK_MUTEX(rf_sparet_wait_mutex); 1929 RF_LOCK_MUTEX(rf_sparet_wait_mutex);
1913 req->next = rf_sparet_wait_queue; 1930 req->next = rf_sparet_wait_queue;
1914 rf_sparet_wait_queue = req; 1931 rf_sparet_wait_queue = req;
1915 wakeup(&rf_sparet_wait_queue); 1932 wakeup(&rf_sparet_wait_queue);
1916 1933
1917 /* mpsleep unlocks the mutex */ 1934 /* mpsleep unlocks the mutex */
1918 while (!rf_sparet_resp_queue) { 1935 while (!rf_sparet_resp_queue) {
1919 tsleep(&rf_sparet_resp_queue, PRIBIO, 1936 tsleep(&rf_sparet_resp_queue, PRIBIO,
1920 "raidframe getsparetable", 0); 1937 "raidframe getsparetable", 0);
1921 } 1938 }
1922 req = rf_sparet_resp_queue; 1939 req = rf_sparet_resp_queue;
1923 rf_sparet_resp_queue = req->next; 1940 rf_sparet_resp_queue = req->next;
1924 RF_UNLOCK_MUTEX(rf_sparet_wait_mutex); 1941 RF_UNLOCK_MUTEX(rf_sparet_wait_mutex);
1925 1942
1926 retcode = req->fcol; 1943 retcode = req->fcol;
1927 RF_Free(req, sizeof(*req)); /* this is not the same req as we 1944 RF_Free(req, sizeof(*req)); /* this is not the same req as we
1928 * alloc'd */ 1945 * alloc'd */
1929 return (retcode); 1946 return (retcode);
1930} 1947}
1931#endif 1948#endif
1932 1949
1933/* a wrapper around rf_DoAccess that extracts appropriate info from the 1950/* a wrapper around rf_DoAccess that extracts appropriate info from the
1934 * bp & passes it down. 1951 * bp & passes it down.
1935 * any calls originating in the kernel must use non-blocking I/O 1952 * any calls originating in the kernel must use non-blocking I/O
1936 * do some extra sanity checking to return "appropriate" error values for 1953 * do some extra sanity checking to return "appropriate" error values for
1937 * certain conditions (to make some standard utilities work) 1954 * certain conditions (to make some standard utilities work)
1938 * 1955 *
1939 * Formerly known as: rf_DoAccessKernel 1956 * Formerly known as: rf_DoAccessKernel
1940 */ 1957 */
1941void 1958void
1942raidstart(RF_Raid_t *raidPtr) 1959raidstart(RF_Raid_t *raidPtr)
1943{ 1960{
1944 RF_SectorCount_t num_blocks, pb, sum; 1961 RF_SectorCount_t num_blocks, pb, sum;
1945 RF_RaidAddr_t raid_addr; 1962 RF_RaidAddr_t raid_addr;
1946 struct partition *pp; 1963 struct partition *pp;
1947 daddr_t blocknum; 1964 daddr_t blocknum;
1948 int unit; 1965 int unit;
1949 struct raid_softc *rs; 1966 struct raid_softc *rs;
1950 int do_async; 1967 int do_async;
1951 struct buf *bp; 1968 struct buf *bp;
1952 int rc; 1969 int rc;
1953 1970
1954 unit = raidPtr->raidid; 1971 unit = raidPtr->raidid;
1955 rs = &raid_softc[unit]; 1972 rs = &raid_softc[unit];
1956 1973
1957 /* quick check to see if anything has died recently */ 1974 /* quick check to see if anything has died recently */
1958 RF_LOCK_MUTEX(raidPtr->mutex); 1975 RF_LOCK_MUTEX(raidPtr->mutex);
1959 if (raidPtr->numNewFailures > 0) { 1976 if (raidPtr->numNewFailures > 0) {
1960 RF_UNLOCK_MUTEX(raidPtr->mutex); 1977 RF_UNLOCK_MUTEX(raidPtr->mutex);
1961 rf_update_component_labels(raidPtr, 1978 rf_update_component_labels(raidPtr,
1962 RF_NORMAL_COMPONENT_UPDATE); 1979 RF_NORMAL_COMPONENT_UPDATE);
1963 RF_LOCK_MUTEX(raidPtr->mutex); 1980 RF_LOCK_MUTEX(raidPtr->mutex);
1964 raidPtr->numNewFailures--; 1981 raidPtr->numNewFailures--;
1965 } 1982 }
1966 1983
1967 /* Check to see if we're at the limit... */ 1984 /* Check to see if we're at the limit... */
1968 while (raidPtr->openings > 0) { 1985 while (raidPtr->openings > 0) {
1969 RF_UNLOCK_MUTEX(raidPtr->mutex); 1986 RF_UNLOCK_MUTEX(raidPtr->mutex);
1970 1987
1971 /* get the next item, if any, from the queue */ 1988 /* get the next item, if any, from the queue */
1972 if ((bp = bufq_get(rs->buf_queue)) == NULL) { 1989 if ((bp = bufq_get(rs->buf_queue)) == NULL) {
1973 /* nothing more to do */ 1990 /* nothing more to do */
1974 return; 1991 return;
1975 } 1992 }
1976 1993
1977 /* Ok, for the bp we have here, bp->b_blkno is relative to the 1994 /* Ok, for the bp we have here, bp->b_blkno is relative to the
1978 * partition.. Need to make it absolute to the underlying 1995 * partition.. Need to make it absolute to the underlying
1979 * device.. */ 1996 * device.. */
1980 1997
1981 blocknum = bp->b_blkno; 1998 blocknum = bp->b_blkno;
1982 if (DISKPART(bp->b_dev) != RAW_PART) { 1999 if (DISKPART(bp->b_dev) != RAW_PART) {
1983 pp = &rs->sc_dkdev.dk_label->d_partitions[DISKPART(bp->b_dev)]; 2000 pp = &rs->sc_dkdev.dk_label->d_partitions[DISKPART(bp->b_dev)];
1984 blocknum += pp->p_offset; 2001 blocknum += pp->p_offset;
1985 } 2002 }
1986 2003
1987 db1_printf(("Blocks: %d, %d\n", (int) bp->b_blkno, 2004 db1_printf(("Blocks: %d, %d\n", (int) bp->b_blkno,
1988 (int) blocknum)); 2005 (int) blocknum));
1989 2006
1990 db1_printf(("bp->b_bcount = %d\n", (int) bp->b_bcount)); 2007 db1_printf(("bp->b_bcount = %d\n", (int) bp->b_bcount));
1991 db1_printf(("bp->b_resid = %d\n", (int) bp->b_resid)); 2008 db1_printf(("bp->b_resid = %d\n", (int) bp->b_resid));
1992 2009
1993 /* *THIS* is where we adjust what block we're going to... 2010 /* *THIS* is where we adjust what block we're going to...
1994 * but DO NOT TOUCH bp->b_blkno!!! */ 2011 * but DO NOT TOUCH bp->b_blkno!!! */
1995 raid_addr = blocknum; 2012 raid_addr = blocknum;
1996 2013
1997 num_blocks = bp->b_bcount >> raidPtr->logBytesPerSector; 2014 num_blocks = bp->b_bcount >> raidPtr->logBytesPerSector;
1998 pb = (bp->b_bcount & raidPtr->sectorMask) ? 1 : 0; 2015 pb = (bp->b_bcount & raidPtr->sectorMask) ? 1 : 0;
1999 sum = raid_addr + num_blocks + pb; 2016 sum = raid_addr + num_blocks + pb;
2000 if (1 || rf_debugKernelAccess) { 2017 if (1 || rf_debugKernelAccess) {
2001 db1_printf(("raid_addr=%d sum=%d num_blocks=%d(+%d) (%d)\n", 2018 db1_printf(("raid_addr=%d sum=%d num_blocks=%d(+%d) (%d)\n",
2002 (int) raid_addr, (int) sum, (int) num_blocks, 2019 (int) raid_addr, (int) sum, (int) num_blocks,
2003 (int) pb, (int) bp->b_resid)); 2020 (int) pb, (int) bp->b_resid));
2004 } 2021 }
2005 if ((sum > raidPtr->totalSectors) || (sum < raid_addr) 2022 if ((sum > raidPtr->totalSectors) || (sum < raid_addr)
2006 || (sum < num_blocks) || (sum < pb)) { 2023 || (sum < num_blocks) || (sum < pb)) {
2007 bp->b_error = ENOSPC; 2024 bp->b_error = ENOSPC;
2008 bp->b_resid = bp->b_bcount; 2025 bp->b_resid = bp->b_bcount;
2009 biodone(bp); 2026 biodone(bp);
2010 RF_LOCK_MUTEX(raidPtr->mutex); 2027 RF_LOCK_MUTEX(raidPtr->mutex);
2011 continue; 2028 continue;
2012 } 2029 }
2013 /* 2030 /*
2014 * XXX rf_DoAccess() should do this, not just DoAccessKernel() 2031 * XXX rf_DoAccess() should do this, not just DoAccessKernel()
2015 */ 2032 */
2016 2033
2017 if (bp->b_bcount & raidPtr->sectorMask) { 2034 if (bp->b_bcount & raidPtr->sectorMask) {
2018 bp->b_error = EINVAL; 2035 bp->b_error = EINVAL;
2019 bp->b_resid = bp->b_bcount; 2036 bp->b_resid = bp->b_bcount;
2020 biodone(bp); 2037 biodone(bp);
2021 RF_LOCK_MUTEX(raidPtr->mutex); 2038 RF_LOCK_MUTEX(raidPtr->mutex);
2022 continue; 2039 continue;
2023 2040
2024 } 2041 }
2025 db1_printf(("Calling DoAccess..\n")); 2042 db1_printf(("Calling DoAccess..\n"));
2026 2043
2027 2044
2028 RF_LOCK_MUTEX(raidPtr->mutex); 2045 RF_LOCK_MUTEX(raidPtr->mutex);
2029 raidPtr->openings--; 2046 raidPtr->openings--;
2030 RF_UNLOCK_MUTEX(raidPtr->mutex); 2047 RF_UNLOCK_MUTEX(raidPtr->mutex);
2031 2048
2032 /* 2049 /*
2033 * Everything is async. 2050 * Everything is async.
2034 */ 2051 */
2035 do_async = 1; 2052 do_async = 1;
2036 2053
2037 disk_busy(&rs->sc_dkdev); 2054 disk_busy(&rs->sc_dkdev);
2038 2055
2039 /* XXX we're still at splbio() here... do we *really* 2056 /* XXX we're still at splbio() here... do we *really*
2040 need to be? */ 2057 need to be? */
2041 2058
2042 /* don't ever condition on bp->b_flags & B_WRITE. 2059 /* don't ever condition on bp->b_flags & B_WRITE.
2043 * always condition on B_READ instead */ 2060 * always condition on B_READ instead */
2044 2061
2045 rc = rf_DoAccess(raidPtr, (bp->b_flags & B_READ) ? 2062 rc = rf_DoAccess(raidPtr, (bp->b_flags & B_READ) ?
2046 RF_IO_TYPE_READ : RF_IO_TYPE_WRITE, 2063 RF_IO_TYPE_READ : RF_IO_TYPE_WRITE,
2047 do_async, raid_addr, num_blocks, 2064 do_async, raid_addr, num_blocks,
2048 bp->b_data, bp, RF_DAG_NONBLOCKING_IO); 2065 bp->b_data, bp, RF_DAG_NONBLOCKING_IO);
2049 2066
2050 if (rc) { 2067 if (rc) {
2051 bp->b_error = rc; 2068 bp->b_error = rc;
2052 bp->b_resid = bp->b_bcount; 2069 bp->b_resid = bp->b_bcount;
2053 biodone(bp); 2070 biodone(bp);
2054 /* continue loop */ 2071 /* continue loop */
2055 } 2072 }
2056 2073
2057 RF_LOCK_MUTEX(raidPtr->mutex); 2074 RF_LOCK_MUTEX(raidPtr->mutex);
2058 } 2075 }
2059 RF_UNLOCK_MUTEX(raidPtr->mutex); 2076 RF_UNLOCK_MUTEX(raidPtr->mutex);
2060} 2077}
2061 2078
2062 2079
2063 2080
2064 2081
2065/* invoke an I/O from kernel mode. Disk queue should be locked upon entry */ 2082/* invoke an I/O from kernel mode. Disk queue should be locked upon entry */
2066 2083
2067int 2084int
2068rf_DispatchKernelIO(RF_DiskQueue_t *queue, RF_DiskQueueData_t *req) 2085rf_DispatchKernelIO(RF_DiskQueue_t *queue, RF_DiskQueueData_t *req)
2069{ 2086{
2070 int op = (req->type == RF_IO_TYPE_READ) ? B_READ : B_WRITE; 2087 int op = (req->type == RF_IO_TYPE_READ) ? B_READ : B_WRITE;
2071 struct buf *bp; 2088 struct buf *bp;
2072 2089
2073 req->queue = queue; 2090 req->queue = queue;
2074 bp = req->bp; 2091 bp = req->bp;
2075 2092
2076 switch (req->type) { 2093 switch (req->type) {
2077 case RF_IO_TYPE_NOP: /* used primarily to unlock a locked queue */ 2094 case RF_IO_TYPE_NOP: /* used primarily to unlock a locked queue */
2078 /* XXX need to do something extra here.. */ 2095 /* XXX need to do something extra here.. */
2079 /* I'm leaving this in, as I've never actually seen it used, 2096 /* I'm leaving this in, as I've never actually seen it used,
2080 * and I'd like folks to report it... GO */ 2097 * and I'd like folks to report it... GO */
2081 printf(("WAKEUP CALLED\n")); 2098 printf(("WAKEUP CALLED\n"));
2082 queue->numOutstanding++; 2099 queue->numOutstanding++;
2083 2100
2084 bp->b_flags = 0; 2101 bp->b_flags = 0;
2085 bp->b_private = req; 2102 bp->b_private = req;
2086 2103
2087 KernelWakeupFunc(bp); 2104 KernelWakeupFunc(bp);
2088 break; 2105 break;
2089 2106
2090 case RF_IO_TYPE_READ: 2107 case RF_IO_TYPE_READ:
2091 case RF_IO_TYPE_WRITE: 2108 case RF_IO_TYPE_WRITE:
2092#if RF_ACC_TRACE > 0 2109#if RF_ACC_TRACE > 0
2093 if (req->tracerec) { 2110 if (req->tracerec) {
2094 RF_ETIMER_START(req->tracerec->timer); 2111 RF_ETIMER_START(req->tracerec->timer);
2095 } 2112 }
2096#endif 2113#endif
2097 InitBP(bp, queue->rf_cinfo->ci_vp, 2114 InitBP(bp, queue->rf_cinfo->ci_vp,
2098 op, queue->rf_cinfo->ci_dev, 2115 op, queue->rf_cinfo->ci_dev,
2099 req->sectorOffset, req->numSector, 2116 req->sectorOffset, req->numSector,
2100 req->buf, KernelWakeupFunc, (void *) req, 2117 req->buf, KernelWakeupFunc, (void *) req,
2101 queue->raidPtr->logBytesPerSector, req->b_proc); 2118 queue->raidPtr->logBytesPerSector, req->b_proc);
2102 2119
2103 if (rf_debugKernelAccess) { 2120 if (rf_debugKernelAccess) {
2104 db1_printf(("dispatch: bp->b_blkno = %ld\n", 2121 db1_printf(("dispatch: bp->b_blkno = %ld\n",
2105 (long) bp->b_blkno)); 2122 (long) bp->b_blkno));
2106 } 2123 }
2107 queue->numOutstanding++; 2124 queue->numOutstanding++;
2108 queue->last_deq_sector = req->sectorOffset; 2125 queue->last_deq_sector = req->sectorOffset;
2109 /* acc wouldn't have been let in if there were any pending 2126 /* acc wouldn't have been let in if there were any pending
2110 * reqs at any other priority */ 2127 * reqs at any other priority */
2111 queue->curPriority = req->priority; 2128 queue->curPriority = req->priority;
2112 2129
2113 db1_printf(("Going for %c to unit %d col %d\n", 2130 db1_printf(("Going for %c to unit %d col %d\n",
2114 req->type, queue->raidPtr->raidid, 2131 req->type, queue->raidPtr->raidid,
2115 queue->col)); 2132 queue->col));
2116 db1_printf(("sector %d count %d (%d bytes) %d\n", 2133 db1_printf(("sector %d count %d (%d bytes) %d\n",
2117 (int) req->sectorOffset, (int) req->numSector, 2134 (int) req->sectorOffset, (int) req->numSector,
2118 (int) (req->numSector << 2135 (int) (req->numSector <<
2119 queue->raidPtr->logBytesPerSector), 2136 queue->raidPtr->logBytesPerSector),
2120 (int) queue->raidPtr->logBytesPerSector)); 2137 (int) queue->raidPtr->logBytesPerSector));
2121 2138
2122 /* 2139 /*
2123 * XXX: drop lock here since this can block at  2140 * XXX: drop lock here since this can block at
2124 * least with backing SCSI devices. Retake it 2141 * least with backing SCSI devices. Retake it
2125 * to minimize fuss with calling interfaces. 2142 * to minimize fuss with calling interfaces.
2126 */ 2143 */
2127 2144
2128 RF_UNLOCK_QUEUE_MUTEX(queue, "unusedparam"); 2145 RF_UNLOCK_QUEUE_MUTEX(queue, "unusedparam");
2129 bdev_strategy(bp); 2146 bdev_strategy(bp);
2130 RF_LOCK_QUEUE_MUTEX(queue, "unusedparam"); 2147 RF_LOCK_QUEUE_MUTEX(queue, "unusedparam");
2131 break; 2148 break;
2132 2149
2133 default: 2150 default:
2134 panic("bad req->type in rf_DispatchKernelIO"); 2151 panic("bad req->type in rf_DispatchKernelIO");
2135 } 2152 }
2136 db1_printf(("Exiting from DispatchKernelIO\n")); 2153 db1_printf(("Exiting from DispatchKernelIO\n"));
2137 2154
2138 return (0); 2155 return (0);
2139} 2156}
2140/* this is the callback function associated with a I/O invoked from 2157/* this is the callback function associated with a I/O invoked from
2141 kernel code. 2158 kernel code.
2142 */ 2159 */
2143static void 2160static void
2144KernelWakeupFunc(struct buf *bp) 2161KernelWakeupFunc(struct buf *bp)
2145{ 2162{
2146 RF_DiskQueueData_t *req = NULL; 2163 RF_DiskQueueData_t *req = NULL;
2147 RF_DiskQueue_t *queue; 2164 RF_DiskQueue_t *queue;
2148 int s; 2165 int s;
2149 2166
2150 s = splbio(); 2167 s = splbio();
2151 db1_printf(("recovering the request queue:\n")); 2168 db1_printf(("recovering the request queue:\n"));
2152 req = bp->b_private; 2169 req = bp->b_private;
2153 2170
2154 queue = (RF_DiskQueue_t *) req->queue; 2171 queue = (RF_DiskQueue_t *) req->queue;
2155 2172
2156#if RF_ACC_TRACE > 0 2173#if RF_ACC_TRACE > 0
2157 if (req->tracerec) { 2174 if (req->tracerec) {
2158 RF_ETIMER_STOP(req->tracerec->timer); 2175 RF_ETIMER_STOP(req->tracerec->timer);
2159 RF_ETIMER_EVAL(req->tracerec->timer); 2176 RF_ETIMER_EVAL(req->tracerec->timer);
2160 RF_LOCK_MUTEX(rf_tracing_mutex); 2177 RF_LOCK_MUTEX(rf_tracing_mutex);
2161 req->tracerec->diskwait_us += RF_ETIMER_VAL_US(req->tracerec->timer); 2178 req->tracerec->diskwait_us += RF_ETIMER_VAL_US(req->tracerec->timer);
2162 req->tracerec->phys_io_us += RF_ETIMER_VAL_US(req->tracerec->timer); 2179 req->tracerec->phys_io_us += RF_ETIMER_VAL_US(req->tracerec->timer);
2163 req->tracerec->num_phys_ios++; 2180 req->tracerec->num_phys_ios++;
2164 RF_UNLOCK_MUTEX(rf_tracing_mutex); 2181 RF_UNLOCK_MUTEX(rf_tracing_mutex);
2165 } 2182 }
2166#endif 2183#endif
2167 2184
2168 /* XXX Ok, let's get aggressive... If b_error is set, let's go 2185 /* XXX Ok, let's get aggressive... If b_error is set, let's go
2169 * ballistic, and mark the component as hosed... */ 2186 * ballistic, and mark the component as hosed... */
2170 2187
2171 if (bp->b_error != 0) { 2188 if (bp->b_error != 0) {
2172 /* Mark the disk as dead */ 2189 /* Mark the disk as dead */
2173 /* but only mark it once... */ 2190 /* but only mark it once... */
2174 /* and only if it wouldn't leave this RAID set 2191 /* and only if it wouldn't leave this RAID set
2175 completely broken */ 2192 completely broken */
2176 if (((queue->raidPtr->Disks[queue->col].status == 2193 if (((queue->raidPtr->Disks[queue->col].status ==
2177 rf_ds_optimal) || 2194 rf_ds_optimal) ||
2178 (queue->raidPtr->Disks[queue->col].status == 2195 (queue->raidPtr->Disks[queue->col].status ==
2179 rf_ds_used_spare)) &&  2196 rf_ds_used_spare)) &&
2180 (queue->raidPtr->numFailures < 2197 (queue->raidPtr->numFailures <
2181 queue->raidPtr->Layout.map->faultsTolerated)) { 2198 queue->raidPtr->Layout.map->faultsTolerated)) {
2182 printf("raid%d: IO Error. Marking %s as failed.\n", 2199 printf("raid%d: IO Error. Marking %s as failed.\n",
2183 queue->raidPtr->raidid, 2200 queue->raidPtr->raidid,
2184 queue->raidPtr->Disks[queue->col].devname); 2201 queue->raidPtr->Disks[queue->col].devname);
2185 queue->raidPtr->Disks[queue->col].status = 2202 queue->raidPtr->Disks[queue->col].status =
2186 rf_ds_failed; 2203 rf_ds_failed;
2187 queue->raidPtr->status = rf_rs_degraded; 2204 queue->raidPtr->status = rf_rs_degraded;
2188 queue->raidPtr->numFailures++; 2205 queue->raidPtr->numFailures++;
2189 queue->raidPtr->numNewFailures++; 2206 queue->raidPtr->numNewFailures++;
2190 } else { /* Disk is already dead... */ 2207 } else { /* Disk is already dead... */
2191 /* printf("Disk already marked as dead!\n"); */ 2208 /* printf("Disk already marked as dead!\n"); */
2192 } 2209 }
2193 2210
2194 } 2211 }
2195 2212
2196 /* Fill in the error value */ 2213 /* Fill in the error value */
2197 2214
2198 req->error = bp->b_error; 2215 req->error = bp->b_error;
2199 2216
2200 simple_lock(&queue->raidPtr->iodone_lock); 2217 simple_lock(&queue->raidPtr->iodone_lock);
2201 2218
2202 /* Drop this one on the "finished" queue... */ 2219 /* Drop this one on the "finished" queue... */
2203 TAILQ_INSERT_TAIL(&(queue->raidPtr->iodone), req, iodone_entries); 2220 TAILQ_INSERT_TAIL(&(queue->raidPtr->iodone), req, iodone_entries);
2204 2221
2205 /* Let the raidio thread know there is work to be done. */ 2222 /* Let the raidio thread know there is work to be done. */
2206 wakeup(&(queue->raidPtr->iodone)); 2223 wakeup(&(queue->raidPtr->iodone));
2207 2224
2208 simple_unlock(&queue->raidPtr->iodone_lock); 2225 simple_unlock(&queue->raidPtr->iodone_lock);
2209 2226
@@ -2624,1084 +2641,1089 @@ rf_update_component_labels(RF_Raid_t *ra @@ -2624,1084 +2641,1089 @@ rf_update_component_labels(RF_Raid_t *ra
2624 2641
2625 */ 2642 */
2626 2643
2627 for(j=0;j<raidPtr->numCol;j++) { 2644 for(j=0;j<raidPtr->numCol;j++) {
2628 if (raidPtr->Disks[j].spareCol == sparecol) { 2645 if (raidPtr->Disks[j].spareCol == sparecol) {
2629 scol = j; 2646 scol = j;
2630 break; 2647 break;
2631 } 2648 }
2632 } 2649 }
2633 2650
2634 /* XXX shouldn't *really* need this... */ 2651 /* XXX shouldn't *really* need this... */
2635 raidread_component_label( 2652 raidread_component_label(
2636 raidPtr->Disks[sparecol].dev, 2653 raidPtr->Disks[sparecol].dev,
2637 raidPtr->raid_cinfo[sparecol].ci_vp, 2654 raidPtr->raid_cinfo[sparecol].ci_vp,
2638 &clabel); 2655 &clabel);
2639 /* make sure status is noted */ 2656 /* make sure status is noted */
2640 2657
2641 raid_init_component_label(raidPtr, &clabel); 2658 raid_init_component_label(raidPtr, &clabel);
2642 2659
2643 clabel.mod_counter = raidPtr->mod_counter; 2660 clabel.mod_counter = raidPtr->mod_counter;
2644 clabel.column = scol; 2661 clabel.column = scol;
2645 clabel.status = rf_ds_optimal; 2662 clabel.status = rf_ds_optimal;
2646 clabel.last_unit = raidPtr->raidid; 2663 clabel.last_unit = raidPtr->raidid;
2647 2664
2648 raidwrite_component_label( 2665 raidwrite_component_label(
2649 raidPtr->Disks[sparecol].dev, 2666 raidPtr->Disks[sparecol].dev,
2650 raidPtr->raid_cinfo[sparecol].ci_vp, 2667 raidPtr->raid_cinfo[sparecol].ci_vp,
2651 &clabel); 2668 &clabel);
2652 if (final == RF_FINAL_COMPONENT_UPDATE) { 2669 if (final == RF_FINAL_COMPONENT_UPDATE) {
2653 if (raidPtr->parity_good == RF_RAID_CLEAN) { 2670 if (raidPtr->parity_good == RF_RAID_CLEAN) {
2654 raidmarkclean( raidPtr->Disks[sparecol].dev, 2671 raidmarkclean( raidPtr->Disks[sparecol].dev,
2655 raidPtr->raid_cinfo[sparecol].ci_vp, 2672 raidPtr->raid_cinfo[sparecol].ci_vp,
2656 raidPtr->mod_counter); 2673 raidPtr->mod_counter);
2657 } 2674 }
2658 } 2675 }
2659 } 2676 }
2660 } 2677 }
2661} 2678}
2662 2679
2663void 2680void
2664rf_close_component(RF_Raid_t *raidPtr, struct vnode *vp, int auto_configured) 2681rf_close_component(RF_Raid_t *raidPtr, struct vnode *vp, int auto_configured)
2665{ 2682{
2666 2683
2667 if (vp != NULL) { 2684 if (vp != NULL) {
2668 if (auto_configured == 1) { 2685 if (auto_configured == 1) {
2669 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 2686 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
2670 VOP_CLOSE(vp, FREAD | FWRITE, NOCRED); 2687 VOP_CLOSE(vp, FREAD | FWRITE, NOCRED);
2671 vput(vp); 2688 vput(vp);
2672 2689
2673 } else { 2690 } else {
2674 (void) vn_close(vp, FREAD | FWRITE, curlwp->l_cred); 2691 (void) vn_close(vp, FREAD | FWRITE, curlwp->l_cred);
2675 } 2692 }
2676 } 2693 }
2677} 2694}
2678 2695
2679 2696
2680void 2697void
2681rf_UnconfigureVnodes(RF_Raid_t *raidPtr) 2698rf_UnconfigureVnodes(RF_Raid_t *raidPtr)
2682{ 2699{
2683 int r,c; 2700 int r,c;
2684 struct vnode *vp; 2701 struct vnode *vp;
2685 int acd; 2702 int acd;
2686 2703
2687 2704
2688 /* We take this opportunity to close the vnodes like we should.. */ 2705 /* We take this opportunity to close the vnodes like we should.. */
2689 2706
2690 for (c = 0; c < raidPtr->numCol; c++) { 2707 for (c = 0; c < raidPtr->numCol; c++) {
2691 vp = raidPtr->raid_cinfo[c].ci_vp; 2708 vp = raidPtr->raid_cinfo[c].ci_vp;
2692 acd = raidPtr->Disks[c].auto_configured; 2709 acd = raidPtr->Disks[c].auto_configured;
2693 rf_close_component(raidPtr, vp, acd); 2710 rf_close_component(raidPtr, vp, acd);
2694 raidPtr->raid_cinfo[c].ci_vp = NULL; 2711 raidPtr->raid_cinfo[c].ci_vp = NULL;
2695 raidPtr->Disks[c].auto_configured = 0; 2712 raidPtr->Disks[c].auto_configured = 0;
2696 } 2713 }
2697 2714
2698 for (r = 0; r < raidPtr->numSpare; r++) { 2715 for (r = 0; r < raidPtr->numSpare; r++) {
2699 vp = raidPtr->raid_cinfo[raidPtr->numCol + r].ci_vp; 2716 vp = raidPtr->raid_cinfo[raidPtr->numCol + r].ci_vp;
2700 acd = raidPtr->Disks[raidPtr->numCol + r].auto_configured; 2717 acd = raidPtr->Disks[raidPtr->numCol + r].auto_configured;
2701 rf_close_component(raidPtr, vp, acd); 2718 rf_close_component(raidPtr, vp, acd);
2702 raidPtr->raid_cinfo[raidPtr->numCol + r].ci_vp = NULL; 2719 raidPtr->raid_cinfo[raidPtr->numCol + r].ci_vp = NULL;
2703 raidPtr->Disks[raidPtr->numCol + r].auto_configured = 0; 2720 raidPtr->Disks[raidPtr->numCol + r].auto_configured = 0;
2704 } 2721 }
2705} 2722}
2706 2723
2707 2724
2708void 2725void
2709rf_ReconThread(struct rf_recon_req *req) 2726rf_ReconThread(struct rf_recon_req *req)
2710{ 2727{
2711 int s; 2728 int s;
2712 RF_Raid_t *raidPtr; 2729 RF_Raid_t *raidPtr;
2713 2730
2714 s = splbio(); 2731 s = splbio();
2715 raidPtr = (RF_Raid_t *) req->raidPtr; 2732 raidPtr = (RF_Raid_t *) req->raidPtr;
2716 raidPtr->recon_in_progress = 1; 2733 raidPtr->recon_in_progress = 1;
2717 2734
2718 rf_FailDisk((RF_Raid_t *) req->raidPtr, req->col, 2735 rf_FailDisk((RF_Raid_t *) req->raidPtr, req->col,
2719 ((req->flags & RF_FDFLAGS_RECON) ? 1 : 0)); 2736 ((req->flags & RF_FDFLAGS_RECON) ? 1 : 0));
2720 2737
2721 RF_Free(req, sizeof(*req)); 2738 RF_Free(req, sizeof(*req));
2722 2739
2723 raidPtr->recon_in_progress = 0; 2740 raidPtr->recon_in_progress = 0;
2724 splx(s); 2741 splx(s);
2725 2742
2726 /* That's all... */ 2743 /* That's all... */
2727 kthread_exit(0); /* does not return */ 2744 kthread_exit(0); /* does not return */
2728} 2745}
2729 2746
2730void 2747void
2731rf_RewriteParityThread(RF_Raid_t *raidPtr) 2748rf_RewriteParityThread(RF_Raid_t *raidPtr)
2732{ 2749{
2733 int retcode; 2750 int retcode;
2734 int s; 2751 int s;
2735 2752
2736 raidPtr->parity_rewrite_stripes_done = 0; 2753 raidPtr->parity_rewrite_stripes_done = 0;
2737 raidPtr->parity_rewrite_in_progress = 1; 2754 raidPtr->parity_rewrite_in_progress = 1;
2738 s = splbio(); 2755 s = splbio();
2739 retcode = rf_RewriteParity(raidPtr); 2756 retcode = rf_RewriteParity(raidPtr);
2740 splx(s); 2757 splx(s);
2741 if (retcode) { 2758 if (retcode) {
2742 printf("raid%d: Error re-writing parity!\n",raidPtr->raidid); 2759 printf("raid%d: Error re-writing parity!\n",raidPtr->raidid);
2743 } else { 2760 } else {
2744 /* set the clean bit! If we shutdown correctly, 2761 /* set the clean bit! If we shutdown correctly,
2745 the clean bit on each component label will get 2762 the clean bit on each component label will get
2746 set */ 2763 set */
2747 raidPtr->parity_good = RF_RAID_CLEAN; 2764 raidPtr->parity_good = RF_RAID_CLEAN;
2748 } 2765 }
2749 raidPtr->parity_rewrite_in_progress = 0; 2766 raidPtr->parity_rewrite_in_progress = 0;
2750 2767
2751 /* Anyone waiting for us to stop? If so, inform them... */ 2768 /* Anyone waiting for us to stop? If so, inform them... */
2752 if (raidPtr->waitShutdown) { 2769 if (raidPtr->waitShutdown) {
2753 wakeup(&raidPtr->parity_rewrite_in_progress); 2770 wakeup(&raidPtr->parity_rewrite_in_progress);
2754 } 2771 }
2755 2772
2756 /* That's all... */ 2773 /* That's all... */
2757 kthread_exit(0); /* does not return */ 2774 kthread_exit(0); /* does not return */
2758} 2775}
2759 2776
2760 2777
2761void 2778void
2762rf_CopybackThread(RF_Raid_t *raidPtr) 2779rf_CopybackThread(RF_Raid_t *raidPtr)
2763{ 2780{
2764 int s; 2781 int s;
2765 2782
2766 raidPtr->copyback_in_progress = 1; 2783 raidPtr->copyback_in_progress = 1;
2767 s = splbio(); 2784 s = splbio();
2768 rf_CopybackReconstructedData(raidPtr); 2785 rf_CopybackReconstructedData(raidPtr);
2769 splx(s); 2786 splx(s);
2770 raidPtr->copyback_in_progress = 0; 2787 raidPtr->copyback_in_progress = 0;
2771 2788
2772 /* That's all... */ 2789 /* That's all... */
2773 kthread_exit(0); /* does not return */ 2790 kthread_exit(0); /* does not return */
2774} 2791}
2775 2792
2776 2793
2777void 2794void
2778rf_ReconstructInPlaceThread(struct rf_recon_req *req) 2795rf_ReconstructInPlaceThread(struct rf_recon_req *req)
2779{ 2796{
2780 int s; 2797 int s;
2781 RF_Raid_t *raidPtr; 2798 RF_Raid_t *raidPtr;
2782 2799
2783 s = splbio(); 2800 s = splbio();
2784 raidPtr = req->raidPtr; 2801 raidPtr = req->raidPtr;
2785 raidPtr->recon_in_progress = 1; 2802 raidPtr->recon_in_progress = 1;
2786 rf_ReconstructInPlace(raidPtr, req->col); 2803 rf_ReconstructInPlace(raidPtr, req->col);
2787 RF_Free(req, sizeof(*req)); 2804 RF_Free(req, sizeof(*req));
2788 raidPtr->recon_in_progress = 0; 2805 raidPtr->recon_in_progress = 0;
2789 splx(s); 2806 splx(s);
2790 2807
2791 /* That's all... */ 2808 /* That's all... */
2792 kthread_exit(0); /* does not return */ 2809 kthread_exit(0); /* does not return */
2793} 2810}
2794 2811
2795static RF_AutoConfig_t * 2812static RF_AutoConfig_t *
2796rf_get_component(RF_AutoConfig_t *ac_list, dev_t dev, struct vnode *vp, 2813rf_get_component(RF_AutoConfig_t *ac_list, dev_t dev, struct vnode *vp,
2797 const char *cname, RF_SectorCount_t size) 2814 const char *cname, RF_SectorCount_t size)
2798{ 2815{
2799 int good_one = 0; 2816 int good_one = 0;
2800 RF_ComponentLabel_t *clabel;  2817 RF_ComponentLabel_t *clabel;
2801 RF_AutoConfig_t *ac; 2818 RF_AutoConfig_t *ac;
2802 2819
2803 clabel = malloc(sizeof(RF_ComponentLabel_t), M_RAIDFRAME, M_NOWAIT); 2820 clabel = malloc(sizeof(RF_ComponentLabel_t), M_RAIDFRAME, M_NOWAIT);
2804 if (clabel == NULL) { 2821 if (clabel == NULL) {
2805oomem: 2822oomem:
2806 while(ac_list) { 2823 while(ac_list) {
2807 ac = ac_list; 2824 ac = ac_list;
2808 if (ac->clabel) 2825 if (ac->clabel)
2809 free(ac->clabel, M_RAIDFRAME); 2826 free(ac->clabel, M_RAIDFRAME);
2810 ac_list = ac_list->next; 2827 ac_list = ac_list->next;
2811 free(ac, M_RAIDFRAME); 2828 free(ac, M_RAIDFRAME);
2812 } 2829 }
2813 printf("RAID auto config: out of memory!\n"); 2830 printf("RAID auto config: out of memory!\n");
2814 return NULL; /* XXX probably should panic? */ 2831 return NULL; /* XXX probably should panic? */
2815 } 2832 }
2816 2833
2817 if (!raidread_component_label(dev, vp, clabel)) { 2834 if (!raidread_component_label(dev, vp, clabel)) {
2818 /* Got the label. Does it look reasonable? */ 2835 /* Got the label. Does it look reasonable? */
2819 if (rf_reasonable_label(clabel) &&  2836 if (rf_reasonable_label(clabel) &&
2820 (clabel->partitionSize <= size)) { 2837 (clabel->partitionSize <= size)) {
2821#ifdef DEBUG 2838#ifdef DEBUG
2822 printf("Component on: %s: %llu\n", 2839 printf("Component on: %s: %llu\n",
2823 cname, (unsigned long long)size); 2840 cname, (unsigned long long)size);
2824 rf_print_component_label(clabel); 2841 rf_print_component_label(clabel);
2825#endif 2842#endif
2826 /* if it's reasonable, add it, else ignore it. */ 2843 /* if it's reasonable, add it, else ignore it. */
2827 ac = malloc(sizeof(RF_AutoConfig_t), M_RAIDFRAME, 2844 ac = malloc(sizeof(RF_AutoConfig_t), M_RAIDFRAME,
2828 M_NOWAIT); 2845 M_NOWAIT);
2829 if (ac == NULL) { 2846 if (ac == NULL) {
2830 free(clabel, M_RAIDFRAME); 2847 free(clabel, M_RAIDFRAME);
2831 goto oomem; 2848 goto oomem;
2832 } 2849 }
2833 strlcpy(ac->devname, cname, sizeof(ac->devname)); 2850 strlcpy(ac->devname, cname, sizeof(ac->devname));
2834 ac->dev = dev; 2851 ac->dev = dev;
2835 ac->vp = vp; 2852 ac->vp = vp;
2836 ac->clabel = clabel; 2853 ac->clabel = clabel;
2837 ac->next = ac_list; 2854 ac->next = ac_list;
2838 ac_list = ac; 2855 ac_list = ac;
2839 good_one = 1; 2856 good_one = 1;
2840 } 2857 }
2841 } 2858 }
2842 if (!good_one) { 2859 if (!good_one) {
2843 /* cleanup */ 2860 /* cleanup */
2844 free(clabel, M_RAIDFRAME); 2861 free(clabel, M_RAIDFRAME);
2845 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 2862 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
2846 VOP_CLOSE(vp, FREAD | FWRITE, NOCRED); 2863 VOP_CLOSE(vp, FREAD | FWRITE, NOCRED);
2847 vput(vp); 2864 vput(vp);
2848 } 2865 }
2849 return ac_list; 2866 return ac_list;
2850} 2867}
2851 2868
2852RF_AutoConfig_t * 2869RF_AutoConfig_t *
2853rf_find_raid_components(void) 2870rf_find_raid_components(void)
2854{ 2871{
2855 struct vnode *vp; 2872 struct vnode *vp;
2856 struct disklabel label; 2873 struct disklabel label;
2857 device_t dv; 2874 device_t dv;
2858 dev_t dev; 2875 dev_t dev;
2859 int bmajor, bminor, wedge; 2876 int bmajor, bminor, wedge;
2860 int error; 2877 int error;
2861 int i; 2878 int i;
2862 RF_AutoConfig_t *ac_list; 2879 RF_AutoConfig_t *ac_list;
2863 2880
2864 2881
2865 /* initialize the AutoConfig list */ 2882 /* initialize the AutoConfig list */
2866 ac_list = NULL; 2883 ac_list = NULL;
2867 2884
2868 /* we begin by trolling through *all* the devices on the system */ 2885 /* we begin by trolling through *all* the devices on the system */
2869 2886
2870 for (dv = alldevs.tqh_first; dv != NULL; 2887 for (dv = alldevs.tqh_first; dv != NULL;
2871 dv = dv->dv_list.tqe_next) { 2888 dv = dv->dv_list.tqe_next) {
2872 2889
2873 /* we are only interested in disks... */ 2890 /* we are only interested in disks... */
2874 if (device_class(dv) != DV_DISK) 2891 if (device_class(dv) != DV_DISK)
2875 continue; 2892 continue;
2876 2893
2877 /* we don't care about floppies... */ 2894 /* we don't care about floppies... */
2878 if (device_is_a(dv, "fd")) { 2895 if (device_is_a(dv, "fd")) {
2879 continue; 2896 continue;
2880 } 2897 }
2881 2898
2882 /* we don't care about CD's... */ 2899 /* we don't care about CD's... */
2883 if (device_is_a(dv, "cd")) { 2900 if (device_is_a(dv, "cd")) {
2884 continue; 2901 continue;
2885 } 2902 }
2886 2903
2887 /* we don't care about md's... */ 2904 /* we don't care about md's... */
2888 if (device_is_a(dv, "md")) { 2905 if (device_is_a(dv, "md")) {
2889 continue; 2906 continue;
2890 } 2907 }
2891 2908
2892 /* hdfd is the Atari/Hades floppy driver */ 2909 /* hdfd is the Atari/Hades floppy driver */
2893 if (device_is_a(dv, "hdfd")) { 2910 if (device_is_a(dv, "hdfd")) {
2894 continue; 2911 continue;
2895 } 2912 }
2896 2913
2897 /* fdisa is the Atari/Milan floppy driver */ 2914 /* fdisa is the Atari/Milan floppy driver */
2898 if (device_is_a(dv, "fdisa")) { 2915 if (device_is_a(dv, "fdisa")) {
2899 continue; 2916 continue;
2900 } 2917 }
2901 2918
2902 /* need to find the device_name_to_block_device_major stuff */ 2919 /* need to find the device_name_to_block_device_major stuff */
2903 bmajor = devsw_name2blk(device_xname(dv), NULL, 0); 2920 bmajor = devsw_name2blk(device_xname(dv), NULL, 0);
2904 2921
2905 /* get a vnode for the raw partition of this disk */ 2922 /* get a vnode for the raw partition of this disk */
2906 2923
2907 wedge = device_is_a(dv, "dk"); 2924 wedge = device_is_a(dv, "dk");
2908 bminor = minor(device_unit(dv)); 2925 bminor = minor(device_unit(dv));
2909 dev = wedge ? makedev(bmajor, bminor) : 2926 dev = wedge ? makedev(bmajor, bminor) :
2910 MAKEDISKDEV(bmajor, bminor, RAW_PART); 2927 MAKEDISKDEV(bmajor, bminor, RAW_PART);
2911 if (bdevvp(dev, &vp)) 2928 if (bdevvp(dev, &vp))
2912 panic("RAID can't alloc vnode"); 2929 panic("RAID can't alloc vnode");
2913 2930
2914 error = VOP_OPEN(vp, FREAD, NOCRED); 2931 error = VOP_OPEN(vp, FREAD, NOCRED);
2915 2932
2916 if (error) { 2933 if (error) {
2917 /* "Who cares." Continue looking 2934 /* "Who cares." Continue looking
2918 for something that exists*/ 2935 for something that exists*/
2919 vput(vp); 2936 vput(vp);
2920 continue; 2937 continue;
2921 } 2938 }
2922 2939
2923 if (wedge) { 2940 if (wedge) {
2924 struct dkwedge_info dkw; 2941 struct dkwedge_info dkw;
2925 error = VOP_IOCTL(vp, DIOCGWEDGEINFO, &dkw, FREAD, 2942 error = VOP_IOCTL(vp, DIOCGWEDGEINFO, &dkw, FREAD,
2926 NOCRED); 2943 NOCRED);
2927 if (error) { 2944 if (error) {
2928 printf("RAIDframe: can't get wedge info for " 2945 printf("RAIDframe: can't get wedge info for "
2929 "dev %s (%d)\n", device_xname(dv), error); 2946 "dev %s (%d)\n", device_xname(dv), error);
2930 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 2947 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
2931 VOP_CLOSE(vp, FREAD | FWRITE, NOCRED); 2948 VOP_CLOSE(vp, FREAD | FWRITE, NOCRED);
2932 vput(vp); 2949 vput(vp);
2933 continue; 2950 continue;
2934 } 2951 }
2935 2952
2936 if (strcmp(dkw.dkw_ptype, DKW_PTYPE_RAIDFRAME) != 0) { 2953 if (strcmp(dkw.dkw_ptype, DKW_PTYPE_RAIDFRAME) != 0) {
2937 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 2954 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
2938 VOP_CLOSE(vp, FREAD | FWRITE, NOCRED); 2955 VOP_CLOSE(vp, FREAD | FWRITE, NOCRED);
2939 vput(vp); 2956 vput(vp);
2940 continue; 2957 continue;
2941 } 2958 }
2942  2959
2943 ac_list = rf_get_component(ac_list, dev, vp, 2960 ac_list = rf_get_component(ac_list, dev, vp,
2944 device_xname(dv), dkw.dkw_size); 2961 device_xname(dv), dkw.dkw_size);
2945 continue; 2962 continue;
2946 } 2963 }
2947 2964
2948 /* Ok, the disk exists. Go get the disklabel. */ 2965 /* Ok, the disk exists. Go get the disklabel. */
2949 error = VOP_IOCTL(vp, DIOCGDINFO, &label, FREAD, NOCRED); 2966 error = VOP_IOCTL(vp, DIOCGDINFO, &label, FREAD, NOCRED);
2950 if (error) { 2967 if (error) {
2951 /* 2968 /*
2952 * XXX can't happen - open() would 2969 * XXX can't happen - open() would
2953 * have errored out (or faked up one) 2970 * have errored out (or faked up one)
2954 */ 2971 */
2955 if (error != ENOTTY) 2972 if (error != ENOTTY)
2956 printf("RAIDframe: can't get label for dev " 2973 printf("RAIDframe: can't get label for dev "
2957 "%s (%d)\n", device_xname(dv), error); 2974 "%s (%d)\n", device_xname(dv), error);
2958 } 2975 }
2959 2976
2960 /* don't need this any more. We'll allocate it again 2977 /* don't need this any more. We'll allocate it again
2961 a little later if we really do... */ 2978 a little later if we really do... */
2962 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 2979 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
2963 VOP_CLOSE(vp, FREAD | FWRITE, NOCRED); 2980 VOP_CLOSE(vp, FREAD | FWRITE, NOCRED);
2964 vput(vp); 2981 vput(vp);
2965 2982
2966 if (error) 2983 if (error)
2967 continue; 2984 continue;
2968 2985
2969 for (i = 0; i < label.d_npartitions; i++) { 2986 for (i = 0; i < label.d_npartitions; i++) {
2970 char cname[sizeof(ac_list->devname)]; 2987 char cname[sizeof(ac_list->devname)];
2971 2988
2972 /* We only support partitions marked as RAID */ 2989 /* We only support partitions marked as RAID */
2973 if (label.d_partitions[i].p_fstype != FS_RAID) 2990 if (label.d_partitions[i].p_fstype != FS_RAID)
2974 continue; 2991 continue;
2975 2992
2976 dev = MAKEDISKDEV(bmajor, device_unit(dv), i); 2993 dev = MAKEDISKDEV(bmajor, device_unit(dv), i);
2977 if (bdevvp(dev, &vp)) 2994 if (bdevvp(dev, &vp))
2978 panic("RAID can't alloc vnode"); 2995 panic("RAID can't alloc vnode");
2979 2996
2980 error = VOP_OPEN(vp, FREAD, NOCRED); 2997 error = VOP_OPEN(vp, FREAD, NOCRED);
2981 if (error) { 2998 if (error) {
2982 /* Whatever... */ 2999 /* Whatever... */
2983 vput(vp); 3000 vput(vp);
2984 continue; 3001 continue;
2985 } 3002 }
2986 snprintf(cname, sizeof(cname), "%s%c", 3003 snprintf(cname, sizeof(cname), "%s%c",
2987 device_xname(dv), 'a' + i); 3004 device_xname(dv), 'a' + i);
2988 ac_list = rf_get_component(ac_list, dev, vp, cname, 3005 ac_list = rf_get_component(ac_list, dev, vp, cname,
2989 label.d_partitions[i].p_size); 3006 label.d_partitions[i].p_size);
2990 } 3007 }
2991 } 3008 }
2992 return ac_list; 3009 return ac_list;
2993} 3010}
2994 3011
2995 3012
2996static int 3013static int
2997rf_reasonable_label(RF_ComponentLabel_t *clabel) 3014rf_reasonable_label(RF_ComponentLabel_t *clabel)
2998{ 3015{
2999 3016
3000 if (((clabel->version==RF_COMPONENT_LABEL_VERSION_1) || 3017 if (((clabel->version==RF_COMPONENT_LABEL_VERSION_1) ||
3001 (clabel->version==RF_COMPONENT_LABEL_VERSION)) && 3018 (clabel->version==RF_COMPONENT_LABEL_VERSION)) &&
3002 ((clabel->clean == RF_RAID_CLEAN) || 3019 ((clabel->clean == RF_RAID_CLEAN) ||
3003 (clabel->clean == RF_RAID_DIRTY)) && 3020 (clabel->clean == RF_RAID_DIRTY)) &&
3004 clabel->row >=0 && 3021 clabel->row >=0 &&
3005 clabel->column >= 0 && 3022 clabel->column >= 0 &&
3006 clabel->num_rows > 0 && 3023 clabel->num_rows > 0 &&
3007 clabel->num_columns > 0 && 3024 clabel->num_columns > 0 &&
3008 clabel->row < clabel->num_rows && 3025 clabel->row < clabel->num_rows &&
3009 clabel->column < clabel->num_columns && 3026 clabel->column < clabel->num_columns &&
3010 clabel->blockSize > 0 && 3027 clabel->blockSize > 0 &&
3011 clabel->numBlocks > 0) { 3028 clabel->numBlocks > 0) {
3012 /* label looks reasonable enough... */ 3029 /* label looks reasonable enough... */
3013 return(1); 3030 return(1);
3014 } 3031 }
3015 return(0); 3032 return(0);
3016} 3033}
3017 3034
3018 3035
3019#ifdef DEBUG 3036#ifdef DEBUG
3020void 3037void
3021rf_print_component_label(RF_ComponentLabel_t *clabel) 3038rf_print_component_label(RF_ComponentLabel_t *clabel)
3022{ 3039{
3023 printf(" Row: %d Column: %d Num Rows: %d Num Columns: %d\n", 3040 printf(" Row: %d Column: %d Num Rows: %d Num Columns: %d\n",
3024 clabel->row, clabel->column, 3041 clabel->row, clabel->column,
3025 clabel->num_rows, clabel->num_columns); 3042 clabel->num_rows, clabel->num_columns);
3026 printf(" Version: %d Serial Number: %d Mod Counter: %d\n", 3043 printf(" Version: %d Serial Number: %d Mod Counter: %d\n",
3027 clabel->version, clabel->serial_number, 3044 clabel->version, clabel->serial_number,
3028 clabel->mod_counter); 3045 clabel->mod_counter);
3029 printf(" Clean: %s Status: %d\n", 3046 printf(" Clean: %s Status: %d\n",
3030 clabel->clean ? "Yes" : "No", clabel->status ); 3047 clabel->clean ? "Yes" : "No", clabel->status );
3031 printf(" sectPerSU: %d SUsPerPU: %d SUsPerRU: %d\n", 3048 printf(" sectPerSU: %d SUsPerPU: %d SUsPerRU: %d\n",
3032 clabel->sectPerSU, clabel->SUsPerPU, clabel->SUsPerRU); 3049 clabel->sectPerSU, clabel->SUsPerPU, clabel->SUsPerRU);
3033 printf(" RAID Level: %c blocksize: %d numBlocks: %d\n", 3050 printf(" RAID Level: %c blocksize: %d numBlocks: %d\n",
3034 (char) clabel->parityConfig, clabel->blockSize, 3051 (char) clabel->parityConfig, clabel->blockSize,
3035 clabel->numBlocks); 3052 clabel->numBlocks);
3036 printf(" Autoconfig: %s\n", clabel->autoconfigure ? "Yes" : "No" ); 3053 printf(" Autoconfig: %s\n", clabel->autoconfigure ? "Yes" : "No" );
3037 printf(" Contains root partition: %s\n", 3054 printf(" Contains root partition: %s\n",
3038 clabel->root_partition ? "Yes" : "No" ); 3055 clabel->root_partition ? "Yes" : "No" );
3039 printf(" Last configured as: raid%d\n", clabel->last_unit ); 3056 printf(" Last configured as: raid%d\n", clabel->last_unit );
3040#if 0 3057#if 0
3041 printf(" Config order: %d\n", clabel->config_order); 3058 printf(" Config order: %d\n", clabel->config_order);
3042#endif 3059#endif
3043 3060
3044} 3061}
3045#endif 3062#endif
3046 3063
3047RF_ConfigSet_t * 3064RF_ConfigSet_t *
3048rf_create_auto_sets(RF_AutoConfig_t *ac_list) 3065rf_create_auto_sets(RF_AutoConfig_t *ac_list)
3049{ 3066{
3050 RF_AutoConfig_t *ac; 3067 RF_AutoConfig_t *ac;
3051 RF_ConfigSet_t *config_sets; 3068 RF_ConfigSet_t *config_sets;
3052 RF_ConfigSet_t *cset; 3069 RF_ConfigSet_t *cset;
3053 RF_AutoConfig_t *ac_next; 3070 RF_AutoConfig_t *ac_next;
3054 3071
3055 3072
3056 config_sets = NULL; 3073 config_sets = NULL;
3057 3074
3058 /* Go through the AutoConfig list, and figure out which components 3075 /* Go through the AutoConfig list, and figure out which components
3059 belong to what sets. */ 3076 belong to what sets. */
3060 ac = ac_list; 3077 ac = ac_list;
3061 while(ac!=NULL) { 3078 while(ac!=NULL) {
3062 /* we're going to putz with ac->next, so save it here 3079 /* we're going to putz with ac->next, so save it here
3063 for use at the end of the loop */ 3080 for use at the end of the loop */
3064 ac_next = ac->next; 3081 ac_next = ac->next;
3065 3082
3066 if (config_sets == NULL) { 3083 if (config_sets == NULL) {
3067 /* will need at least this one... */ 3084 /* will need at least this one... */
3068 config_sets = (RF_ConfigSet_t *) 3085 config_sets = (RF_ConfigSet_t *)
3069 malloc(sizeof(RF_ConfigSet_t), 3086 malloc(sizeof(RF_ConfigSet_t),
3070 M_RAIDFRAME, M_NOWAIT); 3087 M_RAIDFRAME, M_NOWAIT);
3071 if (config_sets == NULL) { 3088 if (config_sets == NULL) {
3072 panic("rf_create_auto_sets: No memory!"); 3089 panic("rf_create_auto_sets: No memory!");
3073 } 3090 }
3074 /* this one is easy :) */ 3091 /* this one is easy :) */
3075 config_sets->ac = ac; 3092 config_sets->ac = ac;
3076 config_sets->next = NULL; 3093 config_sets->next = NULL;
3077 config_sets->rootable = 0; 3094 config_sets->rootable = 0;
3078 ac->next = NULL; 3095 ac->next = NULL;
3079 } else { 3096 } else {
3080 /* which set does this component fit into? */ 3097 /* which set does this component fit into? */
3081 cset = config_sets; 3098 cset = config_sets;
3082 while(cset!=NULL) { 3099 while(cset!=NULL) {
3083 if (rf_does_it_fit(cset, ac)) { 3100 if (rf_does_it_fit(cset, ac)) {
3084 /* looks like it matches... */ 3101 /* looks like it matches... */
3085 ac->next = cset->ac; 3102 ac->next = cset->ac;
3086 cset->ac = ac; 3103 cset->ac = ac;
3087 break; 3104 break;
3088 } 3105 }
3089 cset = cset->next; 3106 cset = cset->next;
3090 } 3107 }
3091 if (cset==NULL) { 3108 if (cset==NULL) {
3092 /* didn't find a match above... new set..*/ 3109 /* didn't find a match above... new set..*/
3093 cset = (RF_ConfigSet_t *) 3110 cset = (RF_ConfigSet_t *)
3094 malloc(sizeof(RF_ConfigSet_t), 3111 malloc(sizeof(RF_ConfigSet_t),
3095 M_RAIDFRAME, M_NOWAIT); 3112 M_RAIDFRAME, M_NOWAIT);
3096 if (cset == NULL) { 3113 if (cset == NULL) {
3097 panic("rf_create_auto_sets: No memory!"); 3114 panic("rf_create_auto_sets: No memory!");
3098 } 3115 }
3099 cset->ac = ac; 3116 cset->ac = ac;
3100 ac->next = NULL; 3117 ac->next = NULL;
3101 cset->next = config_sets; 3118 cset->next = config_sets;
3102 cset->rootable = 0; 3119 cset->rootable = 0;
3103 config_sets = cset; 3120 config_sets = cset;
3104 } 3121 }
3105 } 3122 }
3106 ac = ac_next; 3123 ac = ac_next;
3107 } 3124 }
3108 3125
3109 3126
3110 return(config_sets); 3127 return(config_sets);
3111} 3128}
3112 3129
3113static int 3130static int
3114rf_does_it_fit(RF_ConfigSet_t *cset, RF_AutoConfig_t *ac) 3131rf_does_it_fit(RF_ConfigSet_t *cset, RF_AutoConfig_t *ac)
3115{ 3132{
3116 RF_ComponentLabel_t *clabel1, *clabel2; 3133 RF_ComponentLabel_t *clabel1, *clabel2;
3117 3134
3118 /* If this one matches the *first* one in the set, that's good 3135 /* If this one matches the *first* one in the set, that's good
3119 enough, since the other members of the set would have been 3136 enough, since the other members of the set would have been
3120 through here too... */ 3137 through here too... */
3121 /* note that we are not checking partitionSize here.. 3138 /* note that we are not checking partitionSize here..
3122 3139
3123 Note that we are also not checking the mod_counters here. 3140 Note that we are also not checking the mod_counters here.
3124 If everything else matches execpt the mod_counter, that's 3141 If everything else matches execpt the mod_counter, that's
3125 good enough for this test. We will deal with the mod_counters 3142 good enough for this test. We will deal with the mod_counters
3126 a little later in the autoconfiguration process. 3143 a little later in the autoconfiguration process.
3127 3144
3128 (clabel1->mod_counter == clabel2->mod_counter) && 3145 (clabel1->mod_counter == clabel2->mod_counter) &&
3129 3146
3130 The reason we don't check for this is that failed disks 3147 The reason we don't check for this is that failed disks
3131 will have lower modification counts. If those disks are 3148 will have lower modification counts. If those disks are
3132 not added to the set they used to belong to, then they will 3149 not added to the set they used to belong to, then they will
3133 form their own set, which may result in 2 different sets, 3150 form their own set, which may result in 2 different sets,
3134 for example, competing to be configured at raid0, and 3151 for example, competing to be configured at raid0, and
3135 perhaps competing to be the root filesystem set. If the 3152 perhaps competing to be the root filesystem set. If the
3136 wrong ones get configured, or both attempt to become /, 3153 wrong ones get configured, or both attempt to become /,
3137 weird behaviour and or serious lossage will occur. Thus we 3154 weird behaviour and or serious lossage will occur. Thus we
3138 need to bring them into the fold here, and kick them out at 3155 need to bring them into the fold here, and kick them out at
3139 a later point. 3156 a later point.
3140 3157
3141 */ 3158 */
3142 3159
3143 clabel1 = cset->ac->clabel; 3160 clabel1 = cset->ac->clabel;
3144 clabel2 = ac->clabel; 3161 clabel2 = ac->clabel;
3145 if ((clabel1->version == clabel2->version) && 3162 if ((clabel1->version == clabel2->version) &&
3146 (clabel1->serial_number == clabel2->serial_number) && 3163 (clabel1->serial_number == clabel2->serial_number) &&
3147 (clabel1->num_rows == clabel2->num_rows) && 3164 (clabel1->num_rows == clabel2->num_rows) &&
3148 (clabel1->num_columns == clabel2->num_columns) && 3165 (clabel1->num_columns == clabel2->num_columns) &&
3149 (clabel1->sectPerSU == clabel2->sectPerSU) && 3166 (clabel1->sectPerSU == clabel2->sectPerSU) &&
3150 (clabel1->SUsPerPU == clabel2->SUsPerPU) && 3167 (clabel1->SUsPerPU == clabel2->SUsPerPU) &&
3151 (clabel1->SUsPerRU == clabel2->SUsPerRU) && 3168 (clabel1->SUsPerRU == clabel2->SUsPerRU) &&
3152 (clabel1->parityConfig == clabel2->parityConfig) && 3169 (clabel1->parityConfig == clabel2->parityConfig) &&
3153 (clabel1->maxOutstanding == clabel2->maxOutstanding) && 3170 (clabel1->maxOutstanding == clabel2->maxOutstanding) &&
3154 (clabel1->blockSize == clabel2->blockSize) && 3171 (clabel1->blockSize == clabel2->blockSize) &&
3155 (clabel1->numBlocks == clabel2->numBlocks) && 3172 (clabel1->numBlocks == clabel2->numBlocks) &&
3156 (clabel1->autoconfigure == clabel2->autoconfigure) && 3173 (clabel1->autoconfigure == clabel2->autoconfigure) &&
3157 (clabel1->root_partition == clabel2->root_partition) && 3174 (clabel1->root_partition == clabel2->root_partition) &&
3158 (clabel1->last_unit == clabel2->last_unit) && 3175 (clabel1->last_unit == clabel2->last_unit) &&
3159 (clabel1->config_order == clabel2->config_order)) { 3176 (clabel1->config_order == clabel2->config_order)) {
3160 /* if it get's here, it almost *has* to be a match */ 3177 /* if it get's here, it almost *has* to be a match */
3161 } else { 3178 } else {
3162 /* it's not consistent with somebody in the set.. 3179 /* it's not consistent with somebody in the set..
3163 punt */ 3180 punt */
3164 return(0); 3181 return(0);
3165 } 3182 }
3166 /* all was fine.. it must fit... */ 3183 /* all was fine.. it must fit... */
3167 return(1); 3184 return(1);
3168} 3185}
3169 3186
3170int 3187int
3171rf_have_enough_components(RF_ConfigSet_t *cset) 3188rf_have_enough_components(RF_ConfigSet_t *cset)
3172{ 3189{
3173 RF_AutoConfig_t *ac; 3190 RF_AutoConfig_t *ac;
3174 RF_AutoConfig_t *auto_config; 3191 RF_AutoConfig_t *auto_config;
3175 RF_ComponentLabel_t *clabel; 3192 RF_ComponentLabel_t *clabel;
3176 int c; 3193 int c;
3177 int num_cols; 3194 int num_cols;
3178 int num_missing; 3195 int num_missing;
3179 int mod_counter; 3196 int mod_counter;
3180 int mod_counter_found; 3197 int mod_counter_found;
3181 int even_pair_failed; 3198 int even_pair_failed;
3182 char parity_type; 3199 char parity_type;
3183 3200
3184 3201
3185 /* check to see that we have enough 'live' components 3202 /* check to see that we have enough 'live' components
3186 of this set. If so, we can configure it if necessary */ 3203 of this set. If so, we can configure it if necessary */
3187 3204
3188 num_cols = cset->ac->clabel->num_columns; 3205 num_cols = cset->ac->clabel->num_columns;
3189 parity_type = cset->ac->clabel->parityConfig; 3206 parity_type = cset->ac->clabel->parityConfig;
3190 3207
3191 /* XXX Check for duplicate components!?!?!? */ 3208 /* XXX Check for duplicate components!?!?!? */
3192 3209
3193 /* Determine what the mod_counter is supposed to be for this set. */ 3210 /* Determine what the mod_counter is supposed to be for this set. */
3194 3211
3195 mod_counter_found = 0; 3212 mod_counter_found = 0;
3196 mod_counter = 0; 3213 mod_counter = 0;
3197 ac = cset->ac; 3214 ac = cset->ac;
3198 while(ac!=NULL) { 3215 while(ac!=NULL) {
3199 if (mod_counter_found==0) { 3216 if (mod_counter_found==0) {
3200 mod_counter = ac->clabel->mod_counter; 3217 mod_counter = ac->clabel->mod_counter;
3201 mod_counter_found = 1; 3218 mod_counter_found = 1;
3202 } else { 3219 } else {
3203 if (ac->clabel->mod_counter > mod_counter) { 3220 if (ac->clabel->mod_counter > mod_counter) {
3204 mod_counter = ac->clabel->mod_counter; 3221 mod_counter = ac->clabel->mod_counter;
3205 } 3222 }
3206 } 3223 }
3207 ac = ac->next; 3224 ac = ac->next;
3208 } 3225 }
3209 3226
3210 num_missing = 0; 3227 num_missing = 0;
3211 auto_config = cset->ac; 3228 auto_config = cset->ac;
3212 3229
3213 even_pair_failed = 0; 3230 even_pair_failed = 0;
3214 for(c=0; c<num_cols; c++) { 3231 for(c=0; c<num_cols; c++) {
3215 ac = auto_config; 3232 ac = auto_config;
3216 while(ac!=NULL) { 3233 while(ac!=NULL) {
3217 if ((ac->clabel->column == c) && 3234 if ((ac->clabel->column == c) &&
3218 (ac->clabel->mod_counter == mod_counter)) { 3235 (ac->clabel->mod_counter == mod_counter)) {
3219 /* it's this one... */ 3236 /* it's this one... */
3220#ifdef DEBUG 3237#ifdef DEBUG
3221 printf("Found: %s at %d\n", 3238 printf("Found: %s at %d\n",
3222 ac->devname,c); 3239 ac->devname,c);
3223#endif 3240#endif
3224 break; 3241 break;
3225 } 3242 }
3226 ac=ac->next; 3243 ac=ac->next;
3227 } 3244 }
3228 if (ac==NULL) { 3245 if (ac==NULL) {
3229 /* Didn't find one here! */ 3246 /* Didn't find one here! */
3230 /* special case for RAID 1, especially 3247 /* special case for RAID 1, especially
3231 where there are more than 2 3248 where there are more than 2
3232 components (where RAIDframe treats 3249 components (where RAIDframe treats
3233 things a little differently :( ) */ 3250 things a little differently :( ) */
3234 if (parity_type == '1') { 3251 if (parity_type == '1') {
3235 if (c%2 == 0) { /* even component */ 3252 if (c%2 == 0) { /* even component */
3236 even_pair_failed = 1; 3253 even_pair_failed = 1;
3237 } else { /* odd component. If 3254 } else { /* odd component. If
3238 we're failed, and 3255 we're failed, and
3239 so is the even 3256 so is the even
3240 component, it's 3257 component, it's
3241 "Good Night, Charlie" */ 3258 "Good Night, Charlie" */
3242 if (even_pair_failed == 1) { 3259 if (even_pair_failed == 1) {
3243 return(0); 3260 return(0);
3244 } 3261 }
3245 } 3262 }
3246 } else { 3263 } else {
3247 /* normal accounting */ 3264 /* normal accounting */
3248 num_missing++; 3265 num_missing++;
3249 } 3266 }
3250 } 3267 }
3251 if ((parity_type == '1') && (c%2 == 1)) { 3268 if ((parity_type == '1') && (c%2 == 1)) {
3252 /* Just did an even component, and we didn't 3269 /* Just did an even component, and we didn't
3253 bail.. reset the even_pair_failed flag, 3270 bail.. reset the even_pair_failed flag,
3254 and go on to the next component.... */ 3271 and go on to the next component.... */
3255 even_pair_failed = 0; 3272 even_pair_failed = 0;
3256 } 3273 }
3257 } 3274 }
3258 3275
3259 clabel = cset->ac->clabel; 3276 clabel = cset->ac->clabel;
3260 3277
3261 if (((clabel->parityConfig == '0') && (num_missing > 0)) || 3278 if (((clabel->parityConfig == '0') && (num_missing > 0)) ||
3262 ((clabel->parityConfig == '4') && (num_missing > 1)) || 3279 ((clabel->parityConfig == '4') && (num_missing > 1)) ||
3263 ((clabel->parityConfig == '5') && (num_missing > 1))) { 3280 ((clabel->parityConfig == '5') && (num_missing > 1))) {
3264 /* XXX this needs to be made *much* more general */ 3281 /* XXX this needs to be made *much* more general */
3265 /* Too many failures */ 3282 /* Too many failures */
3266 return(0); 3283 return(0);
3267 } 3284 }
3268 /* otherwise, all is well, and we've got enough to take a kick 3285 /* otherwise, all is well, and we've got enough to take a kick
3269 at autoconfiguring this set */ 3286 at autoconfiguring this set */
3270 return(1); 3287 return(1);
3271} 3288}
3272 3289
3273void 3290void
3274rf_create_configuration(RF_AutoConfig_t *ac, RF_Config_t *config, 3291rf_create_configuration(RF_AutoConfig_t *ac, RF_Config_t *config,
3275 RF_Raid_t *raidPtr) 3292 RF_Raid_t *raidPtr)
3276{ 3293{
3277 RF_ComponentLabel_t *clabel; 3294 RF_ComponentLabel_t *clabel;
3278 int i; 3295 int i;
3279 3296
3280 clabel = ac->clabel; 3297 clabel = ac->clabel;
3281 3298
3282 /* 1. Fill in the common stuff */ 3299 /* 1. Fill in the common stuff */
3283 config->numRow = clabel->num_rows = 1; 3300 config->numRow = clabel->num_rows = 1;
3284 config->numCol = clabel->num_columns; 3301 config->numCol = clabel->num_columns;
3285 config->numSpare = 0; /* XXX should this be set here? */ 3302 config->numSpare = 0; /* XXX should this be set here? */
3286 config->sectPerSU = clabel->sectPerSU; 3303 config->sectPerSU = clabel->sectPerSU;
3287 config->SUsPerPU = clabel->SUsPerPU; 3304 config->SUsPerPU = clabel->SUsPerPU;
3288 config->SUsPerRU = clabel->SUsPerRU; 3305 config->SUsPerRU = clabel->SUsPerRU;
3289 config->parityConfig = clabel->parityConfig; 3306 config->parityConfig = clabel->parityConfig;
3290 /* XXX... */ 3307 /* XXX... */
3291 strcpy(config->diskQueueType,"fifo"); 3308 strcpy(config->diskQueueType,"fifo");
3292 config->maxOutstandingDiskReqs = clabel->maxOutstanding; 3309 config->maxOutstandingDiskReqs = clabel->maxOutstanding;
3293 config->layoutSpecificSize = 0; /* XXX ?? */ 3310 config->layoutSpecificSize = 0; /* XXX ?? */
3294 3311
3295 while(ac!=NULL) { 3312 while(ac!=NULL) {
3296 /* row/col values will be in range due to the checks 3313 /* row/col values will be in range due to the checks
3297 in reasonable_label() */ 3314 in reasonable_label() */
3298 strcpy(config->devnames[0][ac->clabel->column], 3315 strcpy(config->devnames[0][ac->clabel->column],
3299 ac->devname); 3316 ac->devname);
3300 ac = ac->next; 3317 ac = ac->next;
3301 } 3318 }
3302 3319
3303 for(i=0;i<RF_MAXDBGV;i++) { 3320 for(i=0;i<RF_MAXDBGV;i++) {
3304 config->debugVars[i][0] = 0; 3321 config->debugVars[i][0] = 0;
3305 } 3322 }
3306} 3323}
3307 3324
3308int 3325int
3309rf_set_autoconfig(RF_Raid_t *raidPtr, int new_value) 3326rf_set_autoconfig(RF_Raid_t *raidPtr, int new_value)
3310{ 3327{
3311 RF_ComponentLabel_t clabel; 3328 RF_ComponentLabel_t clabel;
3312 struct vnode *vp; 3329 struct vnode *vp;
3313 dev_t dev; 3330 dev_t dev;
3314 int column; 3331 int column;
3315 int sparecol; 3332 int sparecol;
3316 3333
3317 raidPtr->autoconfigure = new_value; 3334 raidPtr->autoconfigure = new_value;
3318 3335
3319 for(column=0; column<raidPtr->numCol; column++) { 3336 for(column=0; column<raidPtr->numCol; column++) {
3320 if (raidPtr->Disks[column].status == rf_ds_optimal) { 3337 if (raidPtr->Disks[column].status == rf_ds_optimal) {
3321 dev = raidPtr->Disks[column].dev; 3338 dev = raidPtr->Disks[column].dev;
3322 vp = raidPtr->raid_cinfo[column].ci_vp; 3339 vp = raidPtr->raid_cinfo[column].ci_vp;
3323 raidread_component_label(dev, vp, &clabel); 3340 raidread_component_label(dev, vp, &clabel);
3324 clabel.autoconfigure = new_value; 3341 clabel.autoconfigure = new_value;
3325 raidwrite_component_label(dev, vp, &clabel); 3342 raidwrite_component_label(dev, vp, &clabel);
3326 } 3343 }
3327 } 3344 }
3328 for(column = 0; column < raidPtr->numSpare ; column++) { 3345 for(column = 0; column < raidPtr->numSpare ; column++) {
3329 sparecol = raidPtr->numCol + column; 3346 sparecol = raidPtr->numCol + column;
3330 if (raidPtr->Disks[sparecol].status == rf_ds_used_spare) { 3347 if (raidPtr->Disks[sparecol].status == rf_ds_used_spare) {
3331 dev = raidPtr->Disks[sparecol].dev; 3348 dev = raidPtr->Disks[sparecol].dev;
3332 vp = raidPtr->raid_cinfo[sparecol].ci_vp; 3349 vp = raidPtr->raid_cinfo[sparecol].ci_vp;
3333 raidread_component_label(dev, vp, &clabel); 3350 raidread_component_label(dev, vp, &clabel);
3334 clabel.autoconfigure = new_value; 3351 clabel.autoconfigure = new_value;
3335 raidwrite_component_label(dev, vp, &clabel); 3352 raidwrite_component_label(dev, vp, &clabel);
3336 } 3353 }
3337 } 3354 }
3338 return(new_value); 3355 return(new_value);
3339} 3356}
3340 3357
3341int 3358int
3342rf_set_rootpartition(RF_Raid_t *raidPtr, int new_value) 3359rf_set_rootpartition(RF_Raid_t *raidPtr, int new_value)
3343{ 3360{
3344 RF_ComponentLabel_t clabel; 3361 RF_ComponentLabel_t clabel;
3345 struct vnode *vp; 3362 struct vnode *vp;
3346 dev_t dev; 3363 dev_t dev;
3347 int column; 3364 int column;
3348 int sparecol; 3365 int sparecol;
3349 3366
3350 raidPtr->root_partition = new_value; 3367 raidPtr->root_partition = new_value;
3351 for(column=0; column<raidPtr->numCol; column++) { 3368 for(column=0; column<raidPtr->numCol; column++) {
3352 if (raidPtr->Disks[column].status == rf_ds_optimal) { 3369 if (raidPtr->Disks[column].status == rf_ds_optimal) {
3353 dev = raidPtr->Disks[column].dev; 3370 dev = raidPtr->Disks[column].dev;
3354 vp = raidPtr->raid_cinfo[column].ci_vp; 3371 vp = raidPtr->raid_cinfo[column].ci_vp;
3355 raidread_component_label(dev, vp, &clabel); 3372 raidread_component_label(dev, vp, &clabel);
3356 clabel.root_partition = new_value; 3373 clabel.root_partition = new_value;
3357 raidwrite_component_label(dev, vp, &clabel); 3374 raidwrite_component_label(dev, vp, &clabel);
3358 } 3375 }
3359 } 3376 }
3360 for(column = 0; column < raidPtr->numSpare ; column++) { 3377 for(column = 0; column < raidPtr->numSpare ; column++) {
3361 sparecol = raidPtr->numCol + column; 3378 sparecol = raidPtr->numCol + column;
3362 if (raidPtr->Disks[sparecol].status == rf_ds_used_spare) { 3379 if (raidPtr->Disks[sparecol].status == rf_ds_used_spare) {
3363 dev = raidPtr->Disks[sparecol].dev; 3380 dev = raidPtr->Disks[sparecol].dev;
3364 vp = raidPtr->raid_cinfo[sparecol].ci_vp; 3381 vp = raidPtr->raid_cinfo[sparecol].ci_vp;
3365 raidread_component_label(dev, vp, &clabel); 3382 raidread_component_label(dev, vp, &clabel);
3366 clabel.root_partition = new_value; 3383 clabel.root_partition = new_value;
3367 raidwrite_component_label(dev, vp, &clabel); 3384 raidwrite_component_label(dev, vp, &clabel);
3368 } 3385 }
3369 } 3386 }
3370 return(new_value); 3387 return(new_value);
3371} 3388}
3372 3389
3373void 3390void
3374rf_release_all_vps(RF_ConfigSet_t *cset) 3391rf_release_all_vps(RF_ConfigSet_t *cset)
3375{ 3392{
3376 RF_AutoConfig_t *ac; 3393 RF_AutoConfig_t *ac;
3377 3394
3378 ac = cset->ac; 3395 ac = cset->ac;
3379 while(ac!=NULL) { 3396 while(ac!=NULL) {
3380 /* Close the vp, and give it back */ 3397 /* Close the vp, and give it back */
3381 if (ac->vp) { 3398 if (ac->vp) {
3382 vn_lock(ac->vp, LK_EXCLUSIVE | LK_RETRY); 3399 vn_lock(ac->vp, LK_EXCLUSIVE | LK_RETRY);
3383 VOP_CLOSE(ac->vp, FREAD, NOCRED); 3400 VOP_CLOSE(ac->vp, FREAD, NOCRED);
3384 vput(ac->vp); 3401 vput(ac->vp);
3385 ac->vp = NULL; 3402 ac->vp = NULL;
3386 } 3403 }
3387 ac = ac->next; 3404 ac = ac->next;
3388 } 3405 }
3389} 3406}
3390 3407
3391 3408
3392void 3409void
3393rf_cleanup_config_set(RF_ConfigSet_t *cset) 3410rf_cleanup_config_set(RF_ConfigSet_t *cset)
3394{ 3411{
3395 RF_AutoConfig_t *ac; 3412 RF_AutoConfig_t *ac;
3396 RF_AutoConfig_t *next_ac; 3413 RF_AutoConfig_t *next_ac;
3397 3414
3398 ac = cset->ac; 3415 ac = cset->ac;
3399 while(ac!=NULL) { 3416 while(ac!=NULL) {
3400 next_ac = ac->next; 3417 next_ac = ac->next;
3401 /* nuke the label */ 3418 /* nuke the label */
3402 free(ac->clabel, M_RAIDFRAME); 3419 free(ac->clabel, M_RAIDFRAME);
3403 /* cleanup the config structure */ 3420 /* cleanup the config structure */
3404 free(ac, M_RAIDFRAME); 3421 free(ac, M_RAIDFRAME);
3405 /* "next.." */ 3422 /* "next.." */
3406 ac = next_ac; 3423 ac = next_ac;
3407 } 3424 }
3408 /* and, finally, nuke the config set */ 3425 /* and, finally, nuke the config set */
3409 free(cset, M_RAIDFRAME); 3426 free(cset, M_RAIDFRAME);
3410} 3427}
3411 3428
3412 3429
3413void 3430void
3414raid_init_component_label(RF_Raid_t *raidPtr, RF_ComponentLabel_t *clabel) 3431raid_init_component_label(RF_Raid_t *raidPtr, RF_ComponentLabel_t *clabel)
3415{ 3432{
3416 /* current version number */ 3433 /* current version number */
3417 clabel->version = RF_COMPONENT_LABEL_VERSION; 3434 clabel->version = RF_COMPONENT_LABEL_VERSION;
3418 clabel->serial_number = raidPtr->serial_number; 3435 clabel->serial_number = raidPtr->serial_number;
3419 clabel->mod_counter = raidPtr->mod_counter; 3436 clabel->mod_counter = raidPtr->mod_counter;
3420 clabel->num_rows = 1; 3437 clabel->num_rows = 1;
3421 clabel->num_columns = raidPtr->numCol; 3438 clabel->num_columns = raidPtr->numCol;
3422 clabel->clean = RF_RAID_DIRTY; /* not clean */ 3439 clabel->clean = RF_RAID_DIRTY; /* not clean */
3423 clabel->status = rf_ds_optimal; /* "It's good!" */ 3440 clabel->status = rf_ds_optimal; /* "It's good!" */
3424 3441
3425 clabel->sectPerSU = raidPtr->Layout.sectorsPerStripeUnit; 3442 clabel->sectPerSU = raidPtr->Layout.sectorsPerStripeUnit;
3426 clabel->SUsPerPU = raidPtr->Layout.SUsPerPU; 3443 clabel->SUsPerPU = raidPtr->Layout.SUsPerPU;
3427 clabel->SUsPerRU = raidPtr->Layout.SUsPerRU; 3444 clabel->SUsPerRU = raidPtr->Layout.SUsPerRU;
3428 3445
3429 clabel->blockSize = raidPtr->bytesPerSector; 3446 clabel->blockSize = raidPtr->bytesPerSector;
3430 clabel->numBlocks = raidPtr->sectorsPerDisk; 3447 clabel->numBlocks = raidPtr->sectorsPerDisk;
3431 3448
3432 /* XXX not portable */ 3449 /* XXX not portable */
3433 clabel->parityConfig = raidPtr->Layout.map->parityConfig; 3450 clabel->parityConfig = raidPtr->Layout.map->parityConfig;
3434 clabel->maxOutstanding = raidPtr->maxOutstanding; 3451 clabel->maxOutstanding = raidPtr->maxOutstanding;
3435 clabel->autoconfigure = raidPtr->autoconfigure; 3452 clabel->autoconfigure = raidPtr->autoconfigure;
3436 clabel->root_partition = raidPtr->root_partition; 3453 clabel->root_partition = raidPtr->root_partition;
3437 clabel->last_unit = raidPtr->raidid; 3454 clabel->last_unit = raidPtr->raidid;
3438 clabel->config_order = raidPtr->config_order; 3455 clabel->config_order = raidPtr->config_order;
3439} 3456}
3440 3457
3441int 3458int
3442rf_auto_config_set(RF_ConfigSet_t *cset, int *unit) 3459rf_auto_config_set(RF_ConfigSet_t *cset, int *unit)
3443{ 3460{
3444 RF_Raid_t *raidPtr; 3461 RF_Raid_t *raidPtr;
3445 RF_Config_t *config; 3462 RF_Config_t *config;
3446 int raidID; 3463 int raidID;
3447 int retcode; 3464 int retcode;
3448 3465
3449#ifdef DEBUG 3466#ifdef DEBUG
3450 printf("RAID autoconfigure\n"); 3467 printf("RAID autoconfigure\n");
3451#endif 3468#endif
3452 3469
3453 retcode = 0; 3470 retcode = 0;
3454 *unit = -1; 3471 *unit = -1;
3455 3472
3456 /* 1. Create a config structure */ 3473 /* 1. Create a config structure */
3457 3474
3458 config = (RF_Config_t *)malloc(sizeof(RF_Config_t), 3475 config = (RF_Config_t *)malloc(sizeof(RF_Config_t),
3459 M_RAIDFRAME, 3476 M_RAIDFRAME,
3460 M_NOWAIT); 3477 M_NOWAIT);
3461 if (config==NULL) { 3478 if (config==NULL) {
3462 printf("Out of mem!?!?\n"); 3479 printf("Out of mem!?!?\n");
3463 /* XXX do something more intelligent here. */ 3480 /* XXX do something more intelligent here. */
3464 return(1); 3481 return(1);
3465 } 3482 }
3466 3483
3467 memset(config, 0, sizeof(RF_Config_t)); 3484 memset(config, 0, sizeof(RF_Config_t));
3468 3485
3469 /* 3486 /*
3470 2. Figure out what RAID ID this one is supposed to live at 3487 2. Figure out what RAID ID this one is supposed to live at
3471 See if we can get the same RAID dev that it was configured 3488 See if we can get the same RAID dev that it was configured
3472 on last time.. 3489 on last time..
3473 */ 3490 */
3474 3491
3475 raidID = cset->ac->clabel->last_unit; 3492 raidID = cset->ac->clabel->last_unit;
3476 if ((raidID < 0) || (raidID >= numraid)) { 3493 if ((raidID < 0) || (raidID >= numraid)) {
3477 /* let's not wander off into lala land. */ 3494 /* let's not wander off into lala land. */
3478 raidID = numraid - 1; 3495 raidID = numraid - 1;
3479 } 3496 }
3480 if (raidPtrs[raidID]->valid != 0) { 3497 if (raidPtrs[raidID]->valid != 0) {
3481 3498
3482 /* 3499 /*
3483 Nope... Go looking for an alternative... 3500 Nope... Go looking for an alternative...
3484 Start high so we don't immediately use raid0 if that's 3501 Start high so we don't immediately use raid0 if that's
3485 not taken. 3502 not taken.
3486 */ 3503 */
3487 3504
3488 for(raidID = numraid - 1; raidID >= 0; raidID--) { 3505 for(raidID = numraid - 1; raidID >= 0; raidID--) {
3489 if (raidPtrs[raidID]->valid == 0) { 3506 if (raidPtrs[raidID]->valid == 0) {
3490 /* can use this one! */ 3507 /* can use this one! */
3491 break; 3508 break;
3492 } 3509 }
3493 } 3510 }
3494 } 3511 }
3495 3512
3496 if (raidID < 0) { 3513 if (raidID < 0) {
3497 /* punt... */ 3514 /* punt... */
3498 printf("Unable to auto configure this set!\n"); 3515 printf("Unable to auto configure this set!\n");
3499 printf("(Out of RAID devs!)\n"); 3516 printf("(Out of RAID devs!)\n");
3500 free(config, M_RAIDFRAME); 3517 free(config, M_RAIDFRAME);
3501 return(1); 3518 return(1);
3502 } 3519 }
3503 3520
3504#ifdef DEBUG 3521#ifdef DEBUG
3505 printf("Configuring raid%d:\n",raidID); 3522 printf("Configuring raid%d:\n",raidID);
3506#endif 3523#endif
3507 3524
3508 raidPtr = raidPtrs[raidID]; 3525 raidPtr = raidPtrs[raidID];
3509 3526
3510 /* XXX all this stuff should be done SOMEWHERE ELSE! */ 3527 /* XXX all this stuff should be done SOMEWHERE ELSE! */
3511 raidPtr->raidid = raidID; 3528 raidPtr->raidid = raidID;
3512 raidPtr->openings = RAIDOUTSTANDING; 3529 raidPtr->openings = RAIDOUTSTANDING;
3513 3530
3514 /* 3. Build the configuration structure */ 3531 /* 3. Build the configuration structure */
3515 rf_create_configuration(cset->ac, config, raidPtr); 3532 rf_create_configuration(cset->ac, config, raidPtr);
3516 3533
3517 /* 4. Do the configuration */ 3534 /* 4. Do the configuration */
3518 retcode = rf_Configure(raidPtr, config, cset->ac); 3535 retcode = rf_Configure(raidPtr, config, cset->ac);
3519 3536
3520 if (retcode == 0) { 3537 if (retcode == 0) {
3521 3538
3522 raidinit(raidPtrs[raidID]); 3539 raidinit(raidPtrs[raidID]);
3523 3540
3524 rf_markalldirty(raidPtrs[raidID]); 3541 rf_markalldirty(raidPtrs[raidID]);
3525 raidPtrs[raidID]->autoconfigure = 1; /* XXX do this here? */ 3542 raidPtrs[raidID]->autoconfigure = 1; /* XXX do this here? */
3526 if (cset->ac->clabel->root_partition==1) { 3543 if (cset->ac->clabel->root_partition==1) {
3527 /* everything configured just fine. Make a note 3544 /* everything configured just fine. Make a note
3528 that this set is eligible to be root. */ 3545 that this set is eligible to be root. */
3529 cset->rootable = 1; 3546 cset->rootable = 1;
3530 /* XXX do this here? */ 3547 /* XXX do this here? */
3531 raidPtrs[raidID]->root_partition = 1; 3548 raidPtrs[raidID]->root_partition = 1;
3532 } 3549 }
3533 } 3550 }
3534 3551
3535 /* 5. Cleanup */ 3552 /* 5. Cleanup */
3536 free(config, M_RAIDFRAME); 3553 free(config, M_RAIDFRAME);
3537 3554
3538 *unit = raidID; 3555 *unit = raidID;
3539 return(retcode); 3556 return(retcode);
3540} 3557}
3541 3558
3542void 3559void
3543rf_disk_unbusy(RF_RaidAccessDesc_t *desc) 3560rf_disk_unbusy(RF_RaidAccessDesc_t *desc)
3544{ 3561{
3545 struct buf *bp; 3562 struct buf *bp;
3546 3563
3547 bp = (struct buf *)desc->bp; 3564 bp = (struct buf *)desc->bp;
3548 disk_unbusy(&raid_softc[desc->raidPtr->raidid].sc_dkdev, 3565 disk_unbusy(&raid_softc[desc->raidPtr->raidid].sc_dkdev,
3549 (bp->b_bcount - bp->b_resid), (bp->b_flags & B_READ)); 3566 (bp->b_bcount - bp->b_resid), (bp->b_flags & B_READ));
3550} 3567}
3551 3568
3552void 3569void
3553rf_pool_init(struct pool *p, size_t size, const char *w_chan, 3570rf_pool_init(struct pool *p, size_t size, const char *w_chan,
3554 size_t xmin, size_t xmax) 3571 size_t xmin, size_t xmax)
3555{ 3572{
3556 pool_init(p, size, 0, 0, 0, w_chan, NULL, IPL_BIO); 3573 pool_init(p, size, 0, 0, 0, w_chan, NULL, IPL_BIO);
3557 pool_sethiwat(p, xmax); 3574 pool_sethiwat(p, xmax);
3558 pool_prime(p, xmin); 3575 pool_prime(p, xmin);
3559 pool_setlowat(p, xmin); 3576 pool_setlowat(p, xmin);
3560} 3577}
3561 3578
3562/* 3579/*
3563 * rf_buf_queue_check(int raidid) -- looks into the buf_queue to see 3580 * rf_buf_queue_check(int raidid) -- looks into the buf_queue to see
3564 * if there is IO pending and if that IO could possibly be done for a 3581 * if there is IO pending and if that IO could possibly be done for a
3565 * given RAID set. Returns 0 if IO is waiting and can be done, 1 3582 * given RAID set. Returns 0 if IO is waiting and can be done, 1
3566 * otherwise. 3583 * otherwise.
3567 * 3584 *
3568 */ 3585 */
3569 3586
3570int 3587int
3571rf_buf_queue_check(int raidid) 3588rf_buf_queue_check(int raidid)
3572{ 3589{
3573 if ((bufq_peek(raid_softc[raidid].buf_queue) != NULL) && 3590 if ((bufq_peek(raid_softc[raidid].buf_queue) != NULL) &&
3574 raidPtrs[raidid]->openings > 0) { 3591 raidPtrs[raidid]->openings > 0) {
3575 /* there is work to do */ 3592 /* there is work to do */
3576 return 0; 3593 return 0;
3577 }  3594 }
3578 /* default is nothing to do */ 3595 /* default is nothing to do */
3579 return 1; 3596 return 1;
3580} 3597}
3581 3598
3582int 3599int
3583rf_getdisksize(struct vnode *vp, struct lwp *l, RF_RaidDisk_t *diskPtr) 3600rf_getdisksize(struct vnode *vp, struct lwp *l, RF_RaidDisk_t *diskPtr)
3584{ 3601{
3585 struct partinfo dpart; 3602 struct partinfo dpart;
3586 struct dkwedge_info dkw; 3603 struct dkwedge_info dkw;
3587 int error; 3604 int error;
3588 3605
3589 error = VOP_IOCTL(vp, DIOCGPART, &dpart, FREAD, l->l_cred); 3606 error = VOP_IOCTL(vp, DIOCGPART, &dpart, FREAD, l->l_cred);
3590 if (error == 0) { 3607 if (error == 0) {
3591 diskPtr->blockSize = dpart.disklab->d_secsize; 3608 diskPtr->blockSize = dpart.disklab->d_secsize;
3592 diskPtr->numBlocks = dpart.part->p_size - rf_protectedSectors; 3609 diskPtr->numBlocks = dpart.part->p_size - rf_protectedSectors;
3593 diskPtr->partitionSize = dpart.part->p_size; 3610 diskPtr->partitionSize = dpart.part->p_size;
3594 return 0; 3611 return 0;
3595 } 3612 }
3596 3613
3597 error = VOP_IOCTL(vp, DIOCGWEDGEINFO, &dkw, FREAD, l->l_cred); 3614 error = VOP_IOCTL(vp, DIOCGWEDGEINFO, &dkw, FREAD, l->l_cred);
3598 if (error == 0) { 3615 if (error == 0) {
3599 diskPtr->blockSize = 512; /* XXX */ 3616 diskPtr->blockSize = 512; /* XXX */
3600 diskPtr->numBlocks = dkw.dkw_size - rf_protectedSectors; 3617 diskPtr->numBlocks = dkw.dkw_size - rf_protectedSectors;
3601 diskPtr->partitionSize = dkw.dkw_size; 3618 diskPtr->partitionSize = dkw.dkw_size;
3602 return 0; 3619 return 0;
3603 } 3620 }
3604 return error; 3621 return error;
3605} 3622}
3606 3623
3607static int 3624static int
3608raid_match(device_t self, cfdata_t cfdata, void *aux) 3625raid_match(device_t self, cfdata_t cfdata, void *aux)
3609{ 3626{
3610 return 1; 3627 return 1;
3611} 3628}
3612 3629
3613static void 3630static void
3614raid_attach(device_t parent, device_t self, void *aux) 3631raid_attach(device_t parent, device_t self, void *aux)
3615{ 3632{
3616 3633
3617} 3634}
3618 3635
3619 3636
3620static int 3637static int
3621raid_detach(device_t self, int flags) 3638raid_detach(device_t self, int flags)
3622{ 3639{
3623 struct raid_softc *rs = device_private(self); 3640 int error;
 3641 struct raid_softc *rs = &raid_softc[device_unit(self)];
3624 3642
3625 if (rs->sc_flags & RAIDF_INITED) 3643 if ((error = raidlock(rs)) != 0)
3626 return EBUSY; 3644 return (error);
3627 3645
3628 return 0; 3646 error = raid_detach_unlocked(rs);
 3647
 3648 raidunlock(rs);
 3649
 3650 return error;
3629} 3651}
3630 3652
3631static void 3653static void
3632rf_set_properties(struct raid_softc *rs, RF_Raid_t *raidPtr) 3654rf_set_properties(struct raid_softc *rs, RF_Raid_t *raidPtr)
3633{ 3655{
3634 prop_dictionary_t disk_info, odisk_info, geom; 3656 prop_dictionary_t disk_info, odisk_info, geom;
3635 disk_info = prop_dictionary_create(); 3657 disk_info = prop_dictionary_create();
3636 geom = prop_dictionary_create(); 3658 geom = prop_dictionary_create();
3637 prop_dictionary_set_uint64(geom, "sectors-per-unit", 3659 prop_dictionary_set_uint64(geom, "sectors-per-unit",
3638 raidPtr->totalSectors); 3660 raidPtr->totalSectors);
3639 prop_dictionary_set_uint32(geom, "sector-size", 3661 prop_dictionary_set_uint32(geom, "sector-size",
3640 raidPtr->bytesPerSector); 3662 raidPtr->bytesPerSector);
3641  3663
3642 prop_dictionary_set_uint16(geom, "sectors-per-track", 3664 prop_dictionary_set_uint16(geom, "sectors-per-track",
3643 raidPtr->Layout.dataSectorsPerStripe); 3665 raidPtr->Layout.dataSectorsPerStripe);
3644 prop_dictionary_set_uint16(geom, "tracks-per-cylinder", 3666 prop_dictionary_set_uint16(geom, "tracks-per-cylinder",
3645 4 * raidPtr->numCol); 3667 4 * raidPtr->numCol);
3646  3668
3647 prop_dictionary_set_uint64(geom, "cylinders-per-unit", 3669 prop_dictionary_set_uint64(geom, "cylinders-per-unit",
3648 raidPtr->totalSectors / (raidPtr->Layout.dataSectorsPerStripe * 3670 raidPtr->totalSectors / (raidPtr->Layout.dataSectorsPerStripe *
3649 (4 * raidPtr->numCol))); 3671 (4 * raidPtr->numCol)));
3650  3672
3651 prop_dictionary_set(disk_info, "geometry", geom); 3673 prop_dictionary_set(disk_info, "geometry", geom);
3652 prop_object_release(geom); 3674 prop_object_release(geom);
3653 prop_dictionary_set(device_properties(rs->sc_dev), 3675 prop_dictionary_set(device_properties(rs->sc_dev),
3654 "disk-info", disk_info); 3676 "disk-info", disk_info);
3655 odisk_info = rs->sc_dkdev.dk_info; 3677 odisk_info = rs->sc_dkdev.dk_info;
3656 rs->sc_dkdev.dk_info = disk_info; 3678 rs->sc_dkdev.dk_info = disk_info;
3657 if (odisk_info) 3679 if (odisk_info)
3658 prop_object_release(odisk_info); 3680 prop_object_release(odisk_info);
3659} 3681}
3660 3682
3661/*  3683/*
3662 * Implement forwarding of the DIOCCACHESYNC ioctl to each of the components. 3684 * Implement forwarding of the DIOCCACHESYNC ioctl to each of the components.
3663 * We end up returning whatever error was returned by the first cache flush 3685 * We end up returning whatever error was returned by the first cache flush
3664 * that fails. 3686 * that fails.
3665 */ 3687 */
3666 3688
3667static int 3689static int
3668rf_sync_component_caches(RF_Raid_t *raidPtr) 3690rf_sync_component_caches(RF_Raid_t *raidPtr)
3669{ 3691{
3670 int c, sparecol; 3692 int c, sparecol;
3671 int e,error; 3693 int e,error;
3672 int force = 1; 3694 int force = 1;
3673  3695
3674 error = 0; 3696 error = 0;
3675 for (c = 0; c < raidPtr->numCol; c++) { 3697 for (c = 0; c < raidPtr->numCol; c++) {
3676 if (raidPtr->Disks[c].status == rf_ds_optimal) { 3698 if (raidPtr->Disks[c].status == rf_ds_optimal) {
3677 e = VOP_IOCTL(raidPtr->raid_cinfo[c].ci_vp, DIOCCACHESYNC,  3699 e = VOP_IOCTL(raidPtr->raid_cinfo[c].ci_vp, DIOCCACHESYNC,
3678 &force, FWRITE, NOCRED); 3700 &force, FWRITE, NOCRED);
3679 if (e) { 3701 if (e) {
3680 if (e != ENODEV) 3702 if (e != ENODEV)
3681 printf("raid%d: cache flush to component %s failed.\n", 3703 printf("raid%d: cache flush to component %s failed.\n",
3682 raidPtr->raidid, raidPtr->Disks[c].devname); 3704 raidPtr->raidid, raidPtr->Disks[c].devname);
3683 if (error == 0) { 3705 if (error == 0) {
3684 error = e; 3706 error = e;
3685 } 3707 }
3686 } 3708 }
3687 } 3709 }
3688 } 3710 }
3689 3711
3690 for( c = 0; c < raidPtr->numSpare ; c++) { 3712 for( c = 0; c < raidPtr->numSpare ; c++) {
3691 sparecol = raidPtr->numCol + c; 3713 sparecol = raidPtr->numCol + c;
3692 /* Need to ensure that the reconstruct actually completed! */ 3714 /* Need to ensure that the reconstruct actually completed! */
3693 if (raidPtr->Disks[sparecol].status == rf_ds_used_spare) { 3715 if (raidPtr->Disks[sparecol].status == rf_ds_used_spare) {
3694 e = VOP_IOCTL(raidPtr->raid_cinfo[sparecol].ci_vp, 3716 e = VOP_IOCTL(raidPtr->raid_cinfo[sparecol].ci_vp,
3695 DIOCCACHESYNC, &force, FWRITE, NOCRED); 3717 DIOCCACHESYNC, &force, FWRITE, NOCRED);
3696 if (e) { 3718 if (e) {
3697 if (e != ENODEV) 3719 if (e != ENODEV)
3698 printf("raid%d: cache flush to component %s failed.\n", 3720 printf("raid%d: cache flush to component %s failed.\n",
3699 raidPtr->raidid, raidPtr->Disks[sparecol].devname); 3721 raidPtr->raidid, raidPtr->Disks[sparecol].devname);
3700 if (error == 0) { 3722 if (error == 0) {
3701 error = e; 3723 error = e;
3702 } 3724 }
3703 } 3725 }
3704 } 3726 }
3705 } 3727 }
3706 return error; 3728 return error;
3707} 3729}