]> git.ipfire.org Git - thirdparty/mdadm.git/blame - super-ddf.c
DDF: validate_geometry_ddf: support RAID10
[thirdparty/mdadm.git] / super-ddf.c
CommitLineData
a322f70c
DW
1/*
2 * mdadm - manage Linux "md" devices aka RAID arrays.
3 *
e736b623 4 * Copyright (C) 2006-2009 Neil Brown <neilb@suse.de>
a322f70c
DW
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * Author: Neil Brown
22 * Email: <neil@brown.name>
23 *
24 * Specifications for DDF takes from Common RAID DDF Specification Revision 1.2
25 * (July 28 2006). Reused by permission of SNIA.
26 */
27
28#define HAVE_STDINT_H 1
29#include "mdadm.h"
549e9569 30#include "mdmon.h"
a322f70c
DW
31#include "sha1.h"
32#include <values.h>
33
a322f70c
DW
34/* a non-official T10 name for creation GUIDs */
35static char T10[] = "Linux-MD";
36
37/* DDF timestamps are 1980 based, so we need to add
38 * second-in-decade-of-seventies to convert to linux timestamps.
39 * 10 years with 2 leap years.
40 */
41#define DECADE (3600*24*(365*10+2))
42unsigned long crc32(
43 unsigned long crc,
44 const unsigned char *buf,
45 unsigned len);
46
bedbf68a 47#define DDF_NOTFOUND (~0U)
48#define DDF_CONTAINER (DDF_NOTFOUND-1)
49
a322f70c
DW
50/* The DDF metadata handling.
51 * DDF metadata lives at the end of the device.
52 * The last 512 byte block provides an 'anchor' which is used to locate
53 * the rest of the metadata which usually lives immediately behind the anchor.
54 *
55 * Note:
56 * - all multibyte numeric fields are bigendian.
57 * - all strings are space padded.
58 *
59 */
60
61/* Primary Raid Level (PRL) */
62#define DDF_RAID0 0x00
63#define DDF_RAID1 0x01
64#define DDF_RAID3 0x03
65#define DDF_RAID4 0x04
66#define DDF_RAID5 0x05
67#define DDF_RAID1E 0x11
68#define DDF_JBOD 0x0f
69#define DDF_CONCAT 0x1f
70#define DDF_RAID5E 0x15
71#define DDF_RAID5EE 0x25
59e36268 72#define DDF_RAID6 0x06
a322f70c
DW
73
74/* Raid Level Qualifier (RLQ) */
75#define DDF_RAID0_SIMPLE 0x00
76#define DDF_RAID1_SIMPLE 0x00 /* just 2 devices in this plex */
77#define DDF_RAID1_MULTI 0x01 /* exactly 3 devices in this plex */
78#define DDF_RAID3_0 0x00 /* parity in first extent */
79#define DDF_RAID3_N 0x01 /* parity in last extent */
80#define DDF_RAID4_0 0x00 /* parity in first extent */
81#define DDF_RAID4_N 0x01 /* parity in last extent */
82/* these apply to raid5e and raid5ee as well */
83#define DDF_RAID5_0_RESTART 0x00 /* same as 'right asymmetric' - layout 1 */
59e36268 84#define DDF_RAID6_0_RESTART 0x01 /* raid6 different from raid5 here!!! */
a322f70c
DW
85#define DDF_RAID5_N_RESTART 0x02 /* same as 'left asymmetric' - layout 0 */
86#define DDF_RAID5_N_CONTINUE 0x03 /* same as 'left symmetric' - layout 2 */
87
88#define DDF_RAID1E_ADJACENT 0x00 /* raid10 nearcopies==2 */
89#define DDF_RAID1E_OFFSET 0x01 /* raid10 offsetcopies==2 */
90
91/* Secondary RAID Level (SRL) */
92#define DDF_2STRIPED 0x00 /* This is weirder than RAID0 !! */
93#define DDF_2MIRRORED 0x01
94#define DDF_2CONCAT 0x02
95#define DDF_2SPANNED 0x03 /* This is also weird - be careful */
96
97/* Magic numbers */
98#define DDF_HEADER_MAGIC __cpu_to_be32(0xDE11DE11)
99#define DDF_CONTROLLER_MAGIC __cpu_to_be32(0xAD111111)
100#define DDF_PHYS_RECORDS_MAGIC __cpu_to_be32(0x22222222)
101#define DDF_PHYS_DATA_MAGIC __cpu_to_be32(0x33333333)
102#define DDF_VIRT_RECORDS_MAGIC __cpu_to_be32(0xDDDDDDDD)
103#define DDF_VD_CONF_MAGIC __cpu_to_be32(0xEEEEEEEE)
104#define DDF_SPARE_ASSIGN_MAGIC __cpu_to_be32(0x55555555)
105#define DDF_VU_CONF_MAGIC __cpu_to_be32(0x88888888)
106#define DDF_VENDOR_LOG_MAGIC __cpu_to_be32(0x01dBEEF0)
107#define DDF_BBM_LOG_MAGIC __cpu_to_be32(0xABADB10C)
108
109#define DDF_GUID_LEN 24
59e36268
NB
110#define DDF_REVISION_0 "01.00.00"
111#define DDF_REVISION_2 "01.02.00"
a322f70c
DW
112
113struct ddf_header {
88c164f4 114 __u32 magic; /* DDF_HEADER_MAGIC */
a322f70c
DW
115 __u32 crc;
116 char guid[DDF_GUID_LEN];
59e36268 117 char revision[8]; /* 01.02.00 */
a322f70c
DW
118 __u32 seq; /* starts at '1' */
119 __u32 timestamp;
120 __u8 openflag;
121 __u8 foreignflag;
122 __u8 enforcegroups;
123 __u8 pad0; /* 0xff */
124 __u8 pad1[12]; /* 12 * 0xff */
125 /* 64 bytes so far */
126 __u8 header_ext[32]; /* reserved: fill with 0xff */
127 __u64 primary_lba;
128 __u64 secondary_lba;
129 __u8 type;
130 __u8 pad2[3]; /* 0xff */
131 __u32 workspace_len; /* sectors for vendor space -
132 * at least 32768(sectors) */
133 __u64 workspace_lba;
134 __u16 max_pd_entries; /* one of 15, 63, 255, 1023, 4095 */
135 __u16 max_vd_entries; /* 2^(4,6,8,10,12)-1 : i.e. as above */
136 __u16 max_partitions; /* i.e. max num of configuration
137 record entries per disk */
138 __u16 config_record_len; /* 1 +ROUNDUP(max_primary_element_entries
139 *12/512) */
140 __u16 max_primary_element_entries; /* 16, 64, 256, 1024, or 4096 */
141 __u8 pad3[54]; /* 0xff */
142 /* 192 bytes so far */
143 __u32 controller_section_offset;
144 __u32 controller_section_length;
145 __u32 phys_section_offset;
146 __u32 phys_section_length;
147 __u32 virt_section_offset;
148 __u32 virt_section_length;
149 __u32 config_section_offset;
150 __u32 config_section_length;
151 __u32 data_section_offset;
152 __u32 data_section_length;
153 __u32 bbm_section_offset;
154 __u32 bbm_section_length;
155 __u32 diag_space_offset;
156 __u32 diag_space_length;
157 __u32 vendor_offset;
158 __u32 vendor_length;
159 /* 256 bytes so far */
160 __u8 pad4[256]; /* 0xff */
161};
162
163/* type field */
164#define DDF_HEADER_ANCHOR 0x00
165#define DDF_HEADER_PRIMARY 0x01
166#define DDF_HEADER_SECONDARY 0x02
167
168/* The content of the 'controller section' - global scope */
169struct ddf_controller_data {
88c164f4 170 __u32 magic; /* DDF_CONTROLLER_MAGIC */
a322f70c
DW
171 __u32 crc;
172 char guid[DDF_GUID_LEN];
173 struct controller_type {
174 __u16 vendor_id;
175 __u16 device_id;
176 __u16 sub_vendor_id;
177 __u16 sub_device_id;
178 } type;
179 char product_id[16];
180 __u8 pad[8]; /* 0xff */
181 __u8 vendor_data[448];
182};
183
184/* The content of phys_section - global scope */
185struct phys_disk {
88c164f4 186 __u32 magic; /* DDF_PHYS_RECORDS_MAGIC */
a322f70c
DW
187 __u32 crc;
188 __u16 used_pdes;
189 __u16 max_pdes;
190 __u8 pad[52];
191 struct phys_disk_entry {
192 char guid[DDF_GUID_LEN];
193 __u32 refnum;
194 __u16 type;
195 __u16 state;
196 __u64 config_size; /* DDF structures must be after here */
197 char path[18]; /* another horrible structure really */
198 __u8 pad[6];
199 } entries[0];
200};
201
202/* phys_disk_entry.type is a bitmap - bigendian remember */
203#define DDF_Forced_PD_GUID 1
204#define DDF_Active_in_VD 2
88c164f4 205#define DDF_Global_Spare 4 /* VD_CONF records are ignored */
a322f70c
DW
206#define DDF_Spare 8 /* overrides Global_spare */
207#define DDF_Foreign 16
208#define DDF_Legacy 32 /* no DDF on this device */
209
210#define DDF_Interface_mask 0xf00
211#define DDF_Interface_SCSI 0x100
212#define DDF_Interface_SAS 0x200
213#define DDF_Interface_SATA 0x300
214#define DDF_Interface_FC 0x400
215
216/* phys_disk_entry.state is a bigendian bitmap */
217#define DDF_Online 1
218#define DDF_Failed 2 /* overrides 1,4,8 */
219#define DDF_Rebuilding 4
220#define DDF_Transition 8
221#define DDF_SMART 16
222#define DDF_ReadErrors 32
223#define DDF_Missing 64
224
225/* The content of the virt_section global scope */
226struct virtual_disk {
88c164f4 227 __u32 magic; /* DDF_VIRT_RECORDS_MAGIC */
a322f70c
DW
228 __u32 crc;
229 __u16 populated_vdes;
230 __u16 max_vdes;
231 __u8 pad[52];
232 struct virtual_entry {
233 char guid[DDF_GUID_LEN];
234 __u16 unit;
235 __u16 pad0; /* 0xffff */
236 __u16 guid_crc;
237 __u16 type;
238 __u8 state;
239 __u8 init_state;
240 __u8 pad1[14];
241 char name[16];
242 } entries[0];
243};
244
245/* virtual_entry.type is a bitmap - bigendian */
246#define DDF_Shared 1
247#define DDF_Enforce_Groups 2
248#define DDF_Unicode 4
249#define DDF_Owner_Valid 8
250
251/* virtual_entry.state is a bigendian bitmap */
252#define DDF_state_mask 0x7
253#define DDF_state_optimal 0x0
254#define DDF_state_degraded 0x1
255#define DDF_state_deleted 0x2
256#define DDF_state_missing 0x3
257#define DDF_state_failed 0x4
7a7cc504 258#define DDF_state_part_optimal 0x5
a322f70c
DW
259
260#define DDF_state_morphing 0x8
261#define DDF_state_inconsistent 0x10
262
263/* virtual_entry.init_state is a bigendian bitmap */
264#define DDF_initstate_mask 0x03
265#define DDF_init_not 0x00
7a7cc504
NB
266#define DDF_init_quick 0x01 /* initialisation is progress.
267 * i.e. 'state_inconsistent' */
a322f70c
DW
268#define DDF_init_full 0x02
269
270#define DDF_access_mask 0xc0
271#define DDF_access_rw 0x00
272#define DDF_access_ro 0x80
273#define DDF_access_blocked 0xc0
274
275/* The content of the config_section - local scope
276 * It has multiple records each config_record_len sectors
277 * They can be vd_config or spare_assign
278 */
279
280struct vd_config {
88c164f4 281 __u32 magic; /* DDF_VD_CONF_MAGIC */
a322f70c
DW
282 __u32 crc;
283 char guid[DDF_GUID_LEN];
284 __u32 timestamp;
285 __u32 seqnum;
286 __u8 pad0[24];
287 __u16 prim_elmnt_count;
288 __u8 chunk_shift; /* 0 == 512, 1==1024 etc */
289 __u8 prl;
290 __u8 rlq;
291 __u8 sec_elmnt_count;
292 __u8 sec_elmnt_seq;
293 __u8 srl;
598f0d58
NB
294 __u64 blocks; /* blocks per component could be different
295 * on different component devices...(only
296 * for concat I hope) */
297 __u64 array_blocks; /* blocks in array */
a322f70c
DW
298 __u8 pad1[8];
299 __u32 spare_refs[8];
300 __u8 cache_pol[8];
301 __u8 bg_rate;
302 __u8 pad2[3];
303 __u8 pad3[52];
304 __u8 pad4[192];
305 __u8 v0[32]; /* reserved- 0xff */
306 __u8 v1[32]; /* reserved- 0xff */
307 __u8 v2[16]; /* reserved- 0xff */
308 __u8 v3[16]; /* reserved- 0xff */
309 __u8 vendor[32];
310 __u32 phys_refnum[0]; /* refnum of each disk in sequence */
311 /*__u64 lba_offset[0]; LBA offset in each phys. Note extents in a
312 bvd are always the same size */
313};
314
315/* vd_config.cache_pol[7] is a bitmap */
316#define DDF_cache_writeback 1 /* else writethrough */
317#define DDF_cache_wadaptive 2 /* only applies if writeback */
318#define DDF_cache_readahead 4
319#define DDF_cache_radaptive 8 /* only if doing read-ahead */
320#define DDF_cache_ifnobatt 16 /* even to write cache if battery is poor */
321#define DDF_cache_wallowed 32 /* enable write caching */
322#define DDF_cache_rallowed 64 /* enable read caching */
323
324struct spare_assign {
88c164f4 325 __u32 magic; /* DDF_SPARE_ASSIGN_MAGIC */
a322f70c
DW
326 __u32 crc;
327 __u32 timestamp;
328 __u8 reserved[7];
329 __u8 type;
330 __u16 populated; /* SAEs used */
331 __u16 max; /* max SAEs */
332 __u8 pad[8];
333 struct spare_assign_entry {
334 char guid[DDF_GUID_LEN];
335 __u16 secondary_element;
336 __u8 pad[6];
337 } spare_ents[0];
338};
339/* spare_assign.type is a bitmap */
340#define DDF_spare_dedicated 0x1 /* else global */
341#define DDF_spare_revertible 0x2 /* else committable */
342#define DDF_spare_active 0x4 /* else not active */
343#define DDF_spare_affinity 0x8 /* enclosure affinity */
344
345/* The data_section contents - local scope */
346struct disk_data {
88c164f4 347 __u32 magic; /* DDF_PHYS_DATA_MAGIC */
a322f70c
DW
348 __u32 crc;
349 char guid[DDF_GUID_LEN];
350 __u32 refnum; /* crc of some magic drive data ... */
351 __u8 forced_ref; /* set when above was not result of magic */
352 __u8 forced_guid; /* set if guid was forced rather than magic */
353 __u8 vendor[32];
354 __u8 pad[442];
355};
356
357/* bbm_section content */
358struct bad_block_log {
359 __u32 magic;
360 __u32 crc;
361 __u16 entry_count;
362 __u32 spare_count;
363 __u8 pad[10];
364 __u64 first_spare;
365 struct mapped_block {
366 __u64 defective_start;
367 __u32 replacement_start;
368 __u16 remap_count;
369 __u8 pad[2];
370 } entries[0];
371};
372
373/* Struct for internally holding ddf structures */
374/* The DDF structure stored on each device is potentially
375 * quite different, as some data is global and some is local.
376 * The global data is:
377 * - ddf header
378 * - controller_data
379 * - Physical disk records
380 * - Virtual disk records
381 * The local data is:
382 * - Configuration records
383 * - Physical Disk data section
384 * ( and Bad block and vendor which I don't care about yet).
385 *
386 * The local data is parsed into separate lists as it is read
387 * and reconstructed for writing. This means that we only need
388 * to make config changes once and they are automatically
389 * propagated to all devices.
390 * Note that the ddf_super has space of the conf and disk data
391 * for this disk and also for a list of all such data.
392 * The list is only used for the superblock that is being
393 * built in Create or Assemble to describe the whole array.
394 */
395struct ddf_super {
6416d527 396 struct ddf_header anchor, primary, secondary;
a322f70c 397 struct ddf_controller_data controller;
6416d527 398 struct ddf_header *active;
a322f70c
DW
399 struct phys_disk *phys;
400 struct virtual_disk *virt;
401 int pdsize, vdsize;
f21e18ca 402 unsigned int max_part, mppe, conf_rec_len;
d2ca6449 403 int currentdev;
18a2f463 404 int updates_pending;
a322f70c 405 struct vcl {
6416d527
NB
406 union {
407 char space[512];
408 struct {
409 struct vcl *next;
410 __u64 *lba_offset; /* location in 'conf' of
411 * the lba table */
f21e18ca 412 unsigned int vcnum; /* index into ->virt */
8ec5d685 413 struct vd_config **other_bvds;
6416d527
NB
414 __u64 *block_sizes; /* NULL if all the same */
415 };
416 };
a322f70c 417 struct vd_config conf;
d2ca6449 418 } *conflist, *currentconf;
a322f70c 419 struct dl {
6416d527
NB
420 union {
421 char space[512];
422 struct {
423 struct dl *next;
424 int major, minor;
425 char *devname;
426 int fd;
427 unsigned long long size; /* sectors */
097bcf00 428 unsigned long long primary_lba; /* sectors */
429 unsigned long long secondary_lba; /* sectors */
430 unsigned long long workspace_lba; /* sectors */
6416d527
NB
431 int pdnum; /* index in ->phys */
432 struct spare_assign *spare;
8592f29d
N
433 void *mdupdate; /* hold metadata update */
434
435 /* These fields used by auto-layout */
436 int raiddisk; /* slot to fill in autolayout */
437 __u64 esize;
6416d527
NB
438 };
439 };
a322f70c 440 struct disk_data disk;
b2280677 441 struct vcl *vlist[0]; /* max_part in size */
2cc2983d 442 } *dlist, *add_list;
a322f70c
DW
443};
444
445#ifndef offsetof
446#define offsetof(t,f) ((size_t)&(((t*)0)->f))
447#endif
448
7d5a7ff3 449#if DEBUG
fb9d0acb 450static int all_ff(const char *guid);
7d5a7ff3 451static void pr_state(struct ddf_super *ddf, const char *msg)
452{
453 unsigned int i;
454 dprintf("%s/%s: ", __func__, msg);
455 for (i = 0; i < __be16_to_cpu(ddf->active->max_vd_entries); i++) {
456 if (all_ff(ddf->virt->entries[i].guid))
457 continue;
458 dprintf("%u(s=%02x i=%02x) ", i,
459 ddf->virt->entries[i].state,
460 ddf->virt->entries[i].init_state);
461 }
462 dprintf("\n");
463}
464#else
465static void pr_state(const struct ddf_super *ddf, const char *msg) {}
466#endif
467
468#define ddf_set_updates_pending(x) \
469 do { (x)->updates_pending = 1; pr_state(x, __func__); } while (0)
470
f21e18ca 471static unsigned int calc_crc(void *buf, int len)
a322f70c
DW
472{
473 /* crcs are always at the same place as in the ddf_header */
474 struct ddf_header *ddf = buf;
475 __u32 oldcrc = ddf->crc;
476 __u32 newcrc;
477 ddf->crc = 0xffffffff;
478
479 newcrc = crc32(0, buf, len);
480 ddf->crc = oldcrc;
4abe6b70
N
481 /* The crc is store (like everything) bigendian, so convert
482 * here for simplicity
483 */
484 return __cpu_to_be32(newcrc);
a322f70c
DW
485}
486
a3163bf0 487#define DDF_INVALID_LEVEL 0xff
488#define DDF_NO_SECONDARY 0xff
489static int err_bad_md_layout(const mdu_array_info_t *array)
490{
491 pr_err("RAID%d layout %x with %d disks is unsupported for DDF\n",
492 array->level, array->layout, array->raid_disks);
493 return DDF_INVALID_LEVEL;
494}
495
496static int layout_md2ddf(const mdu_array_info_t *array,
497 struct vd_config *conf)
498{
499 __u16 prim_elmnt_count = __cpu_to_be16(array->raid_disks);
500 __u8 prl = DDF_INVALID_LEVEL, rlq = 0;
501 __u8 sec_elmnt_count = 1;
502 __u8 srl = DDF_NO_SECONDARY;
503
504 switch (array->level) {
505 case LEVEL_LINEAR:
506 prl = DDF_CONCAT;
507 break;
508 case 0:
509 rlq = DDF_RAID0_SIMPLE;
510 prl = DDF_RAID0;
511 break;
512 case 1:
513 switch (array->raid_disks) {
514 case 2:
515 rlq = DDF_RAID1_SIMPLE;
516 break;
517 case 3:
518 rlq = DDF_RAID1_MULTI;
519 break;
520 default:
521 return err_bad_md_layout(array);
522 }
523 prl = DDF_RAID1;
524 break;
525 case 4:
526 if (array->layout != 0)
527 return err_bad_md_layout(array);
528 rlq = DDF_RAID4_N;
529 prl = DDF_RAID4;
530 break;
531 case 5:
532 switch (array->layout) {
533 case ALGORITHM_LEFT_ASYMMETRIC:
534 rlq = DDF_RAID5_N_RESTART;
535 break;
536 case ALGORITHM_RIGHT_ASYMMETRIC:
537 rlq = DDF_RAID5_0_RESTART;
538 break;
539 case ALGORITHM_LEFT_SYMMETRIC:
540 rlq = DDF_RAID5_N_CONTINUE;
541 break;
542 case ALGORITHM_RIGHT_SYMMETRIC:
543 /* not mentioned in standard */
544 default:
545 return err_bad_md_layout(array);
546 }
547 prl = DDF_RAID5;
548 break;
549 case 6:
550 switch (array->layout) {
551 case ALGORITHM_ROTATING_N_RESTART:
552 rlq = DDF_RAID5_N_RESTART;
553 break;
554 case ALGORITHM_ROTATING_ZERO_RESTART:
555 rlq = DDF_RAID6_0_RESTART;
556 break;
557 case ALGORITHM_ROTATING_N_CONTINUE:
558 rlq = DDF_RAID5_N_CONTINUE;
559 break;
560 default:
561 return err_bad_md_layout(array);
562 }
563 prl = DDF_RAID6;
564 break;
565 case 10:
566 if (array->raid_disks % 2 == 0 && array->layout == 0x102) {
567 rlq = DDF_RAID1_SIMPLE;
568 prim_elmnt_count = __cpu_to_be16(2);
569 sec_elmnt_count = array->raid_disks / 2;
570 } else if (array->raid_disks % 3 == 0
571 && array->layout == 0x103) {
572 rlq = DDF_RAID1_MULTI;
573 prim_elmnt_count = __cpu_to_be16(3);
574 sec_elmnt_count = array->raid_disks / 3;
575 } else
576 return err_bad_md_layout(array);
577 srl = DDF_2SPANNED;
578 prl = DDF_RAID1;
579 break;
580 default:
581 return err_bad_md_layout(array);
582 }
583 conf->prl = prl;
584 conf->prim_elmnt_count = prim_elmnt_count;
585 conf->rlq = rlq;
586 conf->srl = srl;
587 conf->sec_elmnt_count = sec_elmnt_count;
588 return 0;
589}
590
8a2848a7 591static int err_bad_ddf_layout(const struct vd_config *conf)
592{
593 pr_err("DDF RAID %u qualifier %u with %u disks is unsupported\n",
594 conf->prl, conf->rlq, __be16_to_cpu(conf->prim_elmnt_count));
595 return -1;
596}
597
598static int layout_ddf2md(const struct vd_config *conf,
599 mdu_array_info_t *array)
600{
601 int level = LEVEL_UNSUPPORTED;
602 int layout = 0;
603 int raiddisks = __be16_to_cpu(conf->prim_elmnt_count);
604
605 if (conf->sec_elmnt_count > 1) {
606 /* see also check_secondary() */
607 if (conf->prl != DDF_RAID1 ||
608 (conf->srl != DDF_2STRIPED && conf->srl != DDF_2SPANNED)) {
609 pr_err("Unsupported secondary RAID level %u/%u\n",
610 conf->prl, conf->srl);
611 return -1;
612 }
613 if (raiddisks == 2 && conf->rlq == DDF_RAID1_SIMPLE)
614 layout = 0x102;
615 else if (raiddisks == 3 && conf->rlq == DDF_RAID1_MULTI)
616 layout = 0x103;
617 else
618 return err_bad_ddf_layout(conf);
619 raiddisks *= conf->sec_elmnt_count;
620 level = 10;
621 goto good;
622 }
623
624 switch (conf->prl) {
625 case DDF_CONCAT:
626 level = LEVEL_LINEAR;
627 break;
628 case DDF_RAID0:
629 if (conf->rlq != DDF_RAID0_SIMPLE)
630 return err_bad_ddf_layout(conf);
631 level = 0;
632 break;
633 case DDF_RAID1:
634 if (!((conf->rlq == DDF_RAID1_SIMPLE && raiddisks == 2) ||
635 (conf->rlq == DDF_RAID1_MULTI && raiddisks == 3)))
636 return err_bad_ddf_layout(conf);
637 level = 1;
638 break;
639 case DDF_RAID4:
640 if (conf->rlq != DDF_RAID4_N)
641 return err_bad_ddf_layout(conf);
642 level = 4;
643 break;
644 case DDF_RAID5:
645 switch (conf->rlq) {
646 case DDF_RAID5_N_RESTART:
647 layout = ALGORITHM_LEFT_ASYMMETRIC;
648 break;
649 case DDF_RAID5_0_RESTART:
650 layout = ALGORITHM_RIGHT_ASYMMETRIC;
651 break;
652 case DDF_RAID5_N_CONTINUE:
653 layout = ALGORITHM_LEFT_SYMMETRIC;
654 break;
655 default:
656 return err_bad_ddf_layout(conf);
657 }
658 level = 5;
659 break;
660 case DDF_RAID6:
661 switch (conf->rlq) {
662 case DDF_RAID5_N_RESTART:
663 layout = ALGORITHM_ROTATING_N_RESTART;
664 break;
665 case DDF_RAID6_0_RESTART:
666 layout = ALGORITHM_ROTATING_ZERO_RESTART;
667 break;
668 case DDF_RAID5_N_CONTINUE:
669 layout = ALGORITHM_ROTATING_N_CONTINUE;
670 break;
671 default:
672 return err_bad_ddf_layout(conf);
673 }
674 level = 6;
675 break;
676 default:
677 return err_bad_ddf_layout(conf);
678 };
679
680good:
681 array->level = level;
682 array->layout = layout;
683 array->raid_disks = raiddisks;
684 return 0;
685}
686
a322f70c
DW
687static int load_ddf_header(int fd, unsigned long long lba,
688 unsigned long long size,
689 int type,
690 struct ddf_header *hdr, struct ddf_header *anchor)
691{
692 /* read a ddf header (primary or secondary) from fd/lba
693 * and check that it is consistent with anchor
694 * Need to check:
695 * magic, crc, guid, rev, and LBA's header_type, and
696 * everything after header_type must be the same
697 */
698 if (lba >= size-1)
699 return 0;
700
701 if (lseek64(fd, lba<<9, 0) < 0)
702 return 0;
703
704 if (read(fd, hdr, 512) != 512)
705 return 0;
706
707 if (hdr->magic != DDF_HEADER_MAGIC)
708 return 0;
709 if (calc_crc(hdr, 512) != hdr->crc)
710 return 0;
711 if (memcmp(anchor->guid, hdr->guid, DDF_GUID_LEN) != 0 ||
712 memcmp(anchor->revision, hdr->revision, 8) != 0 ||
713 anchor->primary_lba != hdr->primary_lba ||
714 anchor->secondary_lba != hdr->secondary_lba ||
715 hdr->type != type ||
716 memcmp(anchor->pad2, hdr->pad2, 512 -
717 offsetof(struct ddf_header, pad2)) != 0)
718 return 0;
719
720 /* Looks good enough to me... */
721 return 1;
722}
723
724static void *load_section(int fd, struct ddf_super *super, void *buf,
725 __u32 offset_be, __u32 len_be, int check)
726{
727 unsigned long long offset = __be32_to_cpu(offset_be);
728 unsigned long long len = __be32_to_cpu(len_be);
729 int dofree = (buf == NULL);
730
731 if (check)
732 if (len != 2 && len != 8 && len != 32
733 && len != 128 && len != 512)
734 return NULL;
735
736 if (len > 1024)
737 return NULL;
738 if (buf) {
739 /* All pre-allocated sections are a single block */
740 if (len != 1)
741 return NULL;
3d2c4fc7
DW
742 } else if (posix_memalign(&buf, 512, len<<9) != 0)
743 buf = NULL;
6416d527 744
a322f70c
DW
745 if (!buf)
746 return NULL;
747
748 if (super->active->type == 1)
749 offset += __be64_to_cpu(super->active->primary_lba);
750 else
751 offset += __be64_to_cpu(super->active->secondary_lba);
752
f21e18ca 753 if ((unsigned long long)lseek64(fd, offset<<9, 0) != (offset<<9)) {
a322f70c
DW
754 if (dofree)
755 free(buf);
756 return NULL;
757 }
f21e18ca 758 if ((unsigned long long)read(fd, buf, len<<9) != (len<<9)) {
a322f70c
DW
759 if (dofree)
760 free(buf);
761 return NULL;
762 }
763 return buf;
764}
765
766static int load_ddf_headers(int fd, struct ddf_super *super, char *devname)
767{
768 unsigned long long dsize;
769
770 get_dev_size(fd, NULL, &dsize);
771
772 if (lseek64(fd, dsize-512, 0) < 0) {
773 if (devname)
e7b84f9d
N
774 pr_err("Cannot seek to anchor block on %s: %s\n",
775 devname, strerror(errno));
a322f70c
DW
776 return 1;
777 }
778 if (read(fd, &super->anchor, 512) != 512) {
779 if (devname)
e7b84f9d
N
780 pr_err("Cannot read anchor block on %s: %s\n",
781 devname, strerror(errno));
a322f70c
DW
782 return 1;
783 }
784 if (super->anchor.magic != DDF_HEADER_MAGIC) {
785 if (devname)
e7b84f9d 786 pr_err("no DDF anchor found on %s\n",
a322f70c
DW
787 devname);
788 return 2;
789 }
790 if (calc_crc(&super->anchor, 512) != super->anchor.crc) {
791 if (devname)
e7b84f9d 792 pr_err("bad CRC on anchor on %s\n",
a322f70c
DW
793 devname);
794 return 2;
795 }
59e36268
NB
796 if (memcmp(super->anchor.revision, DDF_REVISION_0, 8) != 0 &&
797 memcmp(super->anchor.revision, DDF_REVISION_2, 8) != 0) {
a322f70c 798 if (devname)
e7b84f9d 799 pr_err("can only support super revision"
59e36268
NB
800 " %.8s and earlier, not %.8s on %s\n",
801 DDF_REVISION_2, super->anchor.revision,devname);
a322f70c
DW
802 return 2;
803 }
dbeb699a 804 super->active = NULL;
a322f70c
DW
805 if (load_ddf_header(fd, __be64_to_cpu(super->anchor.primary_lba),
806 dsize >> 9, 1,
807 &super->primary, &super->anchor) == 0) {
808 if (devname)
e7b84f9d
N
809 pr_err("Failed to load primary DDF header "
810 "on %s\n", devname);
dbeb699a 811 } else
812 super->active = &super->primary;
a322f70c
DW
813 if (load_ddf_header(fd, __be64_to_cpu(super->anchor.secondary_lba),
814 dsize >> 9, 2,
815 &super->secondary, &super->anchor)) {
816 if ((__be32_to_cpu(super->primary.seq)
817 < __be32_to_cpu(super->secondary.seq) &&
818 !super->secondary.openflag)
819 || (__be32_to_cpu(super->primary.seq)
820 == __be32_to_cpu(super->secondary.seq) &&
821 super->primary.openflag && !super->secondary.openflag)
dbeb699a 822 || super->active == NULL
a322f70c
DW
823 )
824 super->active = &super->secondary;
dbeb699a 825 } else if (devname)
826 pr_err("Failed to load secondary DDF header on %s\n",
827 devname);
828 if (super->active == NULL)
829 return 2;
a322f70c
DW
830 return 0;
831}
832
833static int load_ddf_global(int fd, struct ddf_super *super, char *devname)
834{
835 void *ok;
836 ok = load_section(fd, super, &super->controller,
837 super->active->controller_section_offset,
838 super->active->controller_section_length,
839 0);
840 super->phys = load_section(fd, super, NULL,
841 super->active->phys_section_offset,
842 super->active->phys_section_length,
843 1);
844 super->pdsize = __be32_to_cpu(super->active->phys_section_length) * 512;
845
846 super->virt = load_section(fd, super, NULL,
847 super->active->virt_section_offset,
848 super->active->virt_section_length,
849 1);
850 super->vdsize = __be32_to_cpu(super->active->virt_section_length) * 512;
851 if (!ok ||
852 !super->phys ||
853 !super->virt) {
854 free(super->phys);
855 free(super->virt);
a2349791
NB
856 super->phys = NULL;
857 super->virt = NULL;
a322f70c
DW
858 return 2;
859 }
860 super->conflist = NULL;
861 super->dlist = NULL;
8c3b8c2c
NB
862
863 super->max_part = __be16_to_cpu(super->active->max_partitions);
864 super->mppe = __be16_to_cpu(super->active->max_primary_element_entries);
865 super->conf_rec_len = __be16_to_cpu(super->active->config_record_len);
a322f70c
DW
866 return 0;
867}
868
3c48f7be 869#define DDF_UNUSED_BVD 0xff
870static int alloc_other_bvds(const struct ddf_super *ddf, struct vcl *vcl)
871{
872 unsigned int n_vds = vcl->conf.sec_elmnt_count - 1;
873 unsigned int i, vdsize;
874 void *p;
875 if (n_vds == 0) {
876 vcl->other_bvds = NULL;
877 return 0;
878 }
879 vdsize = ddf->conf_rec_len * 512;
880 if (posix_memalign(&p, 512, n_vds *
881 (vdsize + sizeof(struct vd_config *))) != 0)
882 return -1;
883 vcl->other_bvds = (struct vd_config **) (p + n_vds * vdsize);
884 for (i = 0; i < n_vds; i++) {
885 vcl->other_bvds[i] = p + i * vdsize;
886 memset(vcl->other_bvds[i], 0, vdsize);
887 vcl->other_bvds[i]->sec_elmnt_seq = DDF_UNUSED_BVD;
888 }
889 return 0;
890}
891
3dc821b0 892static void add_other_bvd(struct vcl *vcl, struct vd_config *vd,
893 unsigned int len)
894{
895 int i;
896 for (i = 0; i < vcl->conf.sec_elmnt_count-1; i++)
3c48f7be 897 if (vcl->other_bvds[i]->sec_elmnt_seq == vd->sec_elmnt_seq)
3dc821b0 898 break;
899
900 if (i < vcl->conf.sec_elmnt_count-1) {
901 if (vd->seqnum <= vcl->other_bvds[i]->seqnum)
902 return;
903 } else {
904 for (i = 0; i < vcl->conf.sec_elmnt_count-1; i++)
3c48f7be 905 if (vcl->other_bvds[i]->sec_elmnt_seq == DDF_UNUSED_BVD)
3dc821b0 906 break;
907 if (i == vcl->conf.sec_elmnt_count-1) {
908 pr_err("no space for sec level config %u, count is %u\n",
909 vd->sec_elmnt_seq, vcl->conf.sec_elmnt_count);
910 return;
911 }
3dc821b0 912 }
913 memcpy(vcl->other_bvds[i], vd, len);
914}
915
a322f70c
DW
916static int load_ddf_local(int fd, struct ddf_super *super,
917 char *devname, int keep)
918{
919 struct dl *dl;
920 struct stat stb;
921 char *conf;
f21e18ca
N
922 unsigned int i;
923 unsigned int confsec;
b2280677 924 int vnum;
f21e18ca 925 unsigned int max_virt_disks = __be16_to_cpu(super->active->max_vd_entries);
d2ca6449 926 unsigned long long dsize;
a322f70c
DW
927
928 /* First the local disk info */
3d2c4fc7 929 if (posix_memalign((void**)&dl, 512,
6416d527 930 sizeof(*dl) +
3d2c4fc7 931 (super->max_part) * sizeof(dl->vlist[0])) != 0) {
e7b84f9d 932 pr_err("%s could not allocate disk info buffer\n",
3d2c4fc7
DW
933 __func__);
934 return 1;
935 }
a322f70c
DW
936
937 load_section(fd, super, &dl->disk,
938 super->active->data_section_offset,
939 super->active->data_section_length,
940 0);
503975b9 941 dl->devname = devname ? xstrdup(devname) : NULL;
598f0d58 942
a322f70c
DW
943 fstat(fd, &stb);
944 dl->major = major(stb.st_rdev);
945 dl->minor = minor(stb.st_rdev);
946 dl->next = super->dlist;
947 dl->fd = keep ? fd : -1;
d2ca6449
NB
948
949 dl->size = 0;
950 if (get_dev_size(fd, devname, &dsize))
951 dl->size = dsize >> 9;
097bcf00 952 /* If the disks have different sizes, the LBAs will differ
953 * between phys disks.
954 * At this point here, the values in super->active must be valid
955 * for this phys disk. */
956 dl->primary_lba = super->active->primary_lba;
957 dl->secondary_lba = super->active->secondary_lba;
958 dl->workspace_lba = super->active->workspace_lba;
b2280677 959 dl->spare = NULL;
f21e18ca 960 for (i = 0 ; i < super->max_part ; i++)
a322f70c
DW
961 dl->vlist[i] = NULL;
962 super->dlist = dl;
59e36268 963 dl->pdnum = -1;
f21e18ca 964 for (i = 0; i < __be16_to_cpu(super->active->max_pd_entries); i++)
5575e7d9
NB
965 if (memcmp(super->phys->entries[i].guid,
966 dl->disk.guid, DDF_GUID_LEN) == 0)
967 dl->pdnum = i;
968
a322f70c
DW
969 /* Now the config list. */
970 /* 'conf' is an array of config entries, some of which are
971 * probably invalid. Those which are good need to be copied into
972 * the conflist
973 */
a322f70c
DW
974
975 conf = load_section(fd, super, NULL,
976 super->active->config_section_offset,
977 super->active->config_section_length,
978 0);
979
b2280677 980 vnum = 0;
e223334f
N
981 for (confsec = 0;
982 confsec < __be32_to_cpu(super->active->config_section_length);
983 confsec += super->conf_rec_len) {
a322f70c 984 struct vd_config *vd =
e223334f 985 (struct vd_config *)((char*)conf + confsec*512);
a322f70c
DW
986 struct vcl *vcl;
987
b2280677
NB
988 if (vd->magic == DDF_SPARE_ASSIGN_MAGIC) {
989 if (dl->spare)
990 continue;
3d2c4fc7
DW
991 if (posix_memalign((void**)&dl->spare, 512,
992 super->conf_rec_len*512) != 0) {
e7b84f9d
N
993 pr_err("%s could not allocate spare info buf\n",
994 __func__);
3d2c4fc7
DW
995 return 1;
996 }
613b0d17 997
b2280677
NB
998 memcpy(dl->spare, vd, super->conf_rec_len*512);
999 continue;
1000 }
a322f70c
DW
1001 if (vd->magic != DDF_VD_CONF_MAGIC)
1002 continue;
1003 for (vcl = super->conflist; vcl; vcl = vcl->next) {
1004 if (memcmp(vcl->conf.guid,
1005 vd->guid, DDF_GUID_LEN) == 0)
1006 break;
1007 }
1008
1009 if (vcl) {
b2280677 1010 dl->vlist[vnum++] = vcl;
3dc821b0 1011 if (vcl->other_bvds != NULL &&
1012 vcl->conf.sec_elmnt_seq != vd->sec_elmnt_seq) {
1013 add_other_bvd(vcl, vd, super->conf_rec_len*512);
1014 continue;
1015 }
a322f70c
DW
1016 if (__be32_to_cpu(vd->seqnum) <=
1017 __be32_to_cpu(vcl->conf.seqnum))
1018 continue;
59e36268 1019 } else {
3d2c4fc7 1020 if (posix_memalign((void**)&vcl, 512,
6416d527 1021 (super->conf_rec_len*512 +
3d2c4fc7 1022 offsetof(struct vcl, conf))) != 0) {
e7b84f9d
N
1023 pr_err("%s could not allocate vcl buf\n",
1024 __func__);
3d2c4fc7
DW
1025 return 1;
1026 }
a322f70c 1027 vcl->next = super->conflist;
59e36268 1028 vcl->block_sizes = NULL; /* FIXME not for CONCAT */
3c48f7be 1029 vcl->conf.sec_elmnt_count = vd->sec_elmnt_count;
1030 if (alloc_other_bvds(super, vcl) != 0) {
1031 pr_err("%s could not allocate other bvds\n",
1032 __func__);
1033 free(vcl);
1034 return 1;
1035 };
a322f70c 1036 super->conflist = vcl;
b2280677 1037 dl->vlist[vnum++] = vcl;
a322f70c 1038 }
8c3b8c2c 1039 memcpy(&vcl->conf, vd, super->conf_rec_len*512);
a322f70c 1040 vcl->lba_offset = (__u64*)
8c3b8c2c 1041 &vcl->conf.phys_refnum[super->mppe];
59e36268
NB
1042
1043 for (i=0; i < max_virt_disks ; i++)
1044 if (memcmp(super->virt->entries[i].guid,
1045 vcl->conf.guid, DDF_GUID_LEN)==0)
1046 break;
1047 if (i < max_virt_disks)
1048 vcl->vcnum = i;
a322f70c
DW
1049 }
1050 free(conf);
1051
1052 return 0;
1053}
1054
1055#ifndef MDASSEMBLE
1056static int load_super_ddf_all(struct supertype *st, int fd,
e1902a7b 1057 void **sbp, char *devname);
a322f70c 1058#endif
37424f13
DW
1059
1060static void free_super_ddf(struct supertype *st);
1061
a322f70c
DW
1062static int load_super_ddf(struct supertype *st, int fd,
1063 char *devname)
1064{
1065 unsigned long long dsize;
1066 struct ddf_super *super;
1067 int rv;
1068
a322f70c
DW
1069 if (get_dev_size(fd, devname, &dsize) == 0)
1070 return 1;
1071
b31df436 1072 if (!st->ignore_hw_compat && test_partition(fd))
691c6ee1
N
1073 /* DDF is not allowed on partitions */
1074 return 1;
1075
a322f70c
DW
1076 /* 32M is a lower bound */
1077 if (dsize <= 32*1024*1024) {
97320d7c 1078 if (devname)
e7b84f9d
N
1079 pr_err("%s is too small for ddf: "
1080 "size is %llu sectors.\n",
1081 devname, dsize>>9);
97320d7c 1082 return 1;
a322f70c
DW
1083 }
1084 if (dsize & 511) {
97320d7c 1085 if (devname)
e7b84f9d
N
1086 pr_err("%s is an odd size for ddf: "
1087 "size is %llu bytes.\n",
1088 devname, dsize);
97320d7c 1089 return 1;
a322f70c
DW
1090 }
1091
37424f13
DW
1092 free_super_ddf(st);
1093
6416d527 1094 if (posix_memalign((void**)&super, 512, sizeof(*super))!= 0) {
e7b84f9d 1095 pr_err("malloc of %zu failed.\n",
a322f70c
DW
1096 sizeof(*super));
1097 return 1;
1098 }
a2349791 1099 memset(super, 0, sizeof(*super));
a322f70c
DW
1100
1101 rv = load_ddf_headers(fd, super, devname);
1102 if (rv) {
1103 free(super);
1104 return rv;
1105 }
1106
1107 /* Have valid headers and have chosen the best. Let's read in the rest*/
1108
1109 rv = load_ddf_global(fd, super, devname);
1110
1111 if (rv) {
1112 if (devname)
e7b84f9d
N
1113 pr_err("Failed to load all information "
1114 "sections on %s\n", devname);
a322f70c
DW
1115 free(super);
1116 return rv;
1117 }
1118
3d2c4fc7
DW
1119 rv = load_ddf_local(fd, super, devname, 0);
1120
1121 if (rv) {
1122 if (devname)
e7b84f9d
N
1123 pr_err("Failed to load all information "
1124 "sections on %s\n", devname);
3d2c4fc7
DW
1125 free(super);
1126 return rv;
1127 }
a322f70c
DW
1128
1129 /* Should possibly check the sections .... */
1130
1131 st->sb = super;
1132 if (st->ss == NULL) {
1133 st->ss = &super_ddf;
1134 st->minor_version = 0;
1135 st->max_devs = 512;
1136 }
1137 return 0;
1138
1139}
1140
1141static void free_super_ddf(struct supertype *st)
1142{
1143 struct ddf_super *ddf = st->sb;
1144 if (ddf == NULL)
1145 return;
1146 free(ddf->phys);
1147 free(ddf->virt);
1148 while (ddf->conflist) {
1149 struct vcl *v = ddf->conflist;
1150 ddf->conflist = v->next;
59e36268
NB
1151 if (v->block_sizes)
1152 free(v->block_sizes);
3c48f7be 1153 if (v->other_bvds)
1154 /*
1155 v->other_bvds[0] points to beginning of buffer,
1156 see alloc_other_bvds()
1157 */
1158 free(v->other_bvds[0]);
a322f70c
DW
1159 free(v);
1160 }
1161 while (ddf->dlist) {
1162 struct dl *d = ddf->dlist;
1163 ddf->dlist = d->next;
1164 if (d->fd >= 0)
1165 close(d->fd);
b2280677
NB
1166 if (d->spare)
1167 free(d->spare);
a322f70c
DW
1168 free(d);
1169 }
8a38cb04
N
1170 while (ddf->add_list) {
1171 struct dl *d = ddf->add_list;
1172 ddf->add_list = d->next;
1173 if (d->fd >= 0)
1174 close(d->fd);
1175 if (d->spare)
1176 free(d->spare);
1177 free(d);
1178 }
a322f70c
DW
1179 free(ddf);
1180 st->sb = NULL;
1181}
1182
1183static struct supertype *match_metadata_desc_ddf(char *arg)
1184{
1185 /* 'ddf' only support containers */
1186 struct supertype *st;
1187 if (strcmp(arg, "ddf") != 0 &&
1188 strcmp(arg, "default") != 0
1189 )
1190 return NULL;
1191
503975b9 1192 st = xcalloc(1, sizeof(*st));
a322f70c
DW
1193 st->ss = &super_ddf;
1194 st->max_devs = 512;
1195 st->minor_version = 0;
1196 st->sb = NULL;
1197 return st;
1198}
1199
a322f70c
DW
1200#ifndef MDASSEMBLE
1201
1202static mapping_t ddf_state[] = {
1203 { "Optimal", 0},
1204 { "Degraded", 1},
1205 { "Deleted", 2},
1206 { "Missing", 3},
1207 { "Failed", 4},
1208 { "Partially Optimal", 5},
1209 { "-reserved-", 6},
1210 { "-reserved-", 7},
1211 { NULL, 0}
1212};
1213
1214static mapping_t ddf_init_state[] = {
1215 { "Not Initialised", 0},
1216 { "QuickInit in Progress", 1},
1217 { "Fully Initialised", 2},
1218 { "*UNKNOWN*", 3},
1219 { NULL, 0}
1220};
1221static mapping_t ddf_access[] = {
1222 { "Read/Write", 0},
1223 { "Reserved", 1},
1224 { "Read Only", 2},
1225 { "Blocked (no access)", 3},
1226 { NULL ,0}
1227};
1228
1229static mapping_t ddf_level[] = {
1230 { "RAID0", DDF_RAID0},
1231 { "RAID1", DDF_RAID1},
1232 { "RAID3", DDF_RAID3},
1233 { "RAID4", DDF_RAID4},
1234 { "RAID5", DDF_RAID5},
1235 { "RAID1E",DDF_RAID1E},
1236 { "JBOD", DDF_JBOD},
1237 { "CONCAT",DDF_CONCAT},
1238 { "RAID5E",DDF_RAID5E},
1239 { "RAID5EE",DDF_RAID5EE},
1240 { "RAID6", DDF_RAID6},
1241 { NULL, 0}
1242};
1243static mapping_t ddf_sec_level[] = {
1244 { "Striped", DDF_2STRIPED},
1245 { "Mirrored", DDF_2MIRRORED},
1246 { "Concat", DDF_2CONCAT},
1247 { "Spanned", DDF_2SPANNED},
1248 { NULL, 0}
1249};
1250#endif
1251
fb9d0acb 1252static int all_ff(const char *guid)
42dc2744
N
1253{
1254 int i;
1255 for (i = 0; i < DDF_GUID_LEN; i++)
1256 if (guid[i] != (char)0xff)
1257 return 0;
1258 return 1;
1259}
1260
a322f70c
DW
1261#ifndef MDASSEMBLE
1262static void print_guid(char *guid, int tstamp)
1263{
1264 /* A GUIDs are part (or all) ASCII and part binary.
1265 * They tend to be space padded.
59e36268
NB
1266 * We print the GUID in HEX, then in parentheses add
1267 * any initial ASCII sequence, and a possible
1268 * time stamp from bytes 16-19
a322f70c
DW
1269 */
1270 int l = DDF_GUID_LEN;
1271 int i;
59e36268
NB
1272
1273 for (i=0 ; i<DDF_GUID_LEN ; i++) {
1274 if ((i&3)==0 && i != 0) printf(":");
1275 printf("%02X", guid[i]&255);
1276 }
1277
cfccea8c 1278 printf("\n (");
a322f70c
DW
1279 while (l && guid[l-1] == ' ')
1280 l--;
1281 for (i=0 ; i<l ; i++) {
1282 if (guid[i] >= 0x20 && guid[i] < 0x7f)
1283 fputc(guid[i], stdout);
1284 else
59e36268 1285 break;
a322f70c
DW
1286 }
1287 if (tstamp) {
1288 time_t then = __be32_to_cpu(*(__u32*)(guid+16)) + DECADE;
1289 char tbuf[100];
1290 struct tm *tm;
1291 tm = localtime(&then);
59e36268 1292 strftime(tbuf, 100, " %D %T",tm);
a322f70c
DW
1293 fputs(tbuf, stdout);
1294 }
59e36268 1295 printf(")");
a322f70c
DW
1296}
1297
1298static void examine_vd(int n, struct ddf_super *sb, char *guid)
1299{
8c3b8c2c 1300 int crl = sb->conf_rec_len;
a322f70c
DW
1301 struct vcl *vcl;
1302
1303 for (vcl = sb->conflist ; vcl ; vcl = vcl->next) {
f21e18ca 1304 unsigned int i;
a322f70c
DW
1305 struct vd_config *vc = &vcl->conf;
1306
1307 if (calc_crc(vc, crl*512) != vc->crc)
1308 continue;
1309 if (memcmp(vc->guid, guid, DDF_GUID_LEN) != 0)
1310 continue;
1311
1312 /* Ok, we know about this VD, let's give more details */
b06e3095 1313 printf(" Raid Devices[%d] : %d (", n,
a322f70c 1314 __be16_to_cpu(vc->prim_elmnt_count));
f21e18ca 1315 for (i = 0; i < __be16_to_cpu(vc->prim_elmnt_count); i++) {
b06e3095
N
1316 int j;
1317 int cnt = __be16_to_cpu(sb->phys->used_pdes);
1318 for (j=0; j<cnt; j++)
1319 if (vc->phys_refnum[i] == sb->phys->entries[j].refnum)
1320 break;
1321 if (i) printf(" ");
1322 if (j < cnt)
1323 printf("%d", j);
1324 else
1325 printf("--");
1326 }
1327 printf(")\n");
1328 if (vc->chunk_shift != 255)
613b0d17
N
1329 printf(" Chunk Size[%d] : %d sectors\n", n,
1330 1 << vc->chunk_shift);
a322f70c
DW
1331 printf(" Raid Level[%d] : %s\n", n,
1332 map_num(ddf_level, vc->prl)?:"-unknown-");
1333 if (vc->sec_elmnt_count != 1) {
1334 printf(" Secondary Position[%d] : %d of %d\n", n,
1335 vc->sec_elmnt_seq, vc->sec_elmnt_count);
1336 printf(" Secondary Level[%d] : %s\n", n,
1337 map_num(ddf_sec_level, vc->srl) ?: "-unknown-");
1338 }
1339 printf(" Device Size[%d] : %llu\n", n,
c9b6907b 1340 (unsigned long long)__be64_to_cpu(vc->blocks)/2);
a322f70c 1341 printf(" Array Size[%d] : %llu\n", n,
c9b6907b 1342 (unsigned long long)__be64_to_cpu(vc->array_blocks)/2);
a322f70c
DW
1343 }
1344}
1345
1346static void examine_vds(struct ddf_super *sb)
1347{
1348 int cnt = __be16_to_cpu(sb->virt->populated_vdes);
fb9d0acb 1349 unsigned int i;
a322f70c
DW
1350 printf(" Virtual Disks : %d\n", cnt);
1351
fb9d0acb 1352 for (i = 0; i < __be16_to_cpu(sb->virt->max_vdes); i++) {
a322f70c 1353 struct virtual_entry *ve = &sb->virt->entries[i];
fb9d0acb 1354 if (all_ff(ve->guid))
1355 continue;
b06e3095 1356 printf("\n");
a322f70c
DW
1357 printf(" VD GUID[%d] : ", i); print_guid(ve->guid, 1);
1358 printf("\n");
1359 printf(" unit[%d] : %d\n", i, __be16_to_cpu(ve->unit));
1360 printf(" state[%d] : %s, %s%s\n", i,
1361 map_num(ddf_state, ve->state & 7),
1362 (ve->state & 8) ? "Morphing, ": "",
1363 (ve->state & 16)? "Not Consistent" : "Consistent");
1364 printf(" init state[%d] : %s\n", i,
1365 map_num(ddf_init_state, ve->init_state&3));
1366 printf(" access[%d] : %s\n", i,
1367 map_num(ddf_access, (ve->init_state>>6) & 3));
1368 printf(" Name[%d] : %.16s\n", i, ve->name);
1369 examine_vd(i, sb, ve->guid);
1370 }
1371 if (cnt) printf("\n");
1372}
1373
1374static void examine_pds(struct ddf_super *sb)
1375{
1376 int cnt = __be16_to_cpu(sb->phys->used_pdes);
1377 int i;
1378 struct dl *dl;
1379 printf(" Physical Disks : %d\n", cnt);
962371a5 1380 printf(" Number RefNo Size Device Type/State\n");
a322f70c
DW
1381
1382 for (i=0 ; i<cnt ; i++) {
1383 struct phys_disk_entry *pd = &sb->phys->entries[i];
1384 int type = __be16_to_cpu(pd->type);
1385 int state = __be16_to_cpu(pd->state);
1386
b06e3095
N
1387 //printf(" PD GUID[%d] : ", i); print_guid(pd->guid, 0);
1388 //printf("\n");
1389 printf(" %3d %08x ", i,
a322f70c 1390 __be32_to_cpu(pd->refnum));
613b0d17 1391 printf("%8lluK ",
c9b6907b 1392 (unsigned long long)__be64_to_cpu(pd->config_size)>>1);
b06e3095
N
1393 for (dl = sb->dlist; dl ; dl = dl->next) {
1394 if (dl->disk.refnum == pd->refnum) {
1395 char *dv = map_dev(dl->major, dl->minor, 0);
1396 if (dv) {
962371a5 1397 printf("%-15s", dv);
b06e3095
N
1398 break;
1399 }
1400 }
1401 }
1402 if (!dl)
962371a5 1403 printf("%15s","");
b06e3095 1404 printf(" %s%s%s%s%s",
a322f70c 1405 (type&2) ? "active":"",
b06e3095 1406 (type&4) ? "Global-Spare":"",
a322f70c
DW
1407 (type&8) ? "spare" : "",
1408 (type&16)? ", foreign" : "",
1409 (type&32)? "pass-through" : "");
18cb4496
N
1410 if (state & DDF_Failed)
1411 /* This over-rides these three */
1412 state &= ~(DDF_Online|DDF_Rebuilding|DDF_Transition);
b06e3095 1413 printf("/%s%s%s%s%s%s%s",
a322f70c
DW
1414 (state&1)? "Online": "Offline",
1415 (state&2)? ", Failed": "",
1416 (state&4)? ", Rebuilding": "",
1417 (state&8)? ", in-transition": "",
b06e3095
N
1418 (state&16)? ", SMART-errors": "",
1419 (state&32)? ", Unrecovered-Read-Errors": "",
a322f70c 1420 (state&64)? ", Missing" : "");
a322f70c
DW
1421 printf("\n");
1422 }
1423}
1424
1425static void examine_super_ddf(struct supertype *st, char *homehost)
1426{
1427 struct ddf_super *sb = st->sb;
1428
1429 printf(" Magic : %08x\n", __be32_to_cpu(sb->anchor.magic));
1430 printf(" Version : %.8s\n", sb->anchor.revision);
598f0d58
NB
1431 printf("Controller GUID : "); print_guid(sb->controller.guid, 0);
1432 printf("\n");
1433 printf(" Container GUID : "); print_guid(sb->anchor.guid, 1);
a322f70c
DW
1434 printf("\n");
1435 printf(" Seq : %08x\n", __be32_to_cpu(sb->active->seq));
1436 printf(" Redundant hdr : %s\n", sb->secondary.magic == DDF_HEADER_MAGIC
1437 ?"yes" : "no");
1438 examine_vds(sb);
1439 examine_pds(sb);
1440}
1441
a5d85af7 1442static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info, char *map);
ff54de6e 1443
bedbf68a 1444static void uuid_from_ddf_guid(const char *guid, int uuid[4]);
42dc2744 1445static void uuid_from_super_ddf(struct supertype *st, int uuid[4]);
ff54de6e 1446
bedbf68a 1447static unsigned int get_vd_num_of_subarray(struct supertype *st)
1448{
1449 /*
1450 * Figure out the VD number for this supertype.
1451 * Returns DDF_CONTAINER for the container itself,
1452 * and DDF_NOTFOUND on error.
1453 */
1454 struct ddf_super *ddf = st->sb;
1455 struct mdinfo *sra;
1456 char *sub, *end;
1457 unsigned int vcnum;
1458
1459 if (*st->container_devnm == '\0')
1460 return DDF_CONTAINER;
1461
1462 sra = sysfs_read(-1, st->devnm, GET_VERSION);
1463 if (!sra || sra->array.major_version != -1 ||
1464 sra->array.minor_version != -2 ||
1465 !is_subarray(sra->text_version))
1466 return DDF_NOTFOUND;
1467
1468 sub = strchr(sra->text_version + 1, '/');
1469 if (sub != NULL)
1470 vcnum = strtoul(sub + 1, &end, 10);
1471 if (sub == NULL || *sub == '\0' || *end != '\0' ||
1472 vcnum >= __be16_to_cpu(ddf->active->max_vd_entries))
1473 return DDF_NOTFOUND;
1474
1475 return vcnum;
1476}
1477
061f2c6a 1478static void brief_examine_super_ddf(struct supertype *st, int verbose)
4737ae25
N
1479{
1480 /* We just write a generic DDF ARRAY entry
1481 */
1482 struct mdinfo info;
1483 char nbuf[64];
a5d85af7 1484 getinfo_super_ddf(st, &info, NULL);
4737ae25
N
1485 fname_from_uuid(st, &info, nbuf, ':');
1486
1487 printf("ARRAY metadata=ddf UUID=%s\n", nbuf + 5);
1488}
1489
1490static void brief_examine_subarrays_ddf(struct supertype *st, int verbose)
a322f70c
DW
1491{
1492 /* We just write a generic DDF ARRAY entry
a322f70c 1493 */
42dc2744 1494 struct ddf_super *ddf = st->sb;
ff54de6e 1495 struct mdinfo info;
f21e18ca 1496 unsigned int i;
ff54de6e 1497 char nbuf[64];
a5d85af7 1498 getinfo_super_ddf(st, &info, NULL);
ff54de6e 1499 fname_from_uuid(st, &info, nbuf, ':');
42dc2744 1500
f21e18ca 1501 for (i = 0; i < __be16_to_cpu(ddf->virt->max_vdes); i++) {
42dc2744
N
1502 struct virtual_entry *ve = &ddf->virt->entries[i];
1503 struct vcl vcl;
1504 char nbuf1[64];
1505 if (all_ff(ve->guid))
1506 continue;
1507 memcpy(vcl.conf.guid, ve->guid, DDF_GUID_LEN);
1508 ddf->currentconf =&vcl;
1509 uuid_from_super_ddf(st, info.uuid);
1510 fname_from_uuid(st, &info, nbuf1, ':');
1511 printf("ARRAY container=%s member=%d UUID=%s\n",
1512 nbuf+5, i, nbuf1+5);
1513 }
a322f70c
DW
1514}
1515
bceedeec
N
1516static void export_examine_super_ddf(struct supertype *st)
1517{
1518 struct mdinfo info;
1519 char nbuf[64];
a5d85af7 1520 getinfo_super_ddf(st, &info, NULL);
bceedeec
N
1521 fname_from_uuid(st, &info, nbuf, ':');
1522 printf("MD_METADATA=ddf\n");
1523 printf("MD_LEVEL=container\n");
1524 printf("MD_UUID=%s\n", nbuf+5);
1525}
bceedeec 1526
74db60b0
N
1527static int copy_metadata_ddf(struct supertype *st, int from, int to)
1528{
1529 void *buf;
1530 unsigned long long dsize, offset;
1531 int bytes;
1532 struct ddf_header *ddf;
1533 int written = 0;
1534
1535 /* The meta consists of an anchor, a primary, and a secondary.
1536 * This all lives at the end of the device.
1537 * So it is easiest to find the earliest of primary and
1538 * secondary, and copy everything from there.
1539 *
1540 * Anchor is 512 from end It contains primary_lba and secondary_lba
1541 * we choose one of those
1542 */
1543
1544 if (posix_memalign(&buf, 4096, 4096) != 0)
1545 return 1;
1546
1547 if (!get_dev_size(from, NULL, &dsize))
1548 goto err;
1549
1550 if (lseek64(from, dsize-512, 0) < 0)
1551 goto err;
1552 if (read(from, buf, 512) != 512)
1553 goto err;
1554 ddf = buf;
1555 if (ddf->magic != DDF_HEADER_MAGIC ||
1556 calc_crc(ddf, 512) != ddf->crc ||
1557 (memcmp(ddf->revision, DDF_REVISION_0, 8) != 0 &&
1558 memcmp(ddf->revision, DDF_REVISION_2, 8) != 0))
1559 goto err;
1560
1561 offset = dsize - 512;
1562 if ((__be64_to_cpu(ddf->primary_lba) << 9) < offset)
1563 offset = __be64_to_cpu(ddf->primary_lba) << 9;
1564 if ((__be64_to_cpu(ddf->secondary_lba) << 9) < offset)
1565 offset = __be64_to_cpu(ddf->secondary_lba) << 9;
1566
1567 bytes = dsize - offset;
1568
1569 if (lseek64(from, offset, 0) < 0 ||
1570 lseek64(to, offset, 0) < 0)
1571 goto err;
1572 while (written < bytes) {
1573 int n = bytes - written;
1574 if (n > 4096)
1575 n = 4096;
1576 if (read(from, buf, n) != n)
1577 goto err;
1578 if (write(to, buf, n) != n)
1579 goto err;
1580 written += n;
1581 }
1582 free(buf);
1583 return 0;
1584err:
1585 free(buf);
1586 return 1;
1587}
1588
a322f70c
DW
1589static void detail_super_ddf(struct supertype *st, char *homehost)
1590{
1591 /* FIXME later
1592 * Could print DDF GUID
1593 * Need to find which array
1594 * If whole, briefly list all arrays
1595 * If one, give name
1596 */
1597}
1598
1599static void brief_detail_super_ddf(struct supertype *st)
1600{
ff54de6e
N
1601 struct mdinfo info;
1602 char nbuf[64];
bedbf68a 1603 struct ddf_super *ddf = st->sb;
1604 unsigned int vcnum = get_vd_num_of_subarray(st);
1605 if (vcnum == DDF_CONTAINER)
1606 uuid_from_super_ddf(st, info.uuid);
1607 else if (vcnum == DDF_NOTFOUND)
1608 return;
1609 else
1610 uuid_from_ddf_guid(ddf->virt->entries[vcnum].guid, info.uuid);
ff54de6e
N
1611 fname_from_uuid(st, &info, nbuf,':');
1612 printf(" UUID=%s", nbuf + 5);
a322f70c 1613}
a322f70c
DW
1614#endif
1615
1616static int match_home_ddf(struct supertype *st, char *homehost)
1617{
1618 /* It matches 'this' host if the controller is a
1619 * Linux-MD controller with vendor_data matching
1620 * the hostname
1621 */
1622 struct ddf_super *ddf = st->sb;
f21e18ca 1623 unsigned int len;
d1d3482b
N
1624
1625 if (!homehost)
1626 return 0;
1627 len = strlen(homehost);
a322f70c
DW
1628
1629 return (memcmp(ddf->controller.guid, T10, 8) == 0 &&
1630 len < sizeof(ddf->controller.vendor_data) &&
1631 memcmp(ddf->controller.vendor_data, homehost,len) == 0 &&
1632 ddf->controller.vendor_data[len] == 0);
1633}
1634
0e600426 1635#ifndef MDASSEMBLE
baba3f4e 1636static int find_index_in_bvd(const struct ddf_super *ddf,
1637 const struct vd_config *conf, unsigned int n,
1638 unsigned int *n_bvd)
1639{
1640 /*
1641 * Find the index of the n-th valid physical disk in this BVD
1642 */
1643 unsigned int i, j;
1644 for (i = 0, j = 0; i < ddf->mppe &&
1645 j < __be16_to_cpu(conf->prim_elmnt_count); i++) {
1646 if (conf->phys_refnum[i] != 0xffffffff) {
1647 if (n == j) {
1648 *n_bvd = i;
1649 return 1;
1650 }
1651 j++;
1652 }
1653 }
1654 dprintf("%s: couldn't find BVD member %u (total %u)\n",
1655 __func__, n, __be16_to_cpu(conf->prim_elmnt_count));
1656 return 0;
1657}
1658
1659static struct vd_config *find_vdcr(struct ddf_super *ddf, unsigned int inst,
1660 unsigned int n,
1661 unsigned int *n_bvd, struct vcl **vcl)
a322f70c 1662{
7a7cc504 1663 struct vcl *v;
59e36268 1664
baba3f4e 1665 for (v = ddf->conflist; v; v = v->next) {
1666 unsigned int nsec, ibvd;
1667 struct vd_config *conf;
1668 if (inst != v->vcnum)
1669 continue;
1670 conf = &v->conf;
1671 if (conf->sec_elmnt_count == 1) {
1672 if (find_index_in_bvd(ddf, conf, n, n_bvd)) {
1673 *vcl = v;
1674 return conf;
1675 } else
1676 goto bad;
1677 }
1678 if (v->other_bvds == NULL) {
1679 pr_err("%s: BUG: other_bvds is NULL, nsec=%u\n",
1680 __func__, conf->sec_elmnt_count);
1681 goto bad;
1682 }
1683 nsec = n / __be16_to_cpu(conf->prim_elmnt_count);
1684 if (conf->sec_elmnt_seq != nsec) {
1685 for (ibvd = 1; ibvd < conf->sec_elmnt_count; ibvd++) {
baba3f4e 1686 if (v->other_bvds[ibvd-1]->sec_elmnt_seq
1687 == nsec)
1688 break;
1689 }
1690 if (ibvd == conf->sec_elmnt_count)
1691 goto bad;
1692 conf = v->other_bvds[ibvd-1];
1693 }
1694 if (!find_index_in_bvd(ddf, conf,
1695 n - nsec*conf->sec_elmnt_count, n_bvd))
1696 goto bad;
1697 dprintf("%s: found disk %u as member %u in bvd %d of array %u\n"
1698 , __func__, n, *n_bvd, ibvd-1, inst);
1699 *vcl = v;
1700 return conf;
1701 }
1702bad:
1703 pr_err("%s: Could't find disk %d in array %u\n", __func__, n, inst);
7a7cc504
NB
1704 return NULL;
1705}
0e600426 1706#endif
7a7cc504 1707
5ec636b7 1708static int find_phys(const struct ddf_super *ddf, __u32 phys_refnum)
7a7cc504
NB
1709{
1710 /* Find the entry in phys_disk which has the given refnum
1711 * and return it's index
1712 */
f21e18ca
N
1713 unsigned int i;
1714 for (i = 0; i < __be16_to_cpu(ddf->phys->max_pdes); i++)
7a7cc504
NB
1715 if (ddf->phys->entries[i].refnum == phys_refnum)
1716 return i;
1717 return -1;
a322f70c
DW
1718}
1719
bedbf68a 1720static void uuid_from_ddf_guid(const char *guid, int uuid[4])
1721{
1722 char buf[20];
1723 struct sha1_ctx ctx;
1724 sha1_init_ctx(&ctx);
1725 sha1_process_bytes(guid, DDF_GUID_LEN, &ctx);
1726 sha1_finish_ctx(&ctx, buf);
1727 memcpy(uuid, buf, 4*4);
1728}
1729
a322f70c
DW
1730static void uuid_from_super_ddf(struct supertype *st, int uuid[4])
1731{
1732 /* The uuid returned here is used for:
1733 * uuid to put into bitmap file (Create, Grow)
1734 * uuid for backup header when saving critical section (Grow)
1735 * comparing uuids when re-adding a device into an array
51006d85
N
1736 * In these cases the uuid required is that of the data-array,
1737 * not the device-set.
1738 * uuid to recognise same set when adding a missing device back
1739 * to an array. This is a uuid for the device-set.
613b0d17 1740 *
a322f70c
DW
1741 * For each of these we can make do with a truncated
1742 * or hashed uuid rather than the original, as long as
1743 * everyone agrees.
a322f70c
DW
1744 * In the case of SVD we assume the BVD is of interest,
1745 * though that might be the case if a bitmap were made for
1746 * a mirrored SVD - worry about that later.
1747 * So we need to find the VD configuration record for the
1748 * relevant BVD and extract the GUID and Secondary_Element_Seq.
1749 * The first 16 bytes of the sha1 of these is used.
1750 */
1751 struct ddf_super *ddf = st->sb;
d2ca6449 1752 struct vcl *vcl = ddf->currentconf;
c5afc314 1753 char *guid;
a322f70c 1754
c5afc314
N
1755 if (vcl)
1756 guid = vcl->conf.guid;
1757 else
1758 guid = ddf->anchor.guid;
bedbf68a 1759 uuid_from_ddf_guid(guid, uuid);
a322f70c
DW
1760}
1761
a5d85af7 1762static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info, char *map);
78e44928 1763
a5d85af7 1764static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info, char *map)
a322f70c
DW
1765{
1766 struct ddf_super *ddf = st->sb;
a5d85af7 1767 int map_disks = info->array.raid_disks;
90fa1a29 1768 __u32 *cptr;
a322f70c 1769
78e44928 1770 if (ddf->currentconf) {
a5d85af7 1771 getinfo_super_ddf_bvd(st, info, map);
78e44928
NB
1772 return;
1773 }
95eeceeb 1774 memset(info, 0, sizeof(*info));
78e44928 1775
a322f70c
DW
1776 info->array.raid_disks = __be16_to_cpu(ddf->phys->used_pdes);
1777 info->array.level = LEVEL_CONTAINER;
1778 info->array.layout = 0;
1779 info->array.md_minor = -1;
90fa1a29
JS
1780 cptr = (__u32 *)(ddf->anchor.guid + 16);
1781 info->array.ctime = DECADE + __be32_to_cpu(*cptr);
1782
a322f70c
DW
1783 info->array.utime = 0;
1784 info->array.chunk_size = 0;
510242aa 1785 info->container_enough = 1;
a322f70c 1786
a322f70c
DW
1787 info->disk.major = 0;
1788 info->disk.minor = 0;
cba0191b
NB
1789 if (ddf->dlist) {
1790 info->disk.number = __be32_to_cpu(ddf->dlist->disk.refnum);
59e36268 1791 info->disk.raid_disk = find_phys(ddf, ddf->dlist->disk.refnum);
d2ca6449
NB
1792
1793 info->data_offset = __be64_to_cpu(ddf->phys->
613b0d17
N
1794 entries[info->disk.raid_disk].
1795 config_size);
d2ca6449 1796 info->component_size = ddf->dlist->size - info->data_offset;
cba0191b
NB
1797 } else {
1798 info->disk.number = -1;
661dce36 1799 info->disk.raid_disk = -1;
cba0191b
NB
1800// info->disk.raid_disk = find refnum in the table and use index;
1801 }
f22385f9 1802 info->disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE);
a19c88b8 1803
921d9e16 1804 info->recovery_start = MaxSector;
a19c88b8 1805 info->reshape_active = 0;
6e75048b 1806 info->recovery_blocked = 0;
c5afc314 1807 info->name[0] = 0;
a322f70c 1808
f35f2525
N
1809 info->array.major_version = -1;
1810 info->array.minor_version = -2;
159c3a1a 1811 strcpy(info->text_version, "ddf");
a67dd8cc 1812 info->safe_mode_delay = 0;
159c3a1a 1813
c5afc314 1814 uuid_from_super_ddf(st, info->uuid);
a322f70c 1815
a5d85af7
N
1816 if (map) {
1817 int i;
1818 for (i = 0 ; i < map_disks; i++) {
1819 if (i < info->array.raid_disks &&
1820 (__be16_to_cpu(ddf->phys->entries[i].state) & DDF_Online) &&
1821 !(__be16_to_cpu(ddf->phys->entries[i].state) & DDF_Failed))
1822 map[i] = 1;
1823 else
1824 map[i] = 0;
1825 }
1826 }
a322f70c
DW
1827}
1828
a5d85af7 1829static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info, char *map)
a322f70c
DW
1830{
1831 struct ddf_super *ddf = st->sb;
d2ca6449
NB
1832 struct vcl *vc = ddf->currentconf;
1833 int cd = ddf->currentdev;
db42fa9b 1834 int j;
8592f29d 1835 struct dl *dl;
a5d85af7 1836 int map_disks = info->array.raid_disks;
90fa1a29 1837 __u32 *cptr;
a322f70c 1838
95eeceeb 1839 memset(info, 0, sizeof(*info));
8a2848a7 1840 if (layout_ddf2md(&vc->conf, &info->array) == -1)
1841 return;
a322f70c 1842 info->array.md_minor = -1;
90fa1a29
JS
1843 cptr = (__u32 *)(vc->conf.guid + 16);
1844 info->array.ctime = DECADE + __be32_to_cpu(*cptr);
d2ca6449
NB
1845 info->array.utime = DECADE + __be32_to_cpu(vc->conf.timestamp);
1846 info->array.chunk_size = 512 << vc->conf.chunk_shift;
da9b4a62 1847 info->custom_array_size = 0;
d2ca6449 1848
f21e18ca 1849 if (cd >= 0 && (unsigned)cd < ddf->mppe) {
d2ca6449
NB
1850 info->data_offset = __be64_to_cpu(vc->lba_offset[cd]);
1851 if (vc->block_sizes)
1852 info->component_size = vc->block_sizes[cd];
1853 else
1854 info->component_size = __be64_to_cpu(vc->conf.blocks);
1855 }
a322f70c 1856
fb204fb2
N
1857 for (dl = ddf->dlist; dl ; dl = dl->next)
1858 if (dl->raiddisk == ddf->currentdev)
1859 break;
1860
a322f70c
DW
1861 info->disk.major = 0;
1862 info->disk.minor = 0;
fb204fb2 1863 info->disk.state = 0;
8592f29d
N
1864 if (dl) {
1865 info->disk.major = dl->major;
1866 info->disk.minor = dl->minor;
fb204fb2
N
1867 info->disk.raid_disk = dl->raiddisk;
1868 info->disk.number = dl->pdnum;
1869 info->disk.state = (1<<MD_DISK_SYNC)|(1<<MD_DISK_ACTIVE);
8592f29d 1870 }
a322f70c 1871
103f2410
NB
1872 info->container_member = ddf->currentconf->vcnum;
1873
921d9e16 1874 info->recovery_start = MaxSector;
80d26cb2 1875 info->resync_start = 0;
624c5ad4 1876 info->reshape_active = 0;
6e75048b 1877 info->recovery_blocked = 0;
80d26cb2
NB
1878 if (!(ddf->virt->entries[info->container_member].state
1879 & DDF_state_inconsistent) &&
1880 (ddf->virt->entries[info->container_member].init_state
1881 & DDF_initstate_mask)
1882 == DDF_init_full)
b7528a20 1883 info->resync_start = MaxSector;
80d26cb2 1884
a322f70c
DW
1885 uuid_from_super_ddf(st, info->uuid);
1886
f35f2525
N
1887 info->array.major_version = -1;
1888 info->array.minor_version = -2;
9b63e648 1889 sprintf(info->text_version, "/%s/%d",
4dd2df09 1890 st->container_devnm,
9b63e648 1891 info->container_member);
a67dd8cc 1892 info->safe_mode_delay = 200;
159c3a1a 1893
db42fa9b
N
1894 memcpy(info->name, ddf->virt->entries[info->container_member].name, 16);
1895 info->name[16]=0;
1896 for(j=0; j<16; j++)
1897 if (info->name[j] == ' ')
1898 info->name[j] = 0;
a5d85af7
N
1899
1900 if (map)
1901 for (j = 0; j < map_disks; j++) {
1902 map[j] = 0;
1903 if (j < info->array.raid_disks) {
1904 int i = find_phys(ddf, vc->conf.phys_refnum[j]);
613b0d17 1905 if (i >= 0 &&
a5d85af7
N
1906 (__be16_to_cpu(ddf->phys->entries[i].state) & DDF_Online) &&
1907 !(__be16_to_cpu(ddf->phys->entries[i].state) & DDF_Failed))
1908 map[i] = 1;
1909 }
1910 }
a322f70c
DW
1911}
1912
1913static int update_super_ddf(struct supertype *st, struct mdinfo *info,
1914 char *update,
1915 char *devname, int verbose,
1916 int uuid_set, char *homehost)
1917{
1918 /* For 'assemble' and 'force' we need to return non-zero if any
1919 * change was made. For others, the return value is ignored.
1920 * Update options are:
1921 * force-one : This device looks a bit old but needs to be included,
1922 * update age info appropriately.
1923 * assemble: clear any 'faulty' flag to allow this device to
1924 * be assembled.
1925 * force-array: Array is degraded but being forced, mark it clean
1926 * if that will be needed to assemble it.
1927 *
1928 * newdev: not used ????
1929 * grow: Array has gained a new device - this is currently for
1930 * linear only
1931 * resync: mark as dirty so a resync will happen.
59e36268 1932 * uuid: Change the uuid of the array to match what is given
a322f70c
DW
1933 * homehost: update the recorded homehost
1934 * name: update the name - preserving the homehost
1935 * _reshape_progress: record new reshape_progress position.
1936 *
1937 * Following are not relevant for this version:
1938 * sparc2.2 : update from old dodgey metadata
1939 * super-minor: change the preferred_minor number
1940 * summaries: update redundant counters.
1941 */
1942 int rv = 0;
1943// struct ddf_super *ddf = st->sb;
7a7cc504 1944// struct vd_config *vd = find_vdcr(ddf, info->container_member);
a322f70c
DW
1945// struct virtual_entry *ve = find_ve(ddf);
1946
a322f70c
DW
1947 /* we don't need to handle "force-*" or "assemble" as
1948 * there is no need to 'trick' the kernel. We the metadata is
1949 * first updated to activate the array, all the implied modifications
1950 * will just happen.
1951 */
1952
1953 if (strcmp(update, "grow") == 0) {
1954 /* FIXME */
1e2b2765 1955 } else if (strcmp(update, "resync") == 0) {
a322f70c 1956// info->resync_checkpoint = 0;
1e2b2765 1957 } else if (strcmp(update, "homehost") == 0) {
a322f70c
DW
1958 /* homehost is stored in controller->vendor_data,
1959 * or it is when we are the vendor
1960 */
1961// if (info->vendor_is_local)
1962// strcpy(ddf->controller.vendor_data, homehost);
1e2b2765 1963 rv = -1;
f49208ec 1964 } else if (strcmp(update, "name") == 0) {
a322f70c
DW
1965 /* name is stored in virtual_entry->name */
1966// memset(ve->name, ' ', 16);
1967// strncpy(ve->name, info->name, 16);
1e2b2765 1968 rv = -1;
f49208ec 1969 } else if (strcmp(update, "_reshape_progress") == 0) {
a322f70c 1970 /* We don't support reshape yet */
f49208ec
N
1971 } else if (strcmp(update, "assemble") == 0 ) {
1972 /* Do nothing, just succeed */
1973 rv = 0;
1e2b2765
N
1974 } else
1975 rv = -1;
a322f70c
DW
1976
1977// update_all_csum(ddf);
1978
1979 return rv;
1980}
1981
5f8097be
NB
1982static void make_header_guid(char *guid)
1983{
1984 __u32 stamp;
5f8097be
NB
1985 /* Create a DDF Header of Virtual Disk GUID */
1986
1987 /* 24 bytes of fiction required.
1988 * first 8 are a 'vendor-id' - "Linux-MD"
1989 * next 8 are controller type.. how about 0X DEAD BEEF 0000 0000
1990 * Remaining 8 random number plus timestamp
1991 */
1992 memcpy(guid, T10, sizeof(T10));
1993 stamp = __cpu_to_be32(0xdeadbeef);
1994 memcpy(guid+8, &stamp, 4);
1995 stamp = __cpu_to_be32(0);
1996 memcpy(guid+12, &stamp, 4);
1997 stamp = __cpu_to_be32(time(0) - DECADE);
1998 memcpy(guid+16, &stamp, 4);
bfb7ea78 1999 stamp = random32();
5f8097be 2000 memcpy(guid+20, &stamp, 4);
5f8097be 2001}
59e36268 2002
fb9d0acb 2003static unsigned int find_unused_vde(const struct ddf_super *ddf)
2004{
2005 unsigned int i;
2006 for (i = 0; i < __be16_to_cpu(ddf->virt->max_vdes); i++) {
2007 if (all_ff(ddf->virt->entries[i].guid))
2008 return i;
2009 }
2010 return DDF_NOTFOUND;
2011}
2012
2013static unsigned int find_vde_by_name(const struct ddf_super *ddf,
2014 const char *name)
2015{
2016 unsigned int i;
2017 if (name == NULL)
2018 return DDF_NOTFOUND;
2019 for (i = 0; i < __be16_to_cpu(ddf->virt->max_vdes); i++) {
2020 if (all_ff(ddf->virt->entries[i].guid))
2021 continue;
2022 if (!strncmp(name, ddf->virt->entries[i].name,
2023 sizeof(ddf->virt->entries[i].name)))
2024 return i;
2025 }
2026 return DDF_NOTFOUND;
2027}
2028
2029static unsigned int find_vde_by_guid(const struct ddf_super *ddf,
2030 const char *guid)
2031{
2032 unsigned int i;
2033 if (guid == NULL || all_ff(guid))
2034 return DDF_NOTFOUND;
2035 for (i = 0; i < __be16_to_cpu(ddf->virt->max_vdes); i++)
2036 if (!memcmp(ddf->virt->entries[i].guid, guid, DDF_GUID_LEN))
2037 return i;
2038 return DDF_NOTFOUND;
2039}
2040
78e44928
NB
2041static int init_super_ddf_bvd(struct supertype *st,
2042 mdu_array_info_t *info,
2043 unsigned long long size,
2044 char *name, char *homehost,
83cd1e97 2045 int *uuid, unsigned long long data_offset);
78e44928 2046
a322f70c
DW
2047static int init_super_ddf(struct supertype *st,
2048 mdu_array_info_t *info,
2049 unsigned long long size, char *name, char *homehost,
83cd1e97 2050 int *uuid, unsigned long long data_offset)
a322f70c
DW
2051{
2052 /* This is primarily called by Create when creating a new array.
2053 * We will then get add_to_super called for each component, and then
2054 * write_init_super called to write it out to each device.
2055 * For DDF, Create can create on fresh devices or on a pre-existing
2056 * array.
2057 * To create on a pre-existing array a different method will be called.
2058 * This one is just for fresh drives.
2059 *
2060 * We need to create the entire 'ddf' structure which includes:
2061 * DDF headers - these are easy.
2062 * Controller data - a Sector describing this controller .. not that
2063 * this is a controller exactly.
2064 * Physical Disk Record - one entry per device, so
2065 * leave plenty of space.
2066 * Virtual Disk Records - again, just leave plenty of space.
2067 * This just lists VDs, doesn't give details
2068 * Config records - describes the VDs that use this disk
2069 * DiskData - describes 'this' device.
2070 * BadBlockManagement - empty
2071 * Diag Space - empty
2072 * Vendor Logs - Could we put bitmaps here?
2073 *
2074 */
2075 struct ddf_super *ddf;
2076 char hostname[17];
2077 int hostlen;
a322f70c
DW
2078 int max_phys_disks, max_virt_disks;
2079 unsigned long long sector;
2080 int clen;
2081 int i;
2082 int pdsize, vdsize;
2083 struct phys_disk *pd;
2084 struct virtual_disk *vd;
2085
83cd1e97 2086 if (data_offset != INVALID_SECTORS) {
ed503f89 2087 pr_err("data-offset not supported by DDF\n");
83cd1e97
N
2088 return 0;
2089 }
2090
78e44928 2091 if (st->sb)
83cd1e97
N
2092 return init_super_ddf_bvd(st, info, size, name, homehost, uuid,
2093 data_offset);
ba7eb04f 2094
3d2c4fc7 2095 if (posix_memalign((void**)&ddf, 512, sizeof(*ddf)) != 0) {
e7b84f9d 2096 pr_err("%s could not allocate superblock\n", __func__);
3d2c4fc7
DW
2097 return 0;
2098 }
6264b437 2099 memset(ddf, 0, sizeof(*ddf));
a322f70c
DW
2100 ddf->dlist = NULL; /* no physical disks yet */
2101 ddf->conflist = NULL; /* No virtual disks yet */
955e9ea1
DW
2102 st->sb = ddf;
2103
2104 if (info == NULL) {
2105 /* zeroing superblock */
2106 return 0;
2107 }
a322f70c
DW
2108
2109 /* At least 32MB *must* be reserved for the ddf. So let's just
2110 * start 32MB from the end, and put the primary header there.
2111 * Don't do secondary for now.
2112 * We don't know exactly where that will be yet as it could be
2113 * different on each device. To just set up the lengths.
2114 *
2115 */
2116
2117 ddf->anchor.magic = DDF_HEADER_MAGIC;
5f8097be 2118 make_header_guid(ddf->anchor.guid);
a322f70c 2119
59e36268 2120 memcpy(ddf->anchor.revision, DDF_REVISION_2, 8);
a322f70c
DW
2121 ddf->anchor.seq = __cpu_to_be32(1);
2122 ddf->anchor.timestamp = __cpu_to_be32(time(0) - DECADE);
2123 ddf->anchor.openflag = 0xFF;
2124 ddf->anchor.foreignflag = 0;
2125 ddf->anchor.enforcegroups = 0; /* Is this best?? */
2126 ddf->anchor.pad0 = 0xff;
2127 memset(ddf->anchor.pad1, 0xff, 12);
2128 memset(ddf->anchor.header_ext, 0xff, 32);
2129 ddf->anchor.primary_lba = ~(__u64)0;
2130 ddf->anchor.secondary_lba = ~(__u64)0;
2131 ddf->anchor.type = DDF_HEADER_ANCHOR;
2132 memset(ddf->anchor.pad2, 0xff, 3);
2133 ddf->anchor.workspace_len = __cpu_to_be32(32768); /* Must be reserved */
2134 ddf->anchor.workspace_lba = ~(__u64)0; /* Put this at bottom
2135 of 32M reserved.. */
2136 max_phys_disks = 1023; /* Should be enough */
2137 ddf->anchor.max_pd_entries = __cpu_to_be16(max_phys_disks);
2138 max_virt_disks = 255;
2139 ddf->anchor.max_vd_entries = __cpu_to_be16(max_virt_disks); /* ?? */
2140 ddf->anchor.max_partitions = __cpu_to_be16(64); /* ?? */
2141 ddf->max_part = 64;
8c3b8c2c 2142 ddf->mppe = 256;
59e36268
NB
2143 ddf->conf_rec_len = 1 + ROUND_UP(ddf->mppe * (4+8), 512)/512;
2144 ddf->anchor.config_record_len = __cpu_to_be16(ddf->conf_rec_len);
2145 ddf->anchor.max_primary_element_entries = __cpu_to_be16(ddf->mppe);
a322f70c 2146 memset(ddf->anchor.pad3, 0xff, 54);
a322f70c
DW
2147 /* controller sections is one sector long immediately
2148 * after the ddf header */
2149 sector = 1;
2150 ddf->anchor.controller_section_offset = __cpu_to_be32(sector);
2151 ddf->anchor.controller_section_length = __cpu_to_be32(1);
2152 sector += 1;
2153
2154 /* phys is 8 sectors after that */
2155 pdsize = ROUND_UP(sizeof(struct phys_disk) +
2156 sizeof(struct phys_disk_entry)*max_phys_disks,
2157 512);
2158 switch(pdsize/512) {
2159 case 2: case 8: case 32: case 128: case 512: break;
2160 default: abort();
2161 }
2162 ddf->anchor.phys_section_offset = __cpu_to_be32(sector);
2163 ddf->anchor.phys_section_length =
2164 __cpu_to_be32(pdsize/512); /* max_primary_element_entries/8 */
2165 sector += pdsize/512;
2166
2167 /* virt is another 32 sectors */
2168 vdsize = ROUND_UP(sizeof(struct virtual_disk) +
2169 sizeof(struct virtual_entry) * max_virt_disks,
2170 512);
2171 switch(vdsize/512) {
2172 case 2: case 8: case 32: case 128: case 512: break;
2173 default: abort();
2174 }
2175 ddf->anchor.virt_section_offset = __cpu_to_be32(sector);
2176 ddf->anchor.virt_section_length =
2177 __cpu_to_be32(vdsize/512); /* max_vd_entries/8 */
2178 sector += vdsize/512;
2179
59e36268 2180 clen = ddf->conf_rec_len * (ddf->max_part+1);
a322f70c
DW
2181 ddf->anchor.config_section_offset = __cpu_to_be32(sector);
2182 ddf->anchor.config_section_length = __cpu_to_be32(clen);
2183 sector += clen;
2184
2185 ddf->anchor.data_section_offset = __cpu_to_be32(sector);
2186 ddf->anchor.data_section_length = __cpu_to_be32(1);
2187 sector += 1;
2188
2189 ddf->anchor.bbm_section_length = __cpu_to_be32(0);
2190 ddf->anchor.bbm_section_offset = __cpu_to_be32(0xFFFFFFFF);
2191 ddf->anchor.diag_space_length = __cpu_to_be32(0);
2192 ddf->anchor.diag_space_offset = __cpu_to_be32(0xFFFFFFFF);
2193 ddf->anchor.vendor_length = __cpu_to_be32(0);
2194 ddf->anchor.vendor_offset = __cpu_to_be32(0xFFFFFFFF);
2195
2196 memset(ddf->anchor.pad4, 0xff, 256);
2197
2198 memcpy(&ddf->primary, &ddf->anchor, 512);
2199 memcpy(&ddf->secondary, &ddf->anchor, 512);
2200
2201 ddf->primary.openflag = 1; /* I guess.. */
2202 ddf->primary.type = DDF_HEADER_PRIMARY;
2203
2204 ddf->secondary.openflag = 1; /* I guess.. */
2205 ddf->secondary.type = DDF_HEADER_SECONDARY;
2206
2207 ddf->active = &ddf->primary;
2208
2209 ddf->controller.magic = DDF_CONTROLLER_MAGIC;
2210
2211 /* 24 more bytes of fiction required.
2212 * first 8 are a 'vendor-id' - "Linux-MD"
2213 * Remaining 16 are serial number.... maybe a hostname would do?
2214 */
2215 memcpy(ddf->controller.guid, T10, sizeof(T10));
1ba6bff9
DW
2216 gethostname(hostname, sizeof(hostname));
2217 hostname[sizeof(hostname) - 1] = 0;
a322f70c
DW
2218 hostlen = strlen(hostname);
2219 memcpy(ddf->controller.guid + 24 - hostlen, hostname, hostlen);
2220 for (i = strlen(T10) ; i+hostlen < 24; i++)
2221 ddf->controller.guid[i] = ' ';
2222
2223 ddf->controller.type.vendor_id = __cpu_to_be16(0xDEAD);
2224 ddf->controller.type.device_id = __cpu_to_be16(0xBEEF);
2225 ddf->controller.type.sub_vendor_id = 0;
2226 ddf->controller.type.sub_device_id = 0;
2227 memcpy(ddf->controller.product_id, "What Is My PID??", 16);
2228 memset(ddf->controller.pad, 0xff, 8);
2229 memset(ddf->controller.vendor_data, 0xff, 448);
a9e1c11d
N
2230 if (homehost && strlen(homehost) < 440)
2231 strcpy((char*)ddf->controller.vendor_data, homehost);
a322f70c 2232
3d2c4fc7 2233 if (posix_memalign((void**)&pd, 512, pdsize) != 0) {
e7b84f9d 2234 pr_err("%s could not allocate pd\n", __func__);
3d2c4fc7
DW
2235 return 0;
2236 }
6416d527 2237 ddf->phys = pd;
a322f70c
DW
2238 ddf->pdsize = pdsize;
2239
2240 memset(pd, 0xff, pdsize);
2241 memset(pd, 0, sizeof(*pd));
076515ba 2242 pd->magic = DDF_PHYS_RECORDS_MAGIC;
a322f70c
DW
2243 pd->used_pdes = __cpu_to_be16(0);
2244 pd->max_pdes = __cpu_to_be16(max_phys_disks);
2245 memset(pd->pad, 0xff, 52);
2246
3d2c4fc7 2247 if (posix_memalign((void**)&vd, 512, vdsize) != 0) {
e7b84f9d 2248 pr_err("%s could not allocate vd\n", __func__);
3d2c4fc7
DW
2249 return 0;
2250 }
6416d527 2251 ddf->virt = vd;
a322f70c
DW
2252 ddf->vdsize = vdsize;
2253 memset(vd, 0, vdsize);
2254 vd->magic = DDF_VIRT_RECORDS_MAGIC;
2255 vd->populated_vdes = __cpu_to_be16(0);
2256 vd->max_vdes = __cpu_to_be16(max_virt_disks);
2257 memset(vd->pad, 0xff, 52);
2258
5f8097be
NB
2259 for (i=0; i<max_virt_disks; i++)
2260 memset(&vd->entries[i], 0xff, sizeof(struct virtual_entry));
2261
a322f70c 2262 st->sb = ddf;
7d5a7ff3 2263 ddf_set_updates_pending(ddf);
a322f70c
DW
2264 return 1;
2265}
2266
5f8097be
NB
2267static int chunk_to_shift(int chunksize)
2268{
2269 return ffs(chunksize/512)-1;
2270}
2271
0e600426 2272#ifndef MDASSEMBLE
59e36268
NB
2273struct extent {
2274 unsigned long long start, size;
2275};
78e44928 2276static int cmp_extent(const void *av, const void *bv)
59e36268
NB
2277{
2278 const struct extent *a = av;
2279 const struct extent *b = bv;
2280 if (a->start < b->start)
2281 return -1;
2282 if (a->start > b->start)
2283 return 1;
2284 return 0;
2285}
2286
78e44928 2287static struct extent *get_extents(struct ddf_super *ddf, struct dl *dl)
59e36268
NB
2288{
2289 /* find a list of used extents on the give physical device
2290 * (dnum) of the given ddf.
2291 * Return a malloced array of 'struct extent'
2292
613b0d17 2293 * FIXME ignore DDF_Legacy devices?
59e36268
NB
2294
2295 */
2296 struct extent *rv;
2297 int n = 0;
f21e18ca 2298 unsigned int i, j;
59e36268 2299
503975b9 2300 rv = xmalloc(sizeof(struct extent) * (ddf->max_part + 2));
59e36268
NB
2301
2302 for (i = 0; i < ddf->max_part; i++) {
2303 struct vcl *v = dl->vlist[i];
2304 if (v == NULL)
2305 continue;
f21e18ca 2306 for (j = 0; j < v->conf.prim_elmnt_count; j++)
59e36268
NB
2307 if (v->conf.phys_refnum[j] == dl->disk.refnum) {
2308 /* This device plays role 'j' in 'v'. */
2309 rv[n].start = __be64_to_cpu(v->lba_offset[j]);
2310 rv[n].size = __be64_to_cpu(v->conf.blocks);
2311 n++;
2312 break;
2313 }
2314 }
2315 qsort(rv, n, sizeof(*rv), cmp_extent);
2316
2317 rv[n].start = __be64_to_cpu(ddf->phys->entries[dl->pdnum].config_size);
2318 rv[n].size = 0;
2319 return rv;
2320}
0e600426 2321#endif
59e36268 2322
5f8097be
NB
2323static int init_super_ddf_bvd(struct supertype *st,
2324 mdu_array_info_t *info,
2325 unsigned long long size,
2326 char *name, char *homehost,
83cd1e97 2327 int *uuid, unsigned long long data_offset)
5f8097be
NB
2328{
2329 /* We are creating a BVD inside a pre-existing container.
2330 * so st->sb is already set.
2331 * We need to create a new vd_config and a new virtual_entry
2332 */
2333 struct ddf_super *ddf = st->sb;
5aaf6c7b 2334 unsigned int venum, i;
5f8097be
NB
2335 struct virtual_entry *ve;
2336 struct vcl *vcl;
2337 struct vd_config *vc;
5f8097be 2338
fb9d0acb 2339 if (find_vde_by_name(ddf, name) != DDF_NOTFOUND) {
2340 pr_err("This ddf already has an array called %s\n", name);
5f8097be
NB
2341 return 0;
2342 }
fb9d0acb 2343 venum = find_unused_vde(ddf);
2344 if (venum == DDF_NOTFOUND) {
2345 pr_err("Cannot find spare slot for virtual disk\n");
5f8097be
NB
2346 return 0;
2347 }
2348 ve = &ddf->virt->entries[venum];
2349
2350 /* A Virtual Disk GUID contains the T10 Vendor ID, controller type,
2351 * timestamp, random number
2352 */
2353 make_header_guid(ve->guid);
2354 ve->unit = __cpu_to_be16(info->md_minor);
2355 ve->pad0 = 0xFFFF;
2356 ve->guid_crc = crc32(0, (unsigned char*)ddf->anchor.guid, DDF_GUID_LEN);
2357 ve->type = 0;
7a7cc504
NB
2358 ve->state = DDF_state_degraded; /* Will be modified as devices are added */
2359 if (info->state & 1) /* clean */
2360 ve->init_state = DDF_init_full;
2361 else
2362 ve->init_state = DDF_init_not;
2363
5f8097be
NB
2364 memset(ve->pad1, 0xff, 14);
2365 memset(ve->name, ' ', 16);
2366 if (name)
2367 strncpy(ve->name, name, 16);
2368 ddf->virt->populated_vdes =
2369 __cpu_to_be16(__be16_to_cpu(ddf->virt->populated_vdes)+1);
2370
2371 /* Now create a new vd_config */
3d2c4fc7
DW
2372 if (posix_memalign((void**)&vcl, 512,
2373 (offsetof(struct vcl, conf) + ddf->conf_rec_len * 512)) != 0) {
e7b84f9d 2374 pr_err("%s could not allocate vd_config\n", __func__);
3d2c4fc7
DW
2375 return 0;
2376 }
8c3b8c2c 2377 vcl->lba_offset = (__u64*) &vcl->conf.phys_refnum[ddf->mppe];
59e36268
NB
2378 vcl->vcnum = venum;
2379 vcl->block_sizes = NULL; /* FIXME not for CONCAT */
5f8097be
NB
2380 vc = &vcl->conf;
2381
2382 vc->magic = DDF_VD_CONF_MAGIC;
2383 memcpy(vc->guid, ve->guid, DDF_GUID_LEN);
2384 vc->timestamp = __cpu_to_be32(time(0)-DECADE);
2385 vc->seqnum = __cpu_to_be32(1);
2386 memset(vc->pad0, 0xff, 24);
5f8097be 2387 vc->chunk_shift = chunk_to_shift(info->chunk_size);
a3163bf0 2388 if (layout_md2ddf(info, vc) == -1 ||
2389 __be16_to_cpu(vc->prim_elmnt_count) > ddf->mppe) {
2390 pr_err("%s: unsupported RAID level/layout %d/%d with %d disks\n",
2391 __func__, info->level, info->layout, info->raid_disks);
2392 free(vcl);
2393 return 0;
2394 }
5f8097be 2395 vc->sec_elmnt_seq = 0;
3c48f7be 2396 if (alloc_other_bvds(ddf, vcl) != 0) {
2397 pr_err("%s could not allocate other bvds\n",
2398 __func__);
2399 free(vcl);
2400 return 0;
2401 }
5f8097be
NB
2402 vc->blocks = __cpu_to_be64(info->size * 2);
2403 vc->array_blocks = __cpu_to_be64(
2404 calc_array_size(info->level, info->raid_disks, info->layout,
2405 info->chunk_size, info->size*2));
2406 memset(vc->pad1, 0xff, 8);
2407 vc->spare_refs[0] = 0xffffffff;
2408 vc->spare_refs[1] = 0xffffffff;
2409 vc->spare_refs[2] = 0xffffffff;
2410 vc->spare_refs[3] = 0xffffffff;
2411 vc->spare_refs[4] = 0xffffffff;
2412 vc->spare_refs[5] = 0xffffffff;
2413 vc->spare_refs[6] = 0xffffffff;
2414 vc->spare_refs[7] = 0xffffffff;
2415 memset(vc->cache_pol, 0, 8);
2416 vc->bg_rate = 0x80;
2417 memset(vc->pad2, 0xff, 3);
2418 memset(vc->pad3, 0xff, 52);
2419 memset(vc->pad4, 0xff, 192);
2420 memset(vc->v0, 0xff, 32);
2421 memset(vc->v1, 0xff, 32);
2422 memset(vc->v2, 0xff, 16);
2423 memset(vc->v3, 0xff, 16);
2424 memset(vc->vendor, 0xff, 32);
598f0d58 2425
8c3b8c2c 2426 memset(vc->phys_refnum, 0xff, 4*ddf->mppe);
e5a2a3cf 2427 memset(vc->phys_refnum+ddf->mppe, 0x00, 8*ddf->mppe);
5f8097be 2428
5aaf6c7b 2429 for (i = 1; i < vc->sec_elmnt_count; i++) {
2430 memcpy(vcl->other_bvds[i-1], vc, ddf->conf_rec_len * 512);
2431 vcl->other_bvds[i-1]->sec_elmnt_seq = i;
2432 }
2433
5f8097be
NB
2434 vcl->next = ddf->conflist;
2435 ddf->conflist = vcl;
d2ca6449 2436 ddf->currentconf = vcl;
7d5a7ff3 2437 ddf_set_updates_pending(ddf);
5f8097be
NB
2438 return 1;
2439}
2440
0e600426 2441#ifndef MDASSEMBLE
5f8097be
NB
2442static void add_to_super_ddf_bvd(struct supertype *st,
2443 mdu_disk_info_t *dk, int fd, char *devname)
2444{
2445 /* fd and devname identify a device with-in the ddf container (st).
2446 * dk identifies a location in the new BVD.
2447 * We need to find suitable free space in that device and update
2448 * the phys_refnum and lba_offset for the newly created vd_config.
2449 * We might also want to update the type in the phys_disk
5575e7d9 2450 * section.
8592f29d
N
2451 *
2452 * Alternately: fd == -1 and we have already chosen which device to
2453 * use and recorded in dlist->raid_disk;
5f8097be
NB
2454 */
2455 struct dl *dl;
2456 struct ddf_super *ddf = st->sb;
2457 struct vd_config *vc;
2458 __u64 *lba_offset;
f21e18ca
N
2459 unsigned int working;
2460 unsigned int i;
59e36268
NB
2461 unsigned long long blocks, pos, esize;
2462 struct extent *ex;
5f8097be 2463
8592f29d
N
2464 if (fd == -1) {
2465 for (dl = ddf->dlist; dl ; dl = dl->next)
2466 if (dl->raiddisk == dk->raid_disk)
2467 break;
2468 } else {
2469 for (dl = ddf->dlist; dl ; dl = dl->next)
2470 if (dl->major == dk->major &&
2471 dl->minor == dk->minor)
2472 break;
2473 }
5f8097be
NB
2474 if (!dl || ! (dk->state & (1<<MD_DISK_SYNC)))
2475 return;
2476
d2ca6449
NB
2477 vc = &ddf->currentconf->conf;
2478 lba_offset = ddf->currentconf->lba_offset;
59e36268
NB
2479
2480 ex = get_extents(ddf, dl);
2481 if (!ex)
2482 return;
2483
2484 i = 0; pos = 0;
2485 blocks = __be64_to_cpu(vc->blocks);
d2ca6449
NB
2486 if (ddf->currentconf->block_sizes)
2487 blocks = ddf->currentconf->block_sizes[dk->raid_disk];
59e36268
NB
2488
2489 do {
2490 esize = ex[i].start - pos;
2491 if (esize >= blocks)
2492 break;
2493 pos = ex[i].start + ex[i].size;
2494 i++;
2495 } while (ex[i-1].size);
2496
2497 free(ex);
2498 if (esize < blocks)
2499 return;
2500
d2ca6449 2501 ddf->currentdev = dk->raid_disk;
5f8097be 2502 vc->phys_refnum[dk->raid_disk] = dl->disk.refnum;
59e36268 2503 lba_offset[dk->raid_disk] = __cpu_to_be64(pos);
5f8097be 2504
f21e18ca 2505 for (i = 0; i < ddf->max_part ; i++)
5575e7d9
NB
2506 if (dl->vlist[i] == NULL)
2507 break;
2508 if (i == ddf->max_part)
2509 return;
d2ca6449 2510 dl->vlist[i] = ddf->currentconf;
5f8097be 2511
8592f29d
N
2512 if (fd >= 0)
2513 dl->fd = fd;
2514 if (devname)
2515 dl->devname = devname;
7a7cc504
NB
2516
2517 /* Check how many working raid_disks, and if we can mark
2518 * array as optimal yet
2519 */
2520 working = 0;
5575e7d9 2521
f21e18ca 2522 for (i = 0; i < __be16_to_cpu(vc->prim_elmnt_count); i++)
7a7cc504
NB
2523 if (vc->phys_refnum[i] != 0xffffffff)
2524 working++;
59e36268 2525
5575e7d9 2526 /* Find which virtual_entry */
d2ca6449 2527 i = ddf->currentconf->vcnum;
7a7cc504 2528 if (working == __be16_to_cpu(vc->prim_elmnt_count))
5575e7d9
NB
2529 ddf->virt->entries[i].state =
2530 (ddf->virt->entries[i].state & ~DDF_state_mask)
7a7cc504
NB
2531 | DDF_state_optimal;
2532
2533 if (vc->prl == DDF_RAID6 &&
2534 working+1 == __be16_to_cpu(vc->prim_elmnt_count))
5575e7d9
NB
2535 ddf->virt->entries[i].state =
2536 (ddf->virt->entries[i].state & ~DDF_state_mask)
7a7cc504 2537 | DDF_state_part_optimal;
5575e7d9
NB
2538
2539 ddf->phys->entries[dl->pdnum].type &= ~__cpu_to_be16(DDF_Global_Spare);
2540 ddf->phys->entries[dl->pdnum].type |= __cpu_to_be16(DDF_Active_in_VD);
7d5a7ff3 2541 ddf_set_updates_pending(ddf);
5f8097be
NB
2542}
2543
a322f70c
DW
2544/* add a device to a container, either while creating it or while
2545 * expanding a pre-existing container
2546 */
f20c3968 2547static int add_to_super_ddf(struct supertype *st,
72ca9bcf
N
2548 mdu_disk_info_t *dk, int fd, char *devname,
2549 unsigned long long data_offset)
a322f70c
DW
2550{
2551 struct ddf_super *ddf = st->sb;
2552 struct dl *dd;
2553 time_t now;
2554 struct tm *tm;
2555 unsigned long long size;
2556 struct phys_disk_entry *pde;
f21e18ca 2557 unsigned int n, i;
a322f70c 2558 struct stat stb;
90fa1a29 2559 __u32 *tptr;
a322f70c 2560
78e44928
NB
2561 if (ddf->currentconf) {
2562 add_to_super_ddf_bvd(st, dk, fd, devname);
f20c3968 2563 return 0;
78e44928
NB
2564 }
2565
a322f70c
DW
2566 /* This is device numbered dk->number. We need to create
2567 * a phys_disk entry and a more detailed disk_data entry.
2568 */
2569 fstat(fd, &stb);
3d2c4fc7
DW
2570 if (posix_memalign((void**)&dd, 512,
2571 sizeof(*dd) + sizeof(dd->vlist[0]) * ddf->max_part) != 0) {
e7b84f9d
N
2572 pr_err("%s could allocate buffer for new disk, aborting\n",
2573 __func__);
f20c3968 2574 return 1;
3d2c4fc7 2575 }
a322f70c
DW
2576 dd->major = major(stb.st_rdev);
2577 dd->minor = minor(stb.st_rdev);
2578 dd->devname = devname;
a322f70c 2579 dd->fd = fd;
b2280677 2580 dd->spare = NULL;
a322f70c
DW
2581
2582 dd->disk.magic = DDF_PHYS_DATA_MAGIC;
2583 now = time(0);
2584 tm = localtime(&now);
2585 sprintf(dd->disk.guid, "%8s%04d%02d%02d",
2586 T10, tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
90fa1a29
JS
2587 tptr = (__u32 *)(dd->disk.guid + 16);
2588 *tptr++ = random32();
2589 *tptr = random32();
a322f70c 2590
59e36268
NB
2591 do {
2592 /* Cannot be bothered finding a CRC of some irrelevant details*/
bfb7ea78 2593 dd->disk.refnum = random32();
f21e18ca
N
2594 for (i = __be16_to_cpu(ddf->active->max_pd_entries);
2595 i > 0; i--)
2596 if (ddf->phys->entries[i-1].refnum == dd->disk.refnum)
59e36268 2597 break;
f21e18ca 2598 } while (i > 0);
59e36268 2599
a322f70c
DW
2600 dd->disk.forced_ref = 1;
2601 dd->disk.forced_guid = 1;
2602 memset(dd->disk.vendor, ' ', 32);
2603 memcpy(dd->disk.vendor, "Linux", 5);
2604 memset(dd->disk.pad, 0xff, 442);
b2280677 2605 for (i = 0; i < ddf->max_part ; i++)
a322f70c
DW
2606 dd->vlist[i] = NULL;
2607
2608 n = __be16_to_cpu(ddf->phys->used_pdes);
2609 pde = &ddf->phys->entries[n];
5575e7d9
NB
2610 dd->pdnum = n;
2611
2cc2983d
N
2612 if (st->update_tail) {
2613 int len = (sizeof(struct phys_disk) +
2614 sizeof(struct phys_disk_entry));
2615 struct phys_disk *pd;
2616
503975b9 2617 pd = xmalloc(len);
2cc2983d
N
2618 pd->magic = DDF_PHYS_RECORDS_MAGIC;
2619 pd->used_pdes = __cpu_to_be16(n);
2620 pde = &pd->entries[0];
2621 dd->mdupdate = pd;
2622 } else {
2623 n++;
2624 ddf->phys->used_pdes = __cpu_to_be16(n);
2625 }
a322f70c
DW
2626
2627 memcpy(pde->guid, dd->disk.guid, DDF_GUID_LEN);
2628 pde->refnum = dd->disk.refnum;
5575e7d9 2629 pde->type = __cpu_to_be16(DDF_Forced_PD_GUID | DDF_Global_Spare);
a322f70c
DW
2630 pde->state = __cpu_to_be16(DDF_Online);
2631 get_dev_size(fd, NULL, &size);
2632 /* We are required to reserve 32Meg, and record the size in sectors */
2633 pde->config_size = __cpu_to_be64( (size - 32*1024*1024) / 512);
2634 sprintf(pde->path, "%17.17s","Information: nil") ;
2635 memset(pde->pad, 0xff, 6);
2636
d2ca6449 2637 dd->size = size >> 9;
2cc2983d
N
2638 if (st->update_tail) {
2639 dd->next = ddf->add_list;
2640 ddf->add_list = dd;
2641 } else {
2642 dd->next = ddf->dlist;
2643 ddf->dlist = dd;
7d5a7ff3 2644 ddf_set_updates_pending(ddf);
2cc2983d 2645 }
f20c3968
DW
2646
2647 return 0;
a322f70c
DW
2648}
2649
4dd968cc
N
2650static int remove_from_super_ddf(struct supertype *st, mdu_disk_info_t *dk)
2651{
2652 struct ddf_super *ddf = st->sb;
2653 struct dl *dl;
2654
2655 /* mdmon has noticed that this disk (dk->major/dk->minor) has
2656 * disappeared from the container.
2657 * We need to arrange that it disappears from the metadata and
2658 * internal data structures too.
2659 * Most of the work is done by ddf_process_update which edits
2660 * the metadata and closes the file handle and attaches the memory
2661 * where free_updates will free it.
2662 */
2663 for (dl = ddf->dlist; dl ; dl = dl->next)
2664 if (dl->major == dk->major &&
2665 dl->minor == dk->minor)
2666 break;
2667 if (!dl)
2668 return -1;
2669
2670 if (st->update_tail) {
2671 int len = (sizeof(struct phys_disk) +
2672 sizeof(struct phys_disk_entry));
2673 struct phys_disk *pd;
2674
503975b9 2675 pd = xmalloc(len);
4dd968cc
N
2676 pd->magic = DDF_PHYS_RECORDS_MAGIC;
2677 pd->used_pdes = __cpu_to_be16(dl->pdnum);
2678 pd->entries[0].state = __cpu_to_be16(DDF_Missing);
2679 append_metadata_update(st, pd, len);
2680 }
2681 return 0;
2682}
2683
a322f70c
DW
2684/*
2685 * This is the write_init_super method for a ddf container. It is
2686 * called when creating a container or adding another device to a
2687 * container.
2688 */
42d5dfd9 2689#define NULL_CONF_SZ 4096
18a2f463 2690
e3c2a365 2691static unsigned int get_pd_index_from_refnum(const struct vcl *vc,
2692 __u32 refnum, unsigned int nmax,
2693 const struct vd_config **bvd,
2694 unsigned int *idx);
2695
7f798aca 2696static int __write_ddf_structure(struct dl *d, struct ddf_super *ddf, __u8 type,
2697 char *null_aligned)
a322f70c 2698{
7f798aca 2699 unsigned long long sector;
2700 struct ddf_header *header;
2701 int fd, i, n_config, conf_size;
a4057a88 2702 int ret = 0;
7f798aca 2703
2704 fd = d->fd;
2705
2706 switch (type) {
2707 case DDF_HEADER_PRIMARY:
2708 header = &ddf->primary;
2709 sector = __be64_to_cpu(header->primary_lba);
2710 break;
2711 case DDF_HEADER_SECONDARY:
2712 header = &ddf->secondary;
2713 sector = __be64_to_cpu(header->secondary_lba);
2714 break;
2715 default:
2716 return 0;
2717 }
2718
2719 header->type = type;
a4057a88 2720 header->openflag = 1;
7f798aca 2721 header->crc = calc_crc(header, 512);
2722
2723 lseek64(fd, sector<<9, 0);
2724 if (write(fd, header, 512) < 0)
a4057a88 2725 goto out;
7f798aca 2726
2727 ddf->controller.crc = calc_crc(&ddf->controller, 512);
2728 if (write(fd, &ddf->controller, 512) < 0)
a4057a88 2729 goto out;
a322f70c 2730
7f798aca 2731 ddf->phys->crc = calc_crc(ddf->phys, ddf->pdsize);
2732 if (write(fd, ddf->phys, ddf->pdsize) < 0)
a4057a88 2733 goto out;
7f798aca 2734 ddf->virt->crc = calc_crc(ddf->virt, ddf->vdsize);
2735 if (write(fd, ddf->virt, ddf->vdsize) < 0)
a4057a88 2736 goto out;
7f798aca 2737
2738 /* Now write lots of config records. */
2739 n_config = ddf->max_part;
2740 conf_size = ddf->conf_rec_len * 512;
2741 for (i = 0 ; i <= n_config ; i++) {
e3c2a365 2742 struct vcl *c;
2743 struct vd_config *vdc = NULL;
2744 if (i == n_config) {
7f798aca 2745 c = (struct vcl *)d->spare;
e3c2a365 2746 if (c)
2747 vdc = &c->conf;
2748 } else {
2749 unsigned int dummy;
2750 c = d->vlist[i];
2751 if (c)
2752 get_pd_index_from_refnum(
2753 c, d->disk.refnum,
2754 ddf->mppe,
2755 (const struct vd_config **)&vdc,
2756 &dummy);
2757 }
7f798aca 2758 if (c) {
dacf3dc5 2759 vdc->seqnum = header->seq;
e3c2a365 2760 vdc->crc = calc_crc(vdc, conf_size);
2761 if (write(fd, vdc, conf_size) < 0)
7f798aca 2762 break;
2763 } else {
2764 unsigned int togo = conf_size;
2765 while (togo > NULL_CONF_SZ) {
2766 if (write(fd, null_aligned, NULL_CONF_SZ) < 0)
2767 break;
2768 togo -= NULL_CONF_SZ;
2769 }
2770 if (write(fd, null_aligned, togo) < 0)
2771 break;
2772 }
2773 }
2774 if (i <= n_config)
a4057a88 2775 goto out;
7f798aca 2776
2777 d->disk.crc = calc_crc(&d->disk, 512);
2778 if (write(fd, &d->disk, 512) < 0)
a4057a88 2779 goto out;
7f798aca 2780
a4057a88 2781 ret = 1;
2782out:
2783 header->openflag = 0;
2784 header->crc = calc_crc(header, 512);
2785
2786 lseek64(fd, sector<<9, 0);
2787 if (write(fd, header, 512) < 0)
2788 ret = 0;
2789
2790 return ret;
7f798aca 2791}
2792
2793static int __write_init_super_ddf(struct supertype *st)
2794{
a322f70c 2795 struct ddf_super *ddf = st->sb;
a322f70c 2796 struct dl *d;
175593bf
DW
2797 int attempts = 0;
2798 int successes = 0;
7f798aca 2799 unsigned long long size;
42d5dfd9 2800 char *null_aligned;
0175cbf6 2801 __u32 seq;
42d5dfd9 2802
7d5a7ff3 2803 pr_state(ddf, __func__);
42d5dfd9
JS
2804 if (posix_memalign((void**)&null_aligned, 4096, NULL_CONF_SZ) != 0) {
2805 return -ENOMEM;
2806 }
2807 memset(null_aligned, 0xff, NULL_CONF_SZ);
a322f70c 2808
dc9e279c 2809 seq = ddf->active->seq + 1;
0175cbf6 2810
175593bf
DW
2811 /* try to write updated metadata,
2812 * if we catch a failure move on to the next disk
2813 */
a322f70c
DW
2814 for (d = ddf->dlist; d; d=d->next) {
2815 int fd = d->fd;
2816
2817 if (fd < 0)
2818 continue;
2819
175593bf 2820 attempts++;
a322f70c
DW
2821 /* We need to fill in the primary, (secondary) and workspace
2822 * lba's in the headers, set their checksums,
2823 * Also checksum phys, virt....
2824 *
2825 * Then write everything out, finally the anchor is written.
2826 */
2827 get_dev_size(fd, NULL, &size);
2828 size /= 512;
097bcf00 2829 if (d->workspace_lba != 0)
2830 ddf->anchor.workspace_lba = d->workspace_lba;
2831 else
2832 ddf->anchor.workspace_lba =
2833 __cpu_to_be64(size - 32*1024*2);
2834 if (d->primary_lba != 0)
2835 ddf->anchor.primary_lba = d->primary_lba;
2836 else
2837 ddf->anchor.primary_lba =
2838 __cpu_to_be64(size - 16*1024*2);
2839 if (d->secondary_lba != 0)
2840 ddf->anchor.secondary_lba = d->secondary_lba;
2841 else
2842 ddf->anchor.secondary_lba =
2843 __cpu_to_be64(size - 32*1024*2);
0175cbf6 2844 ddf->anchor.seq = seq;
a322f70c
DW
2845 memcpy(&ddf->primary, &ddf->anchor, 512);
2846 memcpy(&ddf->secondary, &ddf->anchor, 512);
2847
2848 ddf->anchor.openflag = 0xFF; /* 'open' means nothing */
2849 ddf->anchor.seq = 0xFFFFFFFF; /* no sequencing in anchor */
2850 ddf->anchor.crc = calc_crc(&ddf->anchor, 512);
2851
7f798aca 2852 if (!__write_ddf_structure(d, ddf, DDF_HEADER_PRIMARY,
2853 null_aligned))
175593bf 2854 continue;
a322f70c 2855
7f798aca 2856 if (!__write_ddf_structure(d, ddf, DDF_HEADER_SECONDARY,
2857 null_aligned))
175593bf 2858 continue;
a322f70c 2859
a322f70c 2860 lseek64(fd, (size-1)*512, SEEK_SET);
175593bf
DW
2861 if (write(fd, &ddf->anchor, 512) < 0)
2862 continue;
2863 successes++;
2864 }
42d5dfd9 2865 free(null_aligned);
175593bf 2866
175593bf 2867 return attempts != successes;
a322f70c 2868}
7a7cc504
NB
2869
2870static int write_init_super_ddf(struct supertype *st)
2871{
9b1fb677
DW
2872 struct ddf_super *ddf = st->sb;
2873 struct vcl *currentconf = ddf->currentconf;
2874
2875 /* we are done with currentconf reset it to point st at the container */
2876 ddf->currentconf = NULL;
edd8d13c
NB
2877
2878 if (st->update_tail) {
2879 /* queue the virtual_disk and vd_config as metadata updates */
2880 struct virtual_disk *vd;
2881 struct vd_config *vc;
edd8d13c
NB
2882 int len;
2883
9b1fb677 2884 if (!currentconf) {
2cc2983d
N
2885 int len = (sizeof(struct phys_disk) +
2886 sizeof(struct phys_disk_entry));
2887
2888 /* adding a disk to the container. */
2889 if (!ddf->add_list)
2890 return 0;
2891
2892 append_metadata_update(st, ddf->add_list->mdupdate, len);
2893 ddf->add_list->mdupdate = NULL;
2894 return 0;
2895 }
2896
2897 /* Newly created VD */
2898
edd8d13c
NB
2899 /* First the virtual disk. We have a slightly fake header */
2900 len = sizeof(struct virtual_disk) + sizeof(struct virtual_entry);
503975b9 2901 vd = xmalloc(len);
edd8d13c 2902 *vd = *ddf->virt;
9b1fb677
DW
2903 vd->entries[0] = ddf->virt->entries[currentconf->vcnum];
2904 vd->populated_vdes = __cpu_to_be16(currentconf->vcnum);
edd8d13c
NB
2905 append_metadata_update(st, vd, len);
2906
2907 /* Then the vd_config */
2908 len = ddf->conf_rec_len * 512;
503975b9 2909 vc = xmalloc(len);
9b1fb677 2910 memcpy(vc, &currentconf->conf, len);
edd8d13c
NB
2911 append_metadata_update(st, vc, len);
2912
2913 /* FIXME I need to close the fds! */
2914 return 0;
613b0d17 2915 } else {
d682f344
N
2916 struct dl *d;
2917 for (d = ddf->dlist; d; d=d->next)
ba728be7 2918 while (Kill(d->devname, NULL, 0, -1, 1) == 0);
1cc7f4fe 2919 return __write_init_super_ddf(st);
d682f344 2920 }
7a7cc504
NB
2921}
2922
a322f70c
DW
2923#endif
2924
387fcd59
N
2925static __u64 avail_size_ddf(struct supertype *st, __u64 devsize,
2926 unsigned long long data_offset)
a322f70c
DW
2927{
2928 /* We must reserve the last 32Meg */
2929 if (devsize <= 32*1024*2)
2930 return 0;
2931 return devsize - 32*1024*2;
2932}
2933
2934#ifndef MDASSEMBLE
8592f29d
N
2935
2936static int reserve_space(struct supertype *st, int raiddisks,
2937 unsigned long long size, int chunk,
2938 unsigned long long *freesize)
2939{
2940 /* Find 'raiddisks' spare extents at least 'size' big (but
2941 * only caring about multiples of 'chunk') and remember
2942 * them.
2943 * If the cannot be found, fail.
2944 */
2945 struct dl *dl;
2946 struct ddf_super *ddf = st->sb;
2947 int cnt = 0;
2948
2949 for (dl = ddf->dlist; dl ; dl=dl->next) {
613b0d17 2950 dl->raiddisk = -1;
8592f29d
N
2951 dl->esize = 0;
2952 }
2953 /* Now find largest extent on each device */
2954 for (dl = ddf->dlist ; dl ; dl=dl->next) {
2955 struct extent *e = get_extents(ddf, dl);
2956 unsigned long long pos = 0;
2957 int i = 0;
2958 int found = 0;
2959 unsigned long long minsize = size;
2960
2961 if (size == 0)
2962 minsize = chunk;
2963
2964 if (!e)
2965 continue;
2966 do {
2967 unsigned long long esize;
2968 esize = e[i].start - pos;
2969 if (esize >= minsize) {
2970 found = 1;
2971 minsize = esize;
2972 }
2973 pos = e[i].start + e[i].size;
2974 i++;
2975 } while (e[i-1].size);
2976 if (found) {
2977 cnt++;
2978 dl->esize = minsize;
2979 }
2980 free(e);
2981 }
2982 if (cnt < raiddisks) {
e7b84f9d 2983 pr_err("not enough devices with space to create array.\n");
8592f29d
N
2984 return 0; /* No enough free spaces large enough */
2985 }
2986 if (size == 0) {
2987 /* choose the largest size of which there are at least 'raiddisk' */
2988 for (dl = ddf->dlist ; dl ; dl=dl->next) {
2989 struct dl *dl2;
2990 if (dl->esize <= size)
2991 continue;
2992 /* This is bigger than 'size', see if there are enough */
2993 cnt = 0;
7b80ad6a 2994 for (dl2 = ddf->dlist; dl2 ; dl2=dl2->next)
8592f29d
N
2995 if (dl2->esize >= dl->esize)
2996 cnt++;
2997 if (cnt >= raiddisks)
2998 size = dl->esize;
2999 }
3000 if (chunk) {
3001 size = size / chunk;
3002 size *= chunk;
3003 }
3004 *freesize = size;
3005 if (size < 32) {
e7b84f9d 3006 pr_err("not enough spare devices to create array.\n");
8592f29d
N
3007 return 0;
3008 }
3009 }
3010 /* We have a 'size' of which there are enough spaces.
3011 * We simply do a first-fit */
3012 cnt = 0;
3013 for (dl = ddf->dlist ; dl && cnt < raiddisks ; dl=dl->next) {
3014 if (dl->esize < size)
3015 continue;
613b0d17 3016
8592f29d
N
3017 dl->raiddisk = cnt;
3018 cnt++;
3019 }
3020 return 1;
3021}
3022
2c514b71
NB
3023static int
3024validate_geometry_ddf_container(struct supertype *st,
3025 int level, int layout, int raiddisks,
3026 int chunk, unsigned long long size,
af4348dd 3027 unsigned long long data_offset,
2c514b71
NB
3028 char *dev, unsigned long long *freesize,
3029 int verbose);
78e44928
NB
3030
3031static int validate_geometry_ddf_bvd(struct supertype *st,
3032 int level, int layout, int raiddisks,
c21e737b 3033 int *chunk, unsigned long long size,
af4348dd 3034 unsigned long long data_offset,
2c514b71
NB
3035 char *dev, unsigned long long *freesize,
3036 int verbose);
78e44928
NB
3037
3038static int validate_geometry_ddf(struct supertype *st,
2c514b71 3039 int level, int layout, int raiddisks,
c21e737b 3040 int *chunk, unsigned long long size,
af4348dd 3041 unsigned long long data_offset,
2c514b71
NB
3042 char *dev, unsigned long long *freesize,
3043 int verbose)
a322f70c
DW
3044{
3045 int fd;
3046 struct mdinfo *sra;
3047 int cfd;
3048
3049 /* ddf potentially supports lots of things, but it depends on
3050 * what devices are offered (and maybe kernel version?)
3051 * If given unused devices, we will make a container.
3052 * If given devices in a container, we will make a BVD.
3053 * If given BVDs, we make an SVD, changing all the GUIDs in the process.
3054 */
3055
bb7295f1
N
3056 if (chunk && *chunk == UnSet)
3057 *chunk = DEFAULT_CHUNK;
3058
542ef4ec 3059 if (level == -1000000) level = LEVEL_CONTAINER;
a322f70c 3060 if (level == LEVEL_CONTAINER) {
78e44928
NB
3061 /* Must be a fresh device to add to a container */
3062 return validate_geometry_ddf_container(st, level, layout,
c21e737b 3063 raiddisks, chunk?*chunk:0,
af4348dd
N
3064 size, data_offset, dev,
3065 freesize,
2c514b71 3066 verbose);
5f8097be
NB
3067 }
3068
78e44928 3069 if (!dev) {
a3163bf0 3070 mdu_array_info_t array = {
3071 .level = level, .layout = layout,
3072 .raid_disks = raiddisks
3073 };
3074 struct vd_config conf;
3075 if (layout_md2ddf(&array, &conf) == -1) {
b42f577a 3076 if (verbose)
94b08b7c 3077 pr_err("DDF does not support level %d /layout %d arrays with %d disks\n",
3078 level, layout, raiddisks);
78e44928 3079 return 0;
b42f577a 3080 }
78e44928 3081 /* Should check layout? etc */
8592f29d
N
3082
3083 if (st->sb && freesize) {
3084 /* --create was given a container to create in.
3085 * So we need to check that there are enough
3086 * free spaces and return the amount of space.
3087 * We may as well remember which drives were
3088 * chosen so that add_to_super/getinfo_super
3089 * can return them.
3090 */
c21e737b 3091 return reserve_space(st, raiddisks, size, chunk?*chunk:0, freesize);
8592f29d 3092 }
a322f70c 3093 return 1;
78e44928 3094 }
a322f70c 3095
8592f29d
N
3096 if (st->sb) {
3097 /* A container has already been opened, so we are
3098 * creating in there. Maybe a BVD, maybe an SVD.
3099 * Should make a distinction one day.
3100 */
3101 return validate_geometry_ddf_bvd(st, level, layout, raiddisks,
af4348dd
N
3102 chunk, size, data_offset, dev,
3103 freesize,
8592f29d
N
3104 verbose);
3105 }
78e44928
NB
3106 /* This is the first device for the array.
3107 * If it is a container, we read it in and do automagic allocations,
3108 * no other devices should be given.
3109 * Otherwise it must be a member device of a container, and we
3110 * do manual allocation.
3111 * Later we should check for a BVD and make an SVD.
a322f70c 3112 */
a322f70c
DW
3113 fd = open(dev, O_RDONLY|O_EXCL, 0);
3114 if (fd >= 0) {
4dd2df09 3115 sra = sysfs_read(fd, NULL, GET_VERSION);
a322f70c
DW
3116 close(fd);
3117 if (sra && sra->array.major_version == -1 &&
78e44928
NB
3118 strcmp(sra->text_version, "ddf") == 0) {
3119
3120 /* load super */
3121 /* find space for 'n' devices. */
3122 /* remember the devices */
3123 /* Somehow return the fact that we have enough */
a322f70c
DW
3124 }
3125
2c514b71 3126 if (verbose)
e7b84f9d
N
3127 pr_err("ddf: Cannot create this array "
3128 "on device %s - a container is required.\n",
3129 dev);
a322f70c
DW
3130 return 0;
3131 }
3132 if (errno != EBUSY || (fd = open(dev, O_RDONLY, 0)) < 0) {
2c514b71 3133 if (verbose)
e7b84f9d 3134 pr_err("ddf: Cannot open %s: %s\n",
613b0d17 3135 dev, strerror(errno));
a322f70c
DW
3136 return 0;
3137 }
3138 /* Well, it is in use by someone, maybe a 'ddf' container. */
3139 cfd = open_container(fd);
3140 if (cfd < 0) {
3141 close(fd);
2c514b71 3142 if (verbose)
e7b84f9d 3143 pr_err("ddf: Cannot use %s: %s\n",
613b0d17 3144 dev, strerror(EBUSY));
a322f70c
DW
3145 return 0;
3146 }
4dd2df09 3147 sra = sysfs_read(cfd, NULL, GET_VERSION);
a322f70c
DW
3148 close(fd);
3149 if (sra && sra->array.major_version == -1 &&
3150 strcmp(sra->text_version, "ddf") == 0) {
3151 /* This is a member of a ddf container. Load the container
3152 * and try to create a bvd
3153 */
3154 struct ddf_super *ddf;
e1902a7b 3155 if (load_super_ddf_all(st, cfd, (void **)&ddf, NULL) == 0) {
5f8097be 3156 st->sb = ddf;
4dd2df09 3157 strcpy(st->container_devnm, fd2devnm(cfd));
a322f70c 3158 close(cfd);
78e44928 3159 return validate_geometry_ddf_bvd(st, level, layout,
a322f70c 3160 raiddisks, chunk, size,
af4348dd 3161 data_offset,
2c514b71
NB
3162 dev, freesize,
3163 verbose);
a322f70c
DW
3164 }
3165 close(cfd);
c42ec1ed
DW
3166 } else /* device may belong to a different container */
3167 return 0;
3168
a322f70c
DW
3169 return 1;
3170}
3171
2c514b71
NB
3172static int
3173validate_geometry_ddf_container(struct supertype *st,
3174 int level, int layout, int raiddisks,
3175 int chunk, unsigned long long size,
af4348dd 3176 unsigned long long data_offset,
2c514b71
NB
3177 char *dev, unsigned long long *freesize,
3178 int verbose)
a322f70c
DW
3179{
3180 int fd;
3181 unsigned long long ldsize;
3182
3183 if (level != LEVEL_CONTAINER)
3184 return 0;
3185 if (!dev)
3186 return 1;
3187
3188 fd = open(dev, O_RDONLY|O_EXCL, 0);
3189 if (fd < 0) {
2c514b71 3190 if (verbose)
e7b84f9d 3191 pr_err("ddf: Cannot open %s: %s\n",
613b0d17 3192 dev, strerror(errno));
a322f70c
DW
3193 return 0;
3194 }
3195 if (!get_dev_size(fd, dev, &ldsize)) {
3196 close(fd);
3197 return 0;
3198 }
3199 close(fd);
3200
387fcd59 3201 *freesize = avail_size_ddf(st, ldsize >> 9, INVALID_SECTORS);
ea17e7aa
N
3202 if (*freesize == 0)
3203 return 0;
a322f70c
DW
3204
3205 return 1;
3206}
3207
78e44928
NB
3208static int validate_geometry_ddf_bvd(struct supertype *st,
3209 int level, int layout, int raiddisks,
c21e737b 3210 int *chunk, unsigned long long size,
af4348dd 3211 unsigned long long data_offset,
2c514b71
NB
3212 char *dev, unsigned long long *freesize,
3213 int verbose)
a322f70c
DW
3214{
3215 struct stat stb;
3216 struct ddf_super *ddf = st->sb;
3217 struct dl *dl;
5f8097be
NB
3218 unsigned long long pos = 0;
3219 unsigned long long maxsize;
3220 struct extent *e;
3221 int i;
a322f70c 3222 /* ddf/bvd supports lots of things, but not containers */
b42f577a
N
3223 if (level == LEVEL_CONTAINER) {
3224 if (verbose)
e7b84f9d 3225 pr_err("DDF cannot create a container within an container\n");
a322f70c 3226 return 0;
b42f577a 3227 }
a322f70c
DW
3228 /* We must have the container info already read in. */
3229 if (!ddf)
3230 return 0;
3231
5f8097be
NB
3232 if (!dev) {
3233 /* General test: make sure there is space for
3234 * 'raiddisks' device extents of size 'size'.
3235 */
3236 unsigned long long minsize = size;
3237 int dcnt = 0;
3238 if (minsize == 0)
3239 minsize = 8;
3240 for (dl = ddf->dlist; dl ; dl = dl->next)
3241 {
3242 int found = 0;
7e1432fb 3243 pos = 0;
5f8097be
NB
3244
3245 i = 0;
3246 e = get_extents(ddf, dl);
3247 if (!e) continue;
3248 do {
3249 unsigned long long esize;
3250 esize = e[i].start - pos;
3251 if (esize >= minsize)
3252 found = 1;
3253 pos = e[i].start + e[i].size;
3254 i++;
3255 } while (e[i-1].size);
3256 if (found)
3257 dcnt++;
3258 free(e);
3259 }
3260 if (dcnt < raiddisks) {
2c514b71 3261 if (verbose)
e7b84f9d
N
3262 pr_err("ddf: Not enough devices with "
3263 "space for this array (%d < %d)\n",
3264 dcnt, raiddisks);
5f8097be
NB
3265 return 0;
3266 }
3267 return 1;
3268 }
a322f70c
DW
3269 /* This device must be a member of the set */
3270 if (stat(dev, &stb) < 0)
3271 return 0;
3272 if ((S_IFMT & stb.st_mode) != S_IFBLK)
3273 return 0;
3274 for (dl = ddf->dlist ; dl ; dl = dl->next) {
f21e18ca
N
3275 if (dl->major == (int)major(stb.st_rdev) &&
3276 dl->minor == (int)minor(stb.st_rdev))
a322f70c
DW
3277 break;
3278 }
5f8097be 3279 if (!dl) {
2c514b71 3280 if (verbose)
e7b84f9d 3281 pr_err("ddf: %s is not in the "
613b0d17
N
3282 "same DDF set\n",
3283 dev);
5f8097be
NB
3284 return 0;
3285 }
3286 e = get_extents(ddf, dl);
3287 maxsize = 0;
3288 i = 0;
3289 if (e) do {
613b0d17
N
3290 unsigned long long esize;
3291 esize = e[i].start - pos;
3292 if (esize >= maxsize)
3293 maxsize = esize;
3294 pos = e[i].start + e[i].size;
3295 i++;
3296 } while (e[i-1].size);
5f8097be 3297 *freesize = maxsize;
a322f70c
DW
3298 // FIXME here I am
3299
3300 return 1;
3301}
59e36268 3302
a322f70c 3303static int load_super_ddf_all(struct supertype *st, int fd,
e1902a7b 3304 void **sbp, char *devname)
a322f70c
DW
3305{
3306 struct mdinfo *sra;
3307 struct ddf_super *super;
3308 struct mdinfo *sd, *best = NULL;
3309 int bestseq = 0;
3310 int seq;
3311 char nm[20];
3312 int dfd;
3313
b526e52d 3314 sra = sysfs_read(fd, 0, GET_LEVEL|GET_VERSION|GET_DEVS|GET_STATE);
a322f70c
DW
3315 if (!sra)
3316 return 1;
3317 if (sra->array.major_version != -1 ||
3318 sra->array.minor_version != -2 ||
3319 strcmp(sra->text_version, "ddf") != 0)
3320 return 1;
3321
6416d527 3322 if (posix_memalign((void**)&super, 512, sizeof(*super)) != 0)
a322f70c 3323 return 1;
a2349791 3324 memset(super, 0, sizeof(*super));
a322f70c
DW
3325
3326 /* first, try each device, and choose the best ddf */
3327 for (sd = sra->devs ; sd ; sd = sd->next) {
3328 int rv;
3329 sprintf(nm, "%d:%d", sd->disk.major, sd->disk.minor);
7a7cc504
NB
3330 dfd = dev_open(nm, O_RDONLY);
3331 if (dfd < 0)
a322f70c
DW
3332 return 2;
3333 rv = load_ddf_headers(dfd, super, NULL);
7a7cc504 3334 close(dfd);
a322f70c
DW
3335 if (rv == 0) {
3336 seq = __be32_to_cpu(super->active->seq);
3337 if (super->active->openflag)
3338 seq--;
3339 if (!best || seq > bestseq) {
3340 bestseq = seq;
3341 best = sd;
3342 }
3343 }
3344 }
3345 if (!best)
3346 return 1;
3347 /* OK, load this ddf */
3348 sprintf(nm, "%d:%d", best->disk.major, best->disk.minor);
3349 dfd = dev_open(nm, O_RDONLY);
7a7cc504 3350 if (dfd < 0)
a322f70c
DW
3351 return 1;
3352 load_ddf_headers(dfd, super, NULL);
3353 load_ddf_global(dfd, super, NULL);
3354 close(dfd);
3355 /* Now we need the device-local bits */
3356 for (sd = sra->devs ; sd ; sd = sd->next) {
3d2c4fc7
DW
3357 int rv;
3358
a322f70c 3359 sprintf(nm, "%d:%d", sd->disk.major, sd->disk.minor);
e1902a7b 3360 dfd = dev_open(nm, O_RDWR);
7a7cc504 3361 if (dfd < 0)
a322f70c 3362 return 2;
3d2c4fc7
DW
3363 rv = load_ddf_headers(dfd, super, NULL);
3364 if (rv == 0)
e1902a7b 3365 rv = load_ddf_local(dfd, super, NULL, 1);
3d2c4fc7
DW
3366 if (rv)
3367 return 1;
a322f70c 3368 }
33414a01 3369
a322f70c
DW
3370 *sbp = super;
3371 if (st->ss == NULL) {
78e44928 3372 st->ss = &super_ddf;
a322f70c
DW
3373 st->minor_version = 0;
3374 st->max_devs = 512;
3375 }
4dd2df09 3376 strcpy(st->container_devnm, fd2devnm(fd));
a322f70c
DW
3377 return 0;
3378}
2b959fbf
N
3379
3380static int load_container_ddf(struct supertype *st, int fd,
3381 char *devname)
3382{
3383 return load_super_ddf_all(st, fd, &st->sb, devname);
3384}
3385
0e600426 3386#endif /* MDASSEMBLE */
a322f70c 3387
a5c7adb3 3388static int check_secondary(const struct vcl *vc)
3389{
3390 const struct vd_config *conf = &vc->conf;
3391 int i;
3392
3393 /* The only DDF secondary RAID level md can support is
3394 * RAID 10, if the stripe sizes and Basic volume sizes
3395 * are all equal.
3396 * Other configurations could in theory be supported by exposing
3397 * the BVDs to user space and using device mapper for the secondary
3398 * mapping. So far we don't support that.
3399 */
3400
3401 __u64 sec_elements[4] = {0, 0, 0, 0};
3402#define __set_sec_seen(n) (sec_elements[(n)>>6] |= (1<<((n)&63)))
3403#define __was_sec_seen(n) ((sec_elements[(n)>>6] & (1<<((n)&63))) != 0)
3404
3405 if (vc->other_bvds == NULL) {
3406 pr_err("No BVDs for secondary RAID found\n");
3407 return -1;
3408 }
3409 if (conf->prl != DDF_RAID1) {
3410 pr_err("Secondary RAID level only supported for mirrored BVD\n");
3411 return -1;
3412 }
3413 if (conf->srl != DDF_2STRIPED && conf->srl != DDF_2SPANNED) {
3414 pr_err("Secondary RAID level %d is unsupported\n",
3415 conf->srl);
3416 return -1;
3417 }
3418 __set_sec_seen(conf->sec_elmnt_seq);
3419 for (i = 0; i < conf->sec_elmnt_count-1; i++) {
3420 const struct vd_config *bvd = vc->other_bvds[i];
3c48f7be 3421 if (bvd->sec_elmnt_seq == DDF_UNUSED_BVD)
c98567ba 3422 continue;
a5c7adb3 3423 if (bvd->srl != conf->srl) {
3424 pr_err("Inconsistent secondary RAID level across BVDs\n");
3425 return -1;
3426 }
3427 if (bvd->prl != conf->prl) {
3428 pr_err("Different RAID levels for BVDs are unsupported\n");
3429 return -1;
3430 }
3431 if (bvd->prim_elmnt_count != conf->prim_elmnt_count) {
3432 pr_err("All BVDs must have the same number of primary elements\n");
3433 return -1;
3434 }
3435 if (bvd->chunk_shift != conf->chunk_shift) {
3436 pr_err("Different strip sizes for BVDs are unsupported\n");
3437 return -1;
3438 }
3439 if (bvd->array_blocks != conf->array_blocks) {
3440 pr_err("Different BVD sizes are unsupported\n");
3441 return -1;
3442 }
3443 __set_sec_seen(bvd->sec_elmnt_seq);
3444 }
3445 for (i = 0; i < conf->sec_elmnt_count; i++) {
3446 if (!__was_sec_seen(i)) {
3447 pr_err("BVD %d is missing\n", i);
3448 return -1;
3449 }
3450 }
3451 return 0;
3452}
3453
8a38db86 3454static unsigned int get_pd_index_from_refnum(const struct vcl *vc,
4e587018 3455 __u32 refnum, unsigned int nmax,
3456 const struct vd_config **bvd,
3457 unsigned int *idx)
8a38db86 3458{
4e587018 3459 unsigned int i, j, n, sec, cnt;
3460
3461 cnt = __be16_to_cpu(vc->conf.prim_elmnt_count);
3462 sec = (vc->conf.sec_elmnt_count == 1 ? 0 : vc->conf.sec_elmnt_seq);
3463
3464 for (i = 0, j = 0 ; i < nmax ; i++) {
3465 /* j counts valid entries for this BVD */
3466 if (vc->conf.phys_refnum[i] != 0xffffffff)
3467 j++;
3468 if (vc->conf.phys_refnum[i] == refnum) {
3469 *bvd = &vc->conf;
3470 *idx = i;
3471 return sec * cnt + j - 1;
3472 }
3473 }
3474 if (vc->other_bvds == NULL)
3475 goto bad;
3476
3477 for (n = 1; n < vc->conf.sec_elmnt_count; n++) {
3478 struct vd_config *vd = vc->other_bvds[n-1];
4e587018 3479 sec = vd->sec_elmnt_seq;
3c48f7be 3480 if (sec == DDF_UNUSED_BVD)
3481 continue;
4e587018 3482 for (i = 0, j = 0 ; i < nmax ; i++) {
3483 if (vd->phys_refnum[i] != 0xffffffff)
3484 j++;
3485 if (vd->phys_refnum[i] == refnum) {
3486 *bvd = vd;
3487 *idx = i;
3488 return sec * cnt + j - 1;
3489 }
3490 }
3491 }
3492bad:
3493 *bvd = NULL;
d6e7b083 3494 return DDF_NOTFOUND;
8a38db86 3495}
3496
00bbdbda 3497static struct mdinfo *container_content_ddf(struct supertype *st, char *subarray)
598f0d58
NB
3498{
3499 /* Given a container loaded by load_super_ddf_all,
3500 * extract information about all the arrays into
3501 * an mdinfo tree.
3502 *
3503 * For each vcl in conflist: create an mdinfo, fill it in,
3504 * then look for matching devices (phys_refnum) in dlist
3505 * and create appropriate device mdinfo.
3506 */
3507 struct ddf_super *ddf = st->sb;
3508 struct mdinfo *rest = NULL;
3509 struct vcl *vc;
3510
3511 for (vc = ddf->conflist ; vc ; vc=vc->next)
3512 {
f21e18ca
N
3513 unsigned int i;
3514 unsigned int j;
598f0d58 3515 struct mdinfo *this;
00bbdbda 3516 char *ep;
90fa1a29 3517 __u32 *cptr;
8a38db86 3518 unsigned int pd;
00bbdbda
N
3519
3520 if (subarray &&
3521 (strtoul(subarray, &ep, 10) != vc->vcnum ||
3522 *ep != '\0'))
3523 continue;
3524
a5c7adb3 3525 if (vc->conf.sec_elmnt_count > 1) {
3526 if (check_secondary(vc) != 0)
3527 continue;
3528 }
3529
503975b9 3530 this = xcalloc(1, sizeof(*this));
598f0d58
NB
3531 this->next = rest;
3532 rest = this;
3533
8a2848a7 3534 if (layout_ddf2md(&vc->conf, &this->array))
3535 continue;
598f0d58 3536 this->array.md_minor = -1;
f35f2525
N
3537 this->array.major_version = -1;
3538 this->array.minor_version = -2;
90fa1a29
JS
3539 cptr = (__u32 *)(vc->conf.guid + 16);
3540 this->array.ctime = DECADE + __be32_to_cpu(*cptr);
598f0d58
NB
3541 this->array.utime = DECADE +
3542 __be32_to_cpu(vc->conf.timestamp);
3543 this->array.chunk_size = 512 << vc->conf.chunk_shift;
3544
59e36268 3545 i = vc->vcnum;
7a7cc504
NB
3546 if ((ddf->virt->entries[i].state & DDF_state_inconsistent) ||
3547 (ddf->virt->entries[i].init_state & DDF_initstate_mask) !=
ed9d66aa 3548 DDF_init_full) {
598f0d58 3549 this->array.state = 0;
ed9d66aa
NB
3550 this->resync_start = 0;
3551 } else {
598f0d58 3552 this->array.state = 1;
b7528a20 3553 this->resync_start = MaxSector;
ed9d66aa 3554 }
db42fa9b
N
3555 memcpy(this->name, ddf->virt->entries[i].name, 16);
3556 this->name[16]=0;
3557 for(j=0; j<16; j++)
3558 if (this->name[j] == ' ')
3559 this->name[j] = 0;
598f0d58
NB
3560
3561 memset(this->uuid, 0, sizeof(this->uuid));
3562 this->component_size = __be64_to_cpu(vc->conf.blocks);
3563 this->array.size = this->component_size / 2;
5f2aace8 3564 this->container_member = i;
598f0d58 3565
c5afc314
N
3566 ddf->currentconf = vc;
3567 uuid_from_super_ddf(st, this->uuid);
3568 ddf->currentconf = NULL;
3569
60f18132 3570 sprintf(this->text_version, "/%s/%d",
4dd2df09 3571 st->container_devnm, this->container_member);
60f18132 3572
8a38db86 3573 for (pd = 0; pd < __be16_to_cpu(ddf->phys->used_pdes); pd++) {
598f0d58
NB
3574 struct mdinfo *dev;
3575 struct dl *d;
4e587018 3576 const struct vd_config *bvd;
3577 unsigned int iphys;
3578 __u64 *lba_offset;
fa033bec 3579 int stt;
598f0d58 3580
8a38db86 3581 if (ddf->phys->entries[pd].refnum == 0xFFFFFFFF)
bc17324f 3582 continue;
0cf5ef67
N
3583
3584 stt = __be16_to_cpu(ddf->phys->entries[pd].state);
fa033bec
N
3585 if ((stt & (DDF_Online|DDF_Failed|DDF_Rebuilding))
3586 != DDF_Online)
3587 continue;
3588
8a38db86 3589 i = get_pd_index_from_refnum(
4e587018 3590 vc, ddf->phys->entries[pd].refnum,
3591 ddf->mppe, &bvd, &iphys);
d6e7b083 3592 if (i == DDF_NOTFOUND)
8a38db86 3593 continue;
3594
fa033bec 3595 this->array.working_disks++;
bc17324f 3596
0cf5ef67 3597 for (d = ddf->dlist; d ; d=d->next)
8a38db86 3598 if (d->disk.refnum ==
3599 ddf->phys->entries[pd].refnum)
0cf5ef67
N
3600 break;
3601 if (d == NULL)
3602 /* Haven't found that one yet, maybe there are others */
3603 continue;
3604
503975b9 3605 dev = xcalloc(1, sizeof(*dev));
598f0d58
NB
3606 dev->next = this->devs;
3607 this->devs = dev;
3608
3609 dev->disk.number = __be32_to_cpu(d->disk.refnum);
3610 dev->disk.major = d->major;
3611 dev->disk.minor = d->minor;
3612 dev->disk.raid_disk = i;
3613 dev->disk.state = (1<<MD_DISK_SYNC)|(1<<MD_DISK_ACTIVE);
d23534e4 3614 dev->recovery_start = MaxSector;
598f0d58 3615
120f7677 3616 dev->events = __be32_to_cpu(ddf->primary.seq);
4e587018 3617 lba_offset = (__u64 *)&bvd->phys_refnum[ddf->mppe];
3618 dev->data_offset = __be64_to_cpu(lba_offset[iphys]);
3619 dev->component_size = __be64_to_cpu(bvd->blocks);
598f0d58
NB
3620 if (d->devname)
3621 strcpy(dev->name, d->devname);
3622 }
3623 }
3624 return rest;
3625}
3626
955e9ea1 3627static int store_super_ddf(struct supertype *st, int fd)
a322f70c 3628{
955e9ea1 3629 struct ddf_super *ddf = st->sb;
a322f70c 3630 unsigned long long dsize;
6416d527 3631 void *buf;
3d2c4fc7 3632 int rc;
a322f70c 3633
955e9ea1
DW
3634 if (!ddf)
3635 return 1;
3636
a322f70c
DW
3637 if (!get_dev_size(fd, NULL, &dsize))
3638 return 1;
3639
dbf98368 3640 if (ddf->dlist || ddf->conflist) {
3641 struct stat sta;
3642 struct dl *dl;
3643 int ofd, ret;
3644
3645 if (fstat(fd, &sta) == -1 || !S_ISBLK(sta.st_mode)) {
3646 pr_err("%s: file descriptor for invalid device\n",
3647 __func__);
3648 return 1;
3649 }
3650 for (dl = ddf->dlist; dl; dl = dl->next)
3651 if (dl->major == (int)major(sta.st_rdev) &&
3652 dl->minor == (int)minor(sta.st_rdev))
3653 break;
3654 if (!dl) {
3655 pr_err("%s: couldn't find disk %d/%d\n", __func__,
3656 (int)major(sta.st_rdev),
3657 (int)minor(sta.st_rdev));
3658 return 1;
3659 }
3660 /*
3661 For DDF, writing to just one disk makes no sense.
3662 We would run the risk of writing inconsistent meta data
3663 to the devices. So just call __write_init_super_ddf and
3664 write to all devices, including this one.
3665 Use the fd passed to this function, just in case dl->fd
3666 is invalid.
3667 */
3668 ofd = dl->fd;
3669 dl->fd = fd;
3670 ret = __write_init_super_ddf(st);
3671 dl->fd = ofd;
3672 return ret;
3673 }
3674
3d2c4fc7
DW
3675 if (posix_memalign(&buf, 512, 512) != 0)
3676 return 1;
6416d527
NB
3677 memset(buf, 0, 512);
3678
a322f70c 3679 lseek64(fd, dsize-512, 0);
3d2c4fc7 3680 rc = write(fd, buf, 512);
6416d527 3681 free(buf);
3d2c4fc7
DW
3682 if (rc < 0)
3683 return 1;
a322f70c
DW
3684 return 0;
3685}
3686
a19c88b8
NB
3687static int compare_super_ddf(struct supertype *st, struct supertype *tst)
3688{
3689 /*
3690 * return:
3691 * 0 same, or first was empty, and second was copied
3692 * 1 second had wrong number
3693 * 2 wrong uuid
3694 * 3 wrong other info
3695 */
3696 struct ddf_super *first = st->sb;
3697 struct ddf_super *second = tst->sb;
4eefd651 3698 struct dl *dl1, *dl2;
3699 struct vcl *vl1, *vl2;
2d210697 3700 unsigned int max_vds, max_pds, pd, vd;
a19c88b8
NB
3701
3702 if (!first) {
3703 st->sb = tst->sb;
3704 tst->sb = NULL;
3705 return 0;
3706 }
3707
3708 if (memcmp(first->anchor.guid, second->anchor.guid, DDF_GUID_LEN) != 0)
3709 return 2;
3710
2d210697 3711 if (first->anchor.seq != second->anchor.seq) {
3712 dprintf("%s: sequence number mismatch %u/%u\n", __func__,
3713 __be32_to_cpu(first->anchor.seq),
3714 __be32_to_cpu(second->anchor.seq));
3715 return 3;
3716 }
3717 if (first->max_part != second->max_part ||
3718 first->phys->used_pdes != second->phys->used_pdes ||
3719 first->virt->populated_vdes != second->virt->populated_vdes) {
3720 dprintf("%s: PD/VD number mismatch\n", __func__);
3721 return 3;
3722 }
3723
3724 max_pds = __be16_to_cpu(first->phys->used_pdes);
3725 for (dl2 = second->dlist; dl2; dl2 = dl2->next) {
3726 for (pd = 0; pd < max_pds; pd++)
3727 if (first->phys->entries[pd].refnum == dl2->disk.refnum)
3728 break;
3729 if (pd == max_pds) {
3730 dprintf("%s: no match for disk %08x\n", __func__,
3731 __be32_to_cpu(dl2->disk.refnum));
3732 return 3;
3733 }
3734 }
3735
3736 max_vds = __be16_to_cpu(first->active->max_vd_entries);
3737 for (vl2 = second->conflist; vl2; vl2 = vl2->next) {
3738 if (vl2->conf.magic != DDF_VD_CONF_MAGIC)
3739 continue;
3740 for (vd = 0; vd < max_vds; vd++)
3741 if (!memcmp(first->virt->entries[vd].guid,
3742 vl2->conf.guid, DDF_GUID_LEN))
3743 break;
3744 if (vd == max_vds) {
3745 dprintf("%s: no match for VD config\n", __func__);
3746 return 3;
3747 }
3748 }
a19c88b8 3749 /* FIXME should I look at anything else? */
2d210697 3750
4eefd651 3751 /*
3752 At this point we are fairly sure that the meta data matches.
3753 But the new disk may contain additional local data.
3754 Add it to the super block.
3755 */
3756 for (vl2 = second->conflist; vl2; vl2 = vl2->next) {
3757 for (vl1 = first->conflist; vl1; vl1 = vl1->next)
3758 if (!memcmp(vl1->conf.guid, vl2->conf.guid,
3759 DDF_GUID_LEN))
3760 break;
3761 if (vl1) {
3762 if (vl1->other_bvds != NULL &&
3763 vl1->conf.sec_elmnt_seq !=
3764 vl2->conf.sec_elmnt_seq) {
3765 dprintf("%s: adding BVD %u\n", __func__,
3766 vl2->conf.sec_elmnt_seq);
3767 add_other_bvd(vl1, &vl2->conf,
3768 first->conf_rec_len*512);
3769 }
3770 continue;
3771 }
3772
3773 if (posix_memalign((void **)&vl1, 512,
3774 (first->conf_rec_len*512 +
3775 offsetof(struct vcl, conf))) != 0) {
3776 pr_err("%s could not allocate vcl buf\n",
3777 __func__);
3778 return 3;
3779 }
3780
3781 vl1->next = first->conflist;
3782 vl1->block_sizes = NULL;
4eefd651 3783 memcpy(&vl1->conf, &vl2->conf, first->conf_rec_len*512);
3c48f7be 3784 if (alloc_other_bvds(first, vl1) != 0) {
3785 pr_err("%s could not allocate other bvds\n",
3786 __func__);
3787 free(vl1);
3788 return 3;
3789 }
4eefd651 3790 vl1->lba_offset = (__u64 *)
3791 &vl1->conf.phys_refnum[first->mppe];
3792 for (vd = 0; vd < max_vds; vd++)
3793 if (!memcmp(first->virt->entries[vd].guid,
3794 vl1->conf.guid, DDF_GUID_LEN))
3795 break;
3796 vl1->vcnum = vd;
3797 dprintf("%s: added config for VD %u\n", __func__, vl1->vcnum);
3798 first->conflist = vl1;
3799 }
3800
3801 for (dl2 = second->dlist; dl2; dl2 = dl2->next) {
3802 for (dl1 = first->dlist; dl1; dl1 = dl1->next)
3803 if (dl1->disk.refnum == dl2->disk.refnum)
3804 break;
3805 if (dl1)
3806 continue;
3807
3808 if (posix_memalign((void **)&dl1, 512,
3809 sizeof(*dl1) + (first->max_part) * sizeof(dl1->vlist[0]))
3810 != 0) {
3811 pr_err("%s could not allocate disk info buffer\n",
3812 __func__);
3813 return 3;
3814 }
3815 memcpy(dl1, dl2, sizeof(*dl1));
3816 dl1->mdupdate = NULL;
3817 dl1->next = first->dlist;
3818 dl1->fd = -1;
3819 for (pd = 0; pd < max_pds; pd++)
3820 if (first->phys->entries[pd].refnum == dl1->disk.refnum)
3821 break;
3822 dl1->pdnum = pd;
3823 if (dl2->spare) {
3824 if (posix_memalign((void **)&dl1->spare, 512,
3825 first->conf_rec_len*512) != 0) {
3826 pr_err("%s could not allocate spare info buf\n",
3827 __func__);
3828 return 3;
3829 }
3830 memcpy(dl1->spare, dl2->spare, first->conf_rec_len*512);
3831 }
3832 for (vd = 0 ; vd < first->max_part ; vd++) {
3833 if (!dl2->vlist[vd]) {
3834 dl1->vlist[vd] = NULL;
3835 continue;
3836 }
3837 for (vl1 = first->conflist; vl1; vl1 = vl1->next) {
3838 if (!memcmp(vl1->conf.guid,
3839 dl2->vlist[vd]->conf.guid,
3840 DDF_GUID_LEN))
3841 break;
3842 dl1->vlist[vd] = vl1;
3843 }
3844 }
3845 first->dlist = dl1;
3846 dprintf("%s: added disk %d: %08x\n", __func__, dl1->pdnum,
3847 dl1->disk.refnum);
3848 }
3849
a19c88b8
NB
3850 return 0;
3851}
3852
0e600426 3853#ifndef MDASSEMBLE
4e5528c6
NB
3854/*
3855 * A new array 'a' has been started which claims to be instance 'inst'
3856 * within container 'c'.
3857 * We need to confirm that the array matches the metadata in 'c' so
3858 * that we don't corrupt any metadata.
3859 */
cba0191b 3860static int ddf_open_new(struct supertype *c, struct active_array *a, char *inst)
549e9569 3861{
a2aa439e 3862 struct ddf_super *ddf = c->sb;
3863 int n = atoi(inst);
fb9d0acb 3864 if (all_ff(ddf->virt->entries[n].guid)) {
3865 pr_err("%s: subarray %d doesn't exist\n", __func__, n);
a2aa439e 3866 return -ENODEV;
3867 }
3868 dprintf("ddf: open_new %d\n", n);
3869 a->info.container_member = n;
549e9569
NB
3870 return 0;
3871}
3872
4e5528c6
NB
3873/*
3874 * The array 'a' is to be marked clean in the metadata.
ed9d66aa 3875 * If '->resync_start' is not ~(unsigned long long)0, then the array is only
4e5528c6
NB
3876 * clean up to the point (in sectors). If that cannot be recorded in the
3877 * metadata, then leave it as dirty.
3878 *
3879 * For DDF, we need to clear the DDF_state_inconsistent bit in the
3880 * !global! virtual_disk.virtual_entry structure.
3881 */
01f157d7 3882static int ddf_set_array_state(struct active_array *a, int consistent)
549e9569 3883{
4e5528c6
NB
3884 struct ddf_super *ddf = a->container->sb;
3885 int inst = a->info.container_member;
18a2f463 3886 int old = ddf->virt->entries[inst].state;
01f157d7
N
3887 if (consistent == 2) {
3888 /* Should check if a recovery should be started FIXME */
3889 consistent = 1;
b7941fd6 3890 if (!is_resync_complete(&a->info))
01f157d7
N
3891 consistent = 0;
3892 }
ed9d66aa
NB
3893 if (consistent)
3894 ddf->virt->entries[inst].state &= ~DDF_state_inconsistent;
3895 else
4e5528c6 3896 ddf->virt->entries[inst].state |= DDF_state_inconsistent;
18a2f463 3897 if (old != ddf->virt->entries[inst].state)
7d5a7ff3 3898 ddf_set_updates_pending(ddf);
18a2f463
NB
3899
3900 old = ddf->virt->entries[inst].init_state;
ed9d66aa 3901 ddf->virt->entries[inst].init_state &= ~DDF_initstate_mask;
b7941fd6 3902 if (is_resync_complete(&a->info))
ed9d66aa 3903 ddf->virt->entries[inst].init_state |= DDF_init_full;
b7941fd6 3904 else if (a->info.resync_start == 0)
ed9d66aa 3905 ddf->virt->entries[inst].init_state |= DDF_init_not;
4e5528c6 3906 else
ed9d66aa 3907 ddf->virt->entries[inst].init_state |= DDF_init_quick;
18a2f463 3908 if (old != ddf->virt->entries[inst].init_state)
7d5a7ff3 3909 ddf_set_updates_pending(ddf);
ed9d66aa 3910
2c514b71 3911 dprintf("ddf mark %d %s %llu\n", inst, consistent?"clean":"dirty",
b7941fd6 3912 a->info.resync_start);
01f157d7 3913 return consistent;
fd7cde1b
DW
3914}
3915
5ec636b7 3916static int get_bvd_state(const struct ddf_super *ddf,
3917 const struct vd_config *vc)
3918{
3919 unsigned int i, n_bvd, working = 0;
3920 unsigned int n_prim = __be16_to_cpu(vc->prim_elmnt_count);
3921 int pd, st, state;
3922 for (i = 0; i < n_prim; i++) {
3923 if (!find_index_in_bvd(ddf, vc, i, &n_bvd))
3924 continue;
3925 pd = find_phys(ddf, vc->phys_refnum[n_bvd]);
3926 if (pd < 0)
3927 continue;
3928 st = __be16_to_cpu(ddf->phys->entries[pd].state);
3929 if ((st & (DDF_Online|DDF_Failed|DDF_Rebuilding))
3930 == DDF_Online)
3931 working++;
3932 }
3933
3934 state = DDF_state_degraded;
3935 if (working == n_prim)
3936 state = DDF_state_optimal;
3937 else
3938 switch (vc->prl) {
3939 case DDF_RAID0:
3940 case DDF_CONCAT:
3941 case DDF_JBOD:
3942 state = DDF_state_failed;
3943 break;
3944 case DDF_RAID1:
3945 if (working == 0)
3946 state = DDF_state_failed;
3947 else if (working >= 2)
3948 state = DDF_state_part_optimal;
3949 break;
3950 case DDF_RAID4:
3951 case DDF_RAID5:
3952 if (working < n_prim - 1)
3953 state = DDF_state_failed;
3954 break;
3955 case DDF_RAID6:
3956 if (working < n_prim - 2)
3957 state = DDF_state_failed;
3958 else if (working == n_prim - 1)
3959 state = DDF_state_part_optimal;
3960 break;
3961 }
3962 return state;
3963}
3964
0777d17d 3965static int secondary_state(int state, int other, int seclevel)
3966{
3967 if (state == DDF_state_optimal && other == DDF_state_optimal)
3968 return DDF_state_optimal;
3969 if (seclevel == DDF_2MIRRORED) {
3970 if (state == DDF_state_optimal || other == DDF_state_optimal)
3971 return DDF_state_part_optimal;
3972 if (state == DDF_state_failed && other == DDF_state_failed)
3973 return DDF_state_failed;
3974 return DDF_state_degraded;
3975 } else {
3976 if (state == DDF_state_failed || other == DDF_state_failed)
3977 return DDF_state_failed;
3978 if (state == DDF_state_degraded || other == DDF_state_degraded)
3979 return DDF_state_degraded;
3980 return DDF_state_part_optimal;
3981 }
3982}
3983
3984static int get_svd_state(const struct ddf_super *ddf, const struct vcl *vcl)
3985{
3986 int state = get_bvd_state(ddf, &vcl->conf);
3987 unsigned int i;
3988 for (i = 1; i < vcl->conf.sec_elmnt_count; i++) {
3989 state = secondary_state(
3990 state,
3991 get_bvd_state(ddf, vcl->other_bvds[i-1]),
3992 vcl->conf.srl);
3993 }
3994 return state;
3995}
3996
7a7cc504
NB
3997/*
3998 * The state of each disk is stored in the global phys_disk structure
3999 * in phys_disk.entries[n].state.
4000 * This makes various combinations awkward.
4001 * - When a device fails in any array, it must be failed in all arrays
4002 * that include a part of this device.
4003 * - When a component is rebuilding, we cannot include it officially in the
4004 * array unless this is the only array that uses the device.
4005 *
4006 * So: when transitioning:
4007 * Online -> failed, just set failed flag. monitor will propagate
4008 * spare -> online, the device might need to be added to the array.
4009 * spare -> failed, just set failed. Don't worry if in array or not.
4010 */
8d45d196 4011static void ddf_set_disk(struct active_array *a, int n, int state)
549e9569 4012{
7a7cc504 4013 struct ddf_super *ddf = a->container->sb;
baba3f4e 4014 unsigned int inst = a->info.container_member, n_bvd;
4015 struct vcl *vcl;
4016 struct vd_config *vc = find_vdcr(ddf, inst, (unsigned int)n,
4017 &n_bvd, &vcl);
4018 int pd;
e1316fab
N
4019 struct mdinfo *mdi;
4020 struct dl *dl;
7a7cc504
NB
4021
4022 if (vc == NULL) {
2c514b71 4023 dprintf("ddf: cannot find instance %d!!\n", inst);
7a7cc504
NB
4024 return;
4025 }
e1316fab
N
4026 /* Find the matching slot in 'info'. */
4027 for (mdi = a->info.devs; mdi; mdi = mdi->next)
4028 if (mdi->disk.raid_disk == n)
4029 break;
4030 if (!mdi)
4031 return;
4032
4033 /* and find the 'dl' entry corresponding to that. */
4034 for (dl = ddf->dlist; dl; dl = dl->next)
77632af9
N
4035 if (mdi->state_fd >= 0 &&
4036 mdi->disk.major == dl->major &&
e1316fab
N
4037 mdi->disk.minor == dl->minor)
4038 break;
4039 if (!dl)
4040 return;
4041
baba3f4e 4042 pd = find_phys(ddf, vc->phys_refnum[n_bvd]);
e1316fab
N
4043 if (pd < 0 || pd != dl->pdnum) {
4044 /* disk doesn't currently exist or has changed.
4045 * If it is now in_sync, insert it. */
baba3f4e 4046 dprintf("%s: phys disk not found for %d: %d/%d ref %08x\n",
4047 __func__, dl->pdnum, dl->major, dl->minor,
4048 dl->disk.refnum);
4049 dprintf("%s: array %u disk %u ref %08x pd %d\n",
4050 __func__, inst, n_bvd, vc->phys_refnum[n_bvd], pd);
7a7cc504 4051 if ((state & DS_INSYNC) && ! (state & DS_FAULTY)) {
baba3f4e 4052 __u64 *lba_offset;
4053 pd = dl->pdnum; /* FIXME: is this really correct ? */
4054 vc->phys_refnum[n_bvd] = dl->disk.refnum;
4055 lba_offset = (__u64 *)&vc->phys_refnum[ddf->mppe];
4056 lba_offset[n_bvd] = mdi->data_offset;
e1316fab
N
4057 ddf->phys->entries[pd].type &=
4058 ~__cpu_to_be16(DDF_Global_Spare);
4059 ddf->phys->entries[pd].type |=
4060 __cpu_to_be16(DDF_Active_in_VD);
7d5a7ff3 4061 ddf_set_updates_pending(ddf);
7a7cc504
NB
4062 }
4063 } else {
18a2f463 4064 int old = ddf->phys->entries[pd].state;
7a7cc504
NB
4065 if (state & DS_FAULTY)
4066 ddf->phys->entries[pd].state |= __cpu_to_be16(DDF_Failed);
4067 if (state & DS_INSYNC) {
4068 ddf->phys->entries[pd].state |= __cpu_to_be16(DDF_Online);
4069 ddf->phys->entries[pd].state &= __cpu_to_be16(~DDF_Rebuilding);
4070 }
18a2f463 4071 if (old != ddf->phys->entries[pd].state)
7d5a7ff3 4072 ddf_set_updates_pending(ddf);
7a7cc504
NB
4073 }
4074
2c514b71 4075 dprintf("ddf: set_disk %d to %x\n", n, state);
7e1432fb 4076
7a7cc504
NB
4077 /* Now we need to check the state of the array and update
4078 * virtual_disk.entries[n].state.
4079 * It needs to be one of "optimal", "degraded", "failed".
4080 * I don't understand 'deleted' or 'missing'.
4081 */
0777d17d 4082 state = get_svd_state(ddf, vcl);
7a7cc504 4083
18a2f463
NB
4084 if (ddf->virt->entries[inst].state !=
4085 ((ddf->virt->entries[inst].state & ~DDF_state_mask)
4086 | state)) {
4087
4088 ddf->virt->entries[inst].state =
4089 (ddf->virt->entries[inst].state & ~DDF_state_mask)
4090 | state;
7d5a7ff3 4091 ddf_set_updates_pending(ddf);
18a2f463 4092 }
7a7cc504 4093
549e9569
NB
4094}
4095
2e735d19 4096static void ddf_sync_metadata(struct supertype *st)
549e9569 4097{
7a7cc504
NB
4098
4099 /*
4100 * Write all data to all devices.
4101 * Later, we might be able to track whether only local changes
4102 * have been made, or whether any global data has been changed,
4103 * but ddf is sufficiently weird that it probably always
4104 * changes global data ....
4105 */
18a2f463
NB
4106 struct ddf_super *ddf = st->sb;
4107 if (!ddf->updates_pending)
4108 return;
4109 ddf->updates_pending = 0;
1cc7f4fe 4110 __write_init_super_ddf(st);
2c514b71 4111 dprintf("ddf: sync_metadata\n");
549e9569
NB
4112}
4113
88c164f4
NB
4114static void ddf_process_update(struct supertype *st,
4115 struct metadata_update *update)
4116{
4117 /* Apply this update to the metadata.
4118 * The first 4 bytes are a DDF_*_MAGIC which guides
4119 * our actions.
4120 * Possible update are:
4121 * DDF_PHYS_RECORDS_MAGIC
4dd968cc
N
4122 * Add a new physical device or remove an old one.
4123 * Changes to this record only happen implicitly.
88c164f4
NB
4124 * used_pdes is the device number.
4125 * DDF_VIRT_RECORDS_MAGIC
4126 * Add a new VD. Possibly also change the 'access' bits.
4127 * populated_vdes is the entry number.
4128 * DDF_VD_CONF_MAGIC
4129 * New or updated VD. the VIRT_RECORD must already
4130 * exist. For an update, phys_refnum and lba_offset
4131 * (at least) are updated, and the VD_CONF must
4132 * be written to precisely those devices listed with
4133 * a phys_refnum.
4134 * DDF_SPARE_ASSIGN_MAGIC
4135 * replacement Spare Assignment Record... but for which device?
4136 *
4137 * So, e.g.:
4138 * - to create a new array, we send a VIRT_RECORD and
4139 * a VD_CONF. Then assemble and start the array.
4140 * - to activate a spare we send a VD_CONF to add the phys_refnum
4141 * and offset. This will also mark the spare as active with
4142 * a spare-assignment record.
4143 */
4144 struct ddf_super *ddf = st->sb;
4145 __u32 *magic = (__u32*)update->buf;
4146 struct phys_disk *pd;
4147 struct virtual_disk *vd;
4148 struct vd_config *vc;
4149 struct vcl *vcl;
4150 struct dl *dl;
f21e18ca
N
4151 unsigned int mppe;
4152 unsigned int ent;
c7079c84 4153 unsigned int pdnum, pd2;
88c164f4 4154
2c514b71 4155 dprintf("Process update %x\n", *magic);
7e1432fb 4156
88c164f4
NB
4157 switch (*magic) {
4158 case DDF_PHYS_RECORDS_MAGIC:
4159
4160 if (update->len != (sizeof(struct phys_disk) +
4161 sizeof(struct phys_disk_entry)))
4162 return;
4163 pd = (struct phys_disk*)update->buf;
4164
4165 ent = __be16_to_cpu(pd->used_pdes);
4166 if (ent >= __be16_to_cpu(ddf->phys->max_pdes))
4167 return;
4dd968cc
N
4168 if (pd->entries[0].state & __cpu_to_be16(DDF_Missing)) {
4169 struct dl **dlp;
4170 /* removing this disk. */
4171 ddf->phys->entries[ent].state |= __cpu_to_be16(DDF_Missing);
4172 for (dlp = &ddf->dlist; *dlp; dlp = &(*dlp)->next) {
4173 struct dl *dl = *dlp;
4174 if (dl->pdnum == (signed)ent) {
4175 close(dl->fd);
4176 dl->fd = -1;
4177 /* FIXME this doesn't free
4178 * dl->devname */
4179 update->space = dl;
4180 *dlp = dl->next;
4181 break;
4182 }
4183 }
7d5a7ff3 4184 ddf_set_updates_pending(ddf);
4dd968cc
N
4185 return;
4186 }
88c164f4
NB
4187 if (!all_ff(ddf->phys->entries[ent].guid))
4188 return;
4189 ddf->phys->entries[ent] = pd->entries[0];
4190 ddf->phys->used_pdes = __cpu_to_be16(1 +
613b0d17 4191 __be16_to_cpu(ddf->phys->used_pdes));
7d5a7ff3 4192 ddf_set_updates_pending(ddf);
2cc2983d
N
4193 if (ddf->add_list) {
4194 struct active_array *a;
4195 struct dl *al = ddf->add_list;
4196 ddf->add_list = al->next;
4197
4198 al->next = ddf->dlist;
4199 ddf->dlist = al;
4200
4201 /* As a device has been added, we should check
4202 * for any degraded devices that might make
4203 * use of this spare */
4204 for (a = st->arrays ; a; a=a->next)
4205 a->check_degraded = 1;
4206 }
88c164f4
NB
4207 break;
4208
4209 case DDF_VIRT_RECORDS_MAGIC:
4210
4211 if (update->len != (sizeof(struct virtual_disk) +
4212 sizeof(struct virtual_entry)))
4213 return;
4214 vd = (struct virtual_disk*)update->buf;
4215
fb9d0acb 4216 ent = find_unused_vde(ddf);
4217 if (ent == DDF_NOTFOUND)
88c164f4
NB
4218 return;
4219 ddf->virt->entries[ent] = vd->entries[0];
4220 ddf->virt->populated_vdes = __cpu_to_be16(1 +
613b0d17 4221 __be16_to_cpu(ddf->virt->populated_vdes));
7d5a7ff3 4222 ddf_set_updates_pending(ddf);
88c164f4
NB
4223 break;
4224
4225 case DDF_VD_CONF_MAGIC:
2c514b71 4226 dprintf("len %d %d\n", update->len, ddf->conf_rec_len);
88c164f4
NB
4227
4228 mppe = __be16_to_cpu(ddf->anchor.max_primary_element_entries);
f21e18ca 4229 if ((unsigned)update->len != ddf->conf_rec_len * 512)
88c164f4
NB
4230 return;
4231 vc = (struct vd_config*)update->buf;
4232 for (vcl = ddf->conflist; vcl ; vcl = vcl->next)
4233 if (memcmp(vcl->conf.guid, vc->guid, DDF_GUID_LEN) == 0)
4234 break;
2c514b71 4235 dprintf("vcl = %p\n", vcl);
88c164f4
NB
4236 if (vcl) {
4237 /* An update, just copy the phys_refnum and lba_offset
4238 * fields
4239 */
4240 memcpy(vcl->conf.phys_refnum, vc->phys_refnum,
4241 mppe * (sizeof(__u32) + sizeof(__u64)));
4242 } else {
4243 /* A new VD_CONF */
e6b9548d
DW
4244 if (!update->space)
4245 return;
88c164f4
NB
4246 vcl = update->space;
4247 update->space = NULL;
4248 vcl->next = ddf->conflist;
edd8d13c 4249 memcpy(&vcl->conf, vc, update->len);
88c164f4
NB
4250 vcl->lba_offset = (__u64*)
4251 &vcl->conf.phys_refnum[mppe];
fb9d0acb 4252 ent = find_vde_by_guid(ddf, vc->guid);
4253 if (ent == DDF_NOTFOUND)
4254 return;
4255 vcl->vcnum = ent;
88c164f4
NB
4256 ddf->conflist = vcl;
4257 }
c7079c84
N
4258 /* Set DDF_Transition on all Failed devices - to help
4259 * us detect those that are no longer in use
4260 */
4261 for (pdnum = 0; pdnum < __be16_to_cpu(ddf->phys->used_pdes); pdnum++)
4262 if (ddf->phys->entries[pdnum].state
4263 & __be16_to_cpu(DDF_Failed))
4264 ddf->phys->entries[pdnum].state
4265 |= __be16_to_cpu(DDF_Transition);
88c164f4
NB
4266 /* Now make sure vlist is correct for each dl. */
4267 for (dl = ddf->dlist; dl; dl = dl->next) {
f21e18ca
N
4268 unsigned int dn;
4269 unsigned int vn = 0;
8401644c 4270 int in_degraded = 0;
88c164f4
NB
4271 for (vcl = ddf->conflist; vcl ; vcl = vcl->next)
4272 for (dn=0; dn < ddf->mppe ; dn++)
4273 if (vcl->conf.phys_refnum[dn] ==
4274 dl->disk.refnum) {
8401644c 4275 int vstate;
2c514b71
NB
4276 dprintf("dev %d has %p at %d\n",
4277 dl->pdnum, vcl, vn);
c7079c84
N
4278 /* Clear the Transition flag */
4279 if (ddf->phys->entries[dl->pdnum].state
4280 & __be16_to_cpu(DDF_Failed))
4281 ddf->phys->entries[dl->pdnum].state &=
4282 ~__be16_to_cpu(DDF_Transition);
4283
88c164f4 4284 dl->vlist[vn++] = vcl;
8401644c
N
4285 vstate = ddf->virt->entries[vcl->vcnum].state
4286 & DDF_state_mask;
4287 if (vstate == DDF_state_degraded ||
4288 vstate == DDF_state_part_optimal)
4289 in_degraded = 1;
88c164f4
NB
4290 break;
4291 }
4292 while (vn < ddf->max_part)
4293 dl->vlist[vn++] = NULL;
7e1432fb
NB
4294 if (dl->vlist[0]) {
4295 ddf->phys->entries[dl->pdnum].type &=
4296 ~__cpu_to_be16(DDF_Global_Spare);
8401644c
N
4297 if (!(ddf->phys->entries[dl->pdnum].type &
4298 __cpu_to_be16(DDF_Active_in_VD))) {
613b0d17
N
4299 ddf->phys->entries[dl->pdnum].type |=
4300 __cpu_to_be16(DDF_Active_in_VD);
4301 if (in_degraded)
4302 ddf->phys->entries[dl->pdnum].state |=
4303 __cpu_to_be16(DDF_Rebuilding);
4304 }
7e1432fb
NB
4305 }
4306 if (dl->spare) {
4307 ddf->phys->entries[dl->pdnum].type &=
4308 ~__cpu_to_be16(DDF_Global_Spare);
4309 ddf->phys->entries[dl->pdnum].type |=
4310 __cpu_to_be16(DDF_Spare);
4311 }
4312 if (!dl->vlist[0] && !dl->spare) {
4313 ddf->phys->entries[dl->pdnum].type |=
4314 __cpu_to_be16(DDF_Global_Spare);
4315 ddf->phys->entries[dl->pdnum].type &=
4316 ~__cpu_to_be16(DDF_Spare |
4317 DDF_Active_in_VD);
4318 }
88c164f4 4319 }
c7079c84
N
4320
4321 /* Now remove any 'Failed' devices that are not part
4322 * of any VD. They will have the Transition flag set.
4323 * Once done, we need to update all dl->pdnum numbers.
4324 */
4325 pd2 = 0;
4326 for (pdnum = 0; pdnum < __be16_to_cpu(ddf->phys->used_pdes); pdnum++)
4327 if ((ddf->phys->entries[pdnum].state
4328 & __be16_to_cpu(DDF_Failed))
4329 && (ddf->phys->entries[pdnum].state
4330 & __be16_to_cpu(DDF_Transition)))
4331 /* skip this one */;
4332 else if (pdnum == pd2)
4333 pd2++;
4334 else {
4335 ddf->phys->entries[pd2] = ddf->phys->entries[pdnum];
4336 for (dl = ddf->dlist; dl; dl = dl->next)
4337 if (dl->pdnum == (int)pdnum)
4338 dl->pdnum = pd2;
4339 pd2++;
4340 }
4341 ddf->phys->used_pdes = __cpu_to_be16(pd2);
4342 while (pd2 < pdnum) {
4343 memset(ddf->phys->entries[pd2].guid, 0xff, DDF_GUID_LEN);
4344 pd2++;
4345 }
4346
7d5a7ff3 4347 ddf_set_updates_pending(ddf);
88c164f4
NB
4348 break;
4349 case DDF_SPARE_ASSIGN_MAGIC:
4350 default: break;
4351 }
4352}
4353
edd8d13c
NB
4354static void ddf_prepare_update(struct supertype *st,
4355 struct metadata_update *update)
4356{
4357 /* This update arrived at managemon.
4358 * We are about to pass it to monitor.
4359 * If a malloc is needed, do it here.
4360 */
4361 struct ddf_super *ddf = st->sb;
4362 __u32 *magic = (__u32*)update->buf;
4363 if (*magic == DDF_VD_CONF_MAGIC)
e6b9548d 4364 if (posix_memalign(&update->space, 512,
613b0d17
N
4365 offsetof(struct vcl, conf)
4366 + ddf->conf_rec_len * 512) != 0)
e6b9548d 4367 update->space = NULL;
edd8d13c
NB
4368}
4369
7e1432fb
NB
4370/*
4371 * Check if the array 'a' is degraded but not failed.
4372 * If it is, find as many spares as are available and needed and
4373 * arrange for their inclusion.
4374 * We only choose devices which are not already in the array,
4375 * and prefer those with a spare-assignment to this array.
4376 * otherwise we choose global spares - assuming always that
4377 * there is enough room.
4378 * For each spare that we assign, we return an 'mdinfo' which
4379 * describes the position for the device in the array.
4380 * We also add to 'updates' a DDF_VD_CONF_MAGIC update with
4381 * the new phys_refnum and lba_offset values.
4382 *
4383 * Only worry about BVDs at the moment.
4384 */
4385static struct mdinfo *ddf_activate_spare(struct active_array *a,
4386 struct metadata_update **updates)
4387{
4388 int working = 0;
4389 struct mdinfo *d;
4390 struct ddf_super *ddf = a->container->sb;
4391 int global_ok = 0;
4392 struct mdinfo *rv = NULL;
4393 struct mdinfo *di;
4394 struct metadata_update *mu;
4395 struct dl *dl;
4396 int i;
baba3f4e 4397 struct vcl *vcl;
7e1432fb
NB
4398 struct vd_config *vc;
4399 __u64 *lba;
baba3f4e 4400 unsigned int n_bvd;
7e1432fb 4401
7e1432fb
NB
4402 for (d = a->info.devs ; d ; d = d->next) {
4403 if ((d->curr_state & DS_FAULTY) &&
613b0d17 4404 d->state_fd >= 0)
7e1432fb
NB
4405 /* wait for Removal to happen */
4406 return NULL;
4407 if (d->state_fd >= 0)
4408 working ++;
4409 }
4410
2c514b71
NB
4411 dprintf("ddf_activate: working=%d (%d) level=%d\n", working, a->info.array.raid_disks,
4412 a->info.array.level);
7e1432fb
NB
4413 if (working == a->info.array.raid_disks)
4414 return NULL; /* array not degraded */
4415 switch (a->info.array.level) {
4416 case 1:
4417 if (working == 0)
4418 return NULL; /* failed */
4419 break;
4420 case 4:
4421 case 5:
4422 if (working < a->info.array.raid_disks - 1)
4423 return NULL; /* failed */
4424 break;
4425 case 6:
4426 if (working < a->info.array.raid_disks - 2)
4427 return NULL; /* failed */
4428 break;
4429 default: /* concat or stripe */
4430 return NULL; /* failed */
4431 }
4432
4433 /* For each slot, if it is not working, find a spare */
4434 dl = ddf->dlist;
4435 for (i = 0; i < a->info.array.raid_disks; i++) {
4436 for (d = a->info.devs ; d ; d = d->next)
4437 if (d->disk.raid_disk == i)
4438 break;
2c514b71 4439 dprintf("found %d: %p %x\n", i, d, d?d->curr_state:0);
7e1432fb
NB
4440 if (d && (d->state_fd >= 0))
4441 continue;
4442
4443 /* OK, this device needs recovery. Find a spare */
4444 again:
4445 for ( ; dl ; dl = dl->next) {
4446 unsigned long long esize;
4447 unsigned long long pos;
4448 struct mdinfo *d2;
4449 int is_global = 0;
4450 int is_dedicated = 0;
4451 struct extent *ex;
f21e18ca 4452 unsigned int j;
7e1432fb
NB
4453 /* If in this array, skip */
4454 for (d2 = a->info.devs ; d2 ; d2 = d2->next)
7590d562
N
4455 if (d2->state_fd >= 0 &&
4456 d2->disk.major == dl->major &&
7e1432fb 4457 d2->disk.minor == dl->minor) {
2c514b71 4458 dprintf("%x:%x already in array\n", dl->major, dl->minor);
7e1432fb
NB
4459 break;
4460 }
4461 if (d2)
4462 continue;
4463 if (ddf->phys->entries[dl->pdnum].type &
4464 __cpu_to_be16(DDF_Spare)) {
4465 /* Check spare assign record */
4466 if (dl->spare) {
4467 if (dl->spare->type & DDF_spare_dedicated) {
4468 /* check spare_ents for guid */
4469 for (j = 0 ;
4470 j < __be16_to_cpu(dl->spare->populated);
4471 j++) {
4472 if (memcmp(dl->spare->spare_ents[j].guid,
4473 ddf->virt->entries[a->info.container_member].guid,
4474 DDF_GUID_LEN) == 0)
4475 is_dedicated = 1;
4476 }
4477 } else
4478 is_global = 1;
4479 }
4480 } else if (ddf->phys->entries[dl->pdnum].type &
4481 __cpu_to_be16(DDF_Global_Spare)) {
4482 is_global = 1;
e0e7aeaa
N
4483 } else if (!(ddf->phys->entries[dl->pdnum].state &
4484 __cpu_to_be16(DDF_Failed))) {
4485 /* we can possibly use some of this */
4486 is_global = 1;
7e1432fb
NB
4487 }
4488 if ( ! (is_dedicated ||
4489 (is_global && global_ok))) {
2c514b71 4490 dprintf("%x:%x not suitable: %d %d\n", dl->major, dl->minor,
613b0d17 4491 is_dedicated, is_global);
7e1432fb
NB
4492 continue;
4493 }
4494
4495 /* We are allowed to use this device - is there space?
4496 * We need a->info.component_size sectors */
4497 ex = get_extents(ddf, dl);
4498 if (!ex) {
2c514b71 4499 dprintf("cannot get extents\n");
7e1432fb
NB
4500 continue;
4501 }
4502 j = 0; pos = 0;
4503 esize = 0;
4504
4505 do {
4506 esize = ex[j].start - pos;
4507 if (esize >= a->info.component_size)
4508 break;
e5cc7d46
N
4509 pos = ex[j].start + ex[j].size;
4510 j++;
4511 } while (ex[j-1].size);
7e1432fb
NB
4512
4513 free(ex);
4514 if (esize < a->info.component_size) {
e5cc7d46
N
4515 dprintf("%x:%x has no room: %llu %llu\n",
4516 dl->major, dl->minor,
2c514b71 4517 esize, a->info.component_size);
7e1432fb
NB
4518 /* No room */
4519 continue;
4520 }
4521
4522 /* Cool, we have a device with some space at pos */
503975b9 4523 di = xcalloc(1, sizeof(*di));
7e1432fb
NB
4524 di->disk.number = i;
4525 di->disk.raid_disk = i;
4526 di->disk.major = dl->major;
4527 di->disk.minor = dl->minor;
4528 di->disk.state = 0;
d23534e4 4529 di->recovery_start = 0;
7e1432fb
NB
4530 di->data_offset = pos;
4531 di->component_size = a->info.component_size;
4532 di->container_member = dl->pdnum;
4533 di->next = rv;
4534 rv = di;
2c514b71
NB
4535 dprintf("%x:%x to be %d at %llu\n", dl->major, dl->minor,
4536 i, pos);
7e1432fb
NB
4537
4538 break;
4539 }
4540 if (!dl && ! global_ok) {
4541 /* not enough dedicated spares, try global */
4542 global_ok = 1;
4543 dl = ddf->dlist;
4544 goto again;
4545 }
4546 }
4547
4548 if (!rv)
4549 /* No spares found */
4550 return rv;
4551 /* Now 'rv' has a list of devices to return.
4552 * Create a metadata_update record to update the
4553 * phys_refnum and lba_offset values
4554 */
503975b9
N
4555 mu = xmalloc(sizeof(*mu));
4556 if (posix_memalign(&mu->space, 512, sizeof(struct vcl)) != 0) {
79244939
DW
4557 free(mu);
4558 mu = NULL;
4559 }
503975b9 4560 mu->buf = xmalloc(ddf->conf_rec_len * 512);
7590d562
N
4561 mu->len = ddf->conf_rec_len * 512;
4562 mu->space = NULL;
f50ae22e 4563 mu->space_list = NULL;
7e1432fb 4564 mu->next = *updates;
baba3f4e 4565 vc = find_vdcr(ddf, a->info.container_member, di->disk.raid_disk,
4566 &n_bvd, &vcl);
7e1432fb
NB
4567 memcpy(mu->buf, vc, ddf->conf_rec_len * 512);
4568
4569 vc = (struct vd_config*)mu->buf;
4570 lba = (__u64*)&vc->phys_refnum[ddf->mppe];
4571 for (di = rv ; di ; di = di->next) {
4572 vc->phys_refnum[di->disk.raid_disk] =
4573 ddf->phys->entries[dl->pdnum].refnum;
4574 lba[di->disk.raid_disk] = di->data_offset;
4575 }
4576 *updates = mu;
4577 return rv;
4578}
0e600426 4579#endif /* MDASSEMBLE */
7e1432fb 4580
b640a252
N
4581static int ddf_level_to_layout(int level)
4582{
4583 switch(level) {
4584 case 0:
4585 case 1:
4586 return 0;
4587 case 5:
4588 return ALGORITHM_LEFT_SYMMETRIC;
4589 case 6:
4590 return ALGORITHM_ROTATING_N_CONTINUE;
4591 case 10:
4592 return 0x102;
4593 default:
4594 return UnSet;
4595 }
4596}
4597
30f58b22
DW
4598static void default_geometry_ddf(struct supertype *st, int *level, int *layout, int *chunk)
4599{
4600 if (level && *level == UnSet)
4601 *level = LEVEL_CONTAINER;
4602
4603 if (level && layout && *layout == UnSet)
4604 *layout = ddf_level_to_layout(*level);
4605}
4606
a322f70c
DW
4607struct superswitch super_ddf = {
4608#ifndef MDASSEMBLE
4609 .examine_super = examine_super_ddf,
4610 .brief_examine_super = brief_examine_super_ddf,
4737ae25 4611 .brief_examine_subarrays = brief_examine_subarrays_ddf,
bceedeec 4612 .export_examine_super = export_examine_super_ddf,
a322f70c
DW
4613 .detail_super = detail_super_ddf,
4614 .brief_detail_super = brief_detail_super_ddf,
4615 .validate_geometry = validate_geometry_ddf,
78e44928 4616 .write_init_super = write_init_super_ddf,
0e600426 4617 .add_to_super = add_to_super_ddf,
4dd968cc 4618 .remove_from_super = remove_from_super_ddf,
2b959fbf 4619 .load_container = load_container_ddf,
74db60b0 4620 .copy_metadata = copy_metadata_ddf,
a322f70c
DW
4621#endif
4622 .match_home = match_home_ddf,
4623 .uuid_from_super= uuid_from_super_ddf,
4624 .getinfo_super = getinfo_super_ddf,
4625 .update_super = update_super_ddf,
4626
4627 .avail_size = avail_size_ddf,
4628
a19c88b8
NB
4629 .compare_super = compare_super_ddf,
4630
a322f70c 4631 .load_super = load_super_ddf,
ba7eb04f 4632 .init_super = init_super_ddf,
955e9ea1 4633 .store_super = store_super_ddf,
a322f70c
DW
4634 .free_super = free_super_ddf,
4635 .match_metadata_desc = match_metadata_desc_ddf,
78e44928 4636 .container_content = container_content_ddf,
30f58b22 4637 .default_geometry = default_geometry_ddf,
a322f70c 4638
a322f70c 4639 .external = 1,
549e9569 4640
0e600426 4641#ifndef MDASSEMBLE
549e9569
NB
4642/* for mdmon */
4643 .open_new = ddf_open_new,
ed9d66aa 4644 .set_array_state= ddf_set_array_state,
549e9569
NB
4645 .set_disk = ddf_set_disk,
4646 .sync_metadata = ddf_sync_metadata,
88c164f4 4647 .process_update = ddf_process_update,
edd8d13c 4648 .prepare_update = ddf_prepare_update,
7e1432fb 4649 .activate_spare = ddf_activate_spare,
0e600426 4650#endif
4cce4069 4651 .name = "ddf",
a322f70c 4652};