]> git.ipfire.org Git - thirdparty/mdadm.git/blame - super-ddf.c
DDF: Simplify allocation of "other BVDs"
[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;
f21e18ca 2334 unsigned int venum;
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
NB
2428
2429 vcl->next = ddf->conflist;
2430 ddf->conflist = vcl;
d2ca6449 2431 ddf->currentconf = vcl;
7d5a7ff3 2432 ddf_set_updates_pending(ddf);
5f8097be
NB
2433 return 1;
2434}
2435
0e600426 2436#ifndef MDASSEMBLE
5f8097be
NB
2437static void add_to_super_ddf_bvd(struct supertype *st,
2438 mdu_disk_info_t *dk, int fd, char *devname)
2439{
2440 /* fd and devname identify a device with-in the ddf container (st).
2441 * dk identifies a location in the new BVD.
2442 * We need to find suitable free space in that device and update
2443 * the phys_refnum and lba_offset for the newly created vd_config.
2444 * We might also want to update the type in the phys_disk
5575e7d9 2445 * section.
8592f29d
N
2446 *
2447 * Alternately: fd == -1 and we have already chosen which device to
2448 * use and recorded in dlist->raid_disk;
5f8097be
NB
2449 */
2450 struct dl *dl;
2451 struct ddf_super *ddf = st->sb;
2452 struct vd_config *vc;
2453 __u64 *lba_offset;
f21e18ca
N
2454 unsigned int working;
2455 unsigned int i;
59e36268
NB
2456 unsigned long long blocks, pos, esize;
2457 struct extent *ex;
5f8097be 2458
8592f29d
N
2459 if (fd == -1) {
2460 for (dl = ddf->dlist; dl ; dl = dl->next)
2461 if (dl->raiddisk == dk->raid_disk)
2462 break;
2463 } else {
2464 for (dl = ddf->dlist; dl ; dl = dl->next)
2465 if (dl->major == dk->major &&
2466 dl->minor == dk->minor)
2467 break;
2468 }
5f8097be
NB
2469 if (!dl || ! (dk->state & (1<<MD_DISK_SYNC)))
2470 return;
2471
d2ca6449
NB
2472 vc = &ddf->currentconf->conf;
2473 lba_offset = ddf->currentconf->lba_offset;
59e36268
NB
2474
2475 ex = get_extents(ddf, dl);
2476 if (!ex)
2477 return;
2478
2479 i = 0; pos = 0;
2480 blocks = __be64_to_cpu(vc->blocks);
d2ca6449
NB
2481 if (ddf->currentconf->block_sizes)
2482 blocks = ddf->currentconf->block_sizes[dk->raid_disk];
59e36268
NB
2483
2484 do {
2485 esize = ex[i].start - pos;
2486 if (esize >= blocks)
2487 break;
2488 pos = ex[i].start + ex[i].size;
2489 i++;
2490 } while (ex[i-1].size);
2491
2492 free(ex);
2493 if (esize < blocks)
2494 return;
2495
d2ca6449 2496 ddf->currentdev = dk->raid_disk;
5f8097be 2497 vc->phys_refnum[dk->raid_disk] = dl->disk.refnum;
59e36268 2498 lba_offset[dk->raid_disk] = __cpu_to_be64(pos);
5f8097be 2499
f21e18ca 2500 for (i = 0; i < ddf->max_part ; i++)
5575e7d9
NB
2501 if (dl->vlist[i] == NULL)
2502 break;
2503 if (i == ddf->max_part)
2504 return;
d2ca6449 2505 dl->vlist[i] = ddf->currentconf;
5f8097be 2506
8592f29d
N
2507 if (fd >= 0)
2508 dl->fd = fd;
2509 if (devname)
2510 dl->devname = devname;
7a7cc504
NB
2511
2512 /* Check how many working raid_disks, and if we can mark
2513 * array as optimal yet
2514 */
2515 working = 0;
5575e7d9 2516
f21e18ca 2517 for (i = 0; i < __be16_to_cpu(vc->prim_elmnt_count); i++)
7a7cc504
NB
2518 if (vc->phys_refnum[i] != 0xffffffff)
2519 working++;
59e36268 2520
5575e7d9 2521 /* Find which virtual_entry */
d2ca6449 2522 i = ddf->currentconf->vcnum;
7a7cc504 2523 if (working == __be16_to_cpu(vc->prim_elmnt_count))
5575e7d9
NB
2524 ddf->virt->entries[i].state =
2525 (ddf->virt->entries[i].state & ~DDF_state_mask)
7a7cc504
NB
2526 | DDF_state_optimal;
2527
2528 if (vc->prl == DDF_RAID6 &&
2529 working+1 == __be16_to_cpu(vc->prim_elmnt_count))
5575e7d9
NB
2530 ddf->virt->entries[i].state =
2531 (ddf->virt->entries[i].state & ~DDF_state_mask)
7a7cc504 2532 | DDF_state_part_optimal;
5575e7d9
NB
2533
2534 ddf->phys->entries[dl->pdnum].type &= ~__cpu_to_be16(DDF_Global_Spare);
2535 ddf->phys->entries[dl->pdnum].type |= __cpu_to_be16(DDF_Active_in_VD);
7d5a7ff3 2536 ddf_set_updates_pending(ddf);
5f8097be
NB
2537}
2538
a322f70c
DW
2539/* add a device to a container, either while creating it or while
2540 * expanding a pre-existing container
2541 */
f20c3968 2542static int add_to_super_ddf(struct supertype *st,
72ca9bcf
N
2543 mdu_disk_info_t *dk, int fd, char *devname,
2544 unsigned long long data_offset)
a322f70c
DW
2545{
2546 struct ddf_super *ddf = st->sb;
2547 struct dl *dd;
2548 time_t now;
2549 struct tm *tm;
2550 unsigned long long size;
2551 struct phys_disk_entry *pde;
f21e18ca 2552 unsigned int n, i;
a322f70c 2553 struct stat stb;
90fa1a29 2554 __u32 *tptr;
a322f70c 2555
78e44928
NB
2556 if (ddf->currentconf) {
2557 add_to_super_ddf_bvd(st, dk, fd, devname);
f20c3968 2558 return 0;
78e44928
NB
2559 }
2560
a322f70c
DW
2561 /* This is device numbered dk->number. We need to create
2562 * a phys_disk entry and a more detailed disk_data entry.
2563 */
2564 fstat(fd, &stb);
3d2c4fc7
DW
2565 if (posix_memalign((void**)&dd, 512,
2566 sizeof(*dd) + sizeof(dd->vlist[0]) * ddf->max_part) != 0) {
e7b84f9d
N
2567 pr_err("%s could allocate buffer for new disk, aborting\n",
2568 __func__);
f20c3968 2569 return 1;
3d2c4fc7 2570 }
a322f70c
DW
2571 dd->major = major(stb.st_rdev);
2572 dd->minor = minor(stb.st_rdev);
2573 dd->devname = devname;
a322f70c 2574 dd->fd = fd;
b2280677 2575 dd->spare = NULL;
a322f70c
DW
2576
2577 dd->disk.magic = DDF_PHYS_DATA_MAGIC;
2578 now = time(0);
2579 tm = localtime(&now);
2580 sprintf(dd->disk.guid, "%8s%04d%02d%02d",
2581 T10, tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
90fa1a29
JS
2582 tptr = (__u32 *)(dd->disk.guid + 16);
2583 *tptr++ = random32();
2584 *tptr = random32();
a322f70c 2585
59e36268
NB
2586 do {
2587 /* Cannot be bothered finding a CRC of some irrelevant details*/
bfb7ea78 2588 dd->disk.refnum = random32();
f21e18ca
N
2589 for (i = __be16_to_cpu(ddf->active->max_pd_entries);
2590 i > 0; i--)
2591 if (ddf->phys->entries[i-1].refnum == dd->disk.refnum)
59e36268 2592 break;
f21e18ca 2593 } while (i > 0);
59e36268 2594
a322f70c
DW
2595 dd->disk.forced_ref = 1;
2596 dd->disk.forced_guid = 1;
2597 memset(dd->disk.vendor, ' ', 32);
2598 memcpy(dd->disk.vendor, "Linux", 5);
2599 memset(dd->disk.pad, 0xff, 442);
b2280677 2600 for (i = 0; i < ddf->max_part ; i++)
a322f70c
DW
2601 dd->vlist[i] = NULL;
2602
2603 n = __be16_to_cpu(ddf->phys->used_pdes);
2604 pde = &ddf->phys->entries[n];
5575e7d9
NB
2605 dd->pdnum = n;
2606
2cc2983d
N
2607 if (st->update_tail) {
2608 int len = (sizeof(struct phys_disk) +
2609 sizeof(struct phys_disk_entry));
2610 struct phys_disk *pd;
2611
503975b9 2612 pd = xmalloc(len);
2cc2983d
N
2613 pd->magic = DDF_PHYS_RECORDS_MAGIC;
2614 pd->used_pdes = __cpu_to_be16(n);
2615 pde = &pd->entries[0];
2616 dd->mdupdate = pd;
2617 } else {
2618 n++;
2619 ddf->phys->used_pdes = __cpu_to_be16(n);
2620 }
a322f70c
DW
2621
2622 memcpy(pde->guid, dd->disk.guid, DDF_GUID_LEN);
2623 pde->refnum = dd->disk.refnum;
5575e7d9 2624 pde->type = __cpu_to_be16(DDF_Forced_PD_GUID | DDF_Global_Spare);
a322f70c
DW
2625 pde->state = __cpu_to_be16(DDF_Online);
2626 get_dev_size(fd, NULL, &size);
2627 /* We are required to reserve 32Meg, and record the size in sectors */
2628 pde->config_size = __cpu_to_be64( (size - 32*1024*1024) / 512);
2629 sprintf(pde->path, "%17.17s","Information: nil") ;
2630 memset(pde->pad, 0xff, 6);
2631
d2ca6449 2632 dd->size = size >> 9;
2cc2983d
N
2633 if (st->update_tail) {
2634 dd->next = ddf->add_list;
2635 ddf->add_list = dd;
2636 } else {
2637 dd->next = ddf->dlist;
2638 ddf->dlist = dd;
7d5a7ff3 2639 ddf_set_updates_pending(ddf);
2cc2983d 2640 }
f20c3968
DW
2641
2642 return 0;
a322f70c
DW
2643}
2644
4dd968cc
N
2645static int remove_from_super_ddf(struct supertype *st, mdu_disk_info_t *dk)
2646{
2647 struct ddf_super *ddf = st->sb;
2648 struct dl *dl;
2649
2650 /* mdmon has noticed that this disk (dk->major/dk->minor) has
2651 * disappeared from the container.
2652 * We need to arrange that it disappears from the metadata and
2653 * internal data structures too.
2654 * Most of the work is done by ddf_process_update which edits
2655 * the metadata and closes the file handle and attaches the memory
2656 * where free_updates will free it.
2657 */
2658 for (dl = ddf->dlist; dl ; dl = dl->next)
2659 if (dl->major == dk->major &&
2660 dl->minor == dk->minor)
2661 break;
2662 if (!dl)
2663 return -1;
2664
2665 if (st->update_tail) {
2666 int len = (sizeof(struct phys_disk) +
2667 sizeof(struct phys_disk_entry));
2668 struct phys_disk *pd;
2669
503975b9 2670 pd = xmalloc(len);
4dd968cc
N
2671 pd->magic = DDF_PHYS_RECORDS_MAGIC;
2672 pd->used_pdes = __cpu_to_be16(dl->pdnum);
2673 pd->entries[0].state = __cpu_to_be16(DDF_Missing);
2674 append_metadata_update(st, pd, len);
2675 }
2676 return 0;
2677}
2678
a322f70c
DW
2679/*
2680 * This is the write_init_super method for a ddf container. It is
2681 * called when creating a container or adding another device to a
2682 * container.
2683 */
42d5dfd9 2684#define NULL_CONF_SZ 4096
18a2f463 2685
e3c2a365 2686static unsigned int get_pd_index_from_refnum(const struct vcl *vc,
2687 __u32 refnum, unsigned int nmax,
2688 const struct vd_config **bvd,
2689 unsigned int *idx);
2690
7f798aca 2691static int __write_ddf_structure(struct dl *d, struct ddf_super *ddf, __u8 type,
2692 char *null_aligned)
a322f70c 2693{
7f798aca 2694 unsigned long long sector;
2695 struct ddf_header *header;
2696 int fd, i, n_config, conf_size;
a4057a88 2697 int ret = 0;
7f798aca 2698
2699 fd = d->fd;
2700
2701 switch (type) {
2702 case DDF_HEADER_PRIMARY:
2703 header = &ddf->primary;
2704 sector = __be64_to_cpu(header->primary_lba);
2705 break;
2706 case DDF_HEADER_SECONDARY:
2707 header = &ddf->secondary;
2708 sector = __be64_to_cpu(header->secondary_lba);
2709 break;
2710 default:
2711 return 0;
2712 }
2713
2714 header->type = type;
a4057a88 2715 header->openflag = 1;
7f798aca 2716 header->crc = calc_crc(header, 512);
2717
2718 lseek64(fd, sector<<9, 0);
2719 if (write(fd, header, 512) < 0)
a4057a88 2720 goto out;
7f798aca 2721
2722 ddf->controller.crc = calc_crc(&ddf->controller, 512);
2723 if (write(fd, &ddf->controller, 512) < 0)
a4057a88 2724 goto out;
a322f70c 2725
7f798aca 2726 ddf->phys->crc = calc_crc(ddf->phys, ddf->pdsize);
2727 if (write(fd, ddf->phys, ddf->pdsize) < 0)
a4057a88 2728 goto out;
7f798aca 2729 ddf->virt->crc = calc_crc(ddf->virt, ddf->vdsize);
2730 if (write(fd, ddf->virt, ddf->vdsize) < 0)
a4057a88 2731 goto out;
7f798aca 2732
2733 /* Now write lots of config records. */
2734 n_config = ddf->max_part;
2735 conf_size = ddf->conf_rec_len * 512;
2736 for (i = 0 ; i <= n_config ; i++) {
e3c2a365 2737 struct vcl *c;
2738 struct vd_config *vdc = NULL;
2739 if (i == n_config) {
7f798aca 2740 c = (struct vcl *)d->spare;
e3c2a365 2741 if (c)
2742 vdc = &c->conf;
2743 } else {
2744 unsigned int dummy;
2745 c = d->vlist[i];
2746 if (c)
2747 get_pd_index_from_refnum(
2748 c, d->disk.refnum,
2749 ddf->mppe,
2750 (const struct vd_config **)&vdc,
2751 &dummy);
2752 }
7f798aca 2753 if (c) {
dacf3dc5 2754 vdc->seqnum = header->seq;
e3c2a365 2755 vdc->crc = calc_crc(vdc, conf_size);
2756 if (write(fd, vdc, conf_size) < 0)
7f798aca 2757 break;
2758 } else {
2759 unsigned int togo = conf_size;
2760 while (togo > NULL_CONF_SZ) {
2761 if (write(fd, null_aligned, NULL_CONF_SZ) < 0)
2762 break;
2763 togo -= NULL_CONF_SZ;
2764 }
2765 if (write(fd, null_aligned, togo) < 0)
2766 break;
2767 }
2768 }
2769 if (i <= n_config)
a4057a88 2770 goto out;
7f798aca 2771
2772 d->disk.crc = calc_crc(&d->disk, 512);
2773 if (write(fd, &d->disk, 512) < 0)
a4057a88 2774 goto out;
7f798aca 2775
a4057a88 2776 ret = 1;
2777out:
2778 header->openflag = 0;
2779 header->crc = calc_crc(header, 512);
2780
2781 lseek64(fd, sector<<9, 0);
2782 if (write(fd, header, 512) < 0)
2783 ret = 0;
2784
2785 return ret;
7f798aca 2786}
2787
2788static int __write_init_super_ddf(struct supertype *st)
2789{
a322f70c 2790 struct ddf_super *ddf = st->sb;
a322f70c 2791 struct dl *d;
175593bf
DW
2792 int attempts = 0;
2793 int successes = 0;
7f798aca 2794 unsigned long long size;
42d5dfd9 2795 char *null_aligned;
0175cbf6 2796 __u32 seq;
42d5dfd9 2797
7d5a7ff3 2798 pr_state(ddf, __func__);
42d5dfd9
JS
2799 if (posix_memalign((void**)&null_aligned, 4096, NULL_CONF_SZ) != 0) {
2800 return -ENOMEM;
2801 }
2802 memset(null_aligned, 0xff, NULL_CONF_SZ);
a322f70c 2803
dc9e279c 2804 seq = ddf->active->seq + 1;
0175cbf6 2805
175593bf
DW
2806 /* try to write updated metadata,
2807 * if we catch a failure move on to the next disk
2808 */
a322f70c
DW
2809 for (d = ddf->dlist; d; d=d->next) {
2810 int fd = d->fd;
2811
2812 if (fd < 0)
2813 continue;
2814
175593bf 2815 attempts++;
a322f70c
DW
2816 /* We need to fill in the primary, (secondary) and workspace
2817 * lba's in the headers, set their checksums,
2818 * Also checksum phys, virt....
2819 *
2820 * Then write everything out, finally the anchor is written.
2821 */
2822 get_dev_size(fd, NULL, &size);
2823 size /= 512;
097bcf00 2824 if (d->workspace_lba != 0)
2825 ddf->anchor.workspace_lba = d->workspace_lba;
2826 else
2827 ddf->anchor.workspace_lba =
2828 __cpu_to_be64(size - 32*1024*2);
2829 if (d->primary_lba != 0)
2830 ddf->anchor.primary_lba = d->primary_lba;
2831 else
2832 ddf->anchor.primary_lba =
2833 __cpu_to_be64(size - 16*1024*2);
2834 if (d->secondary_lba != 0)
2835 ddf->anchor.secondary_lba = d->secondary_lba;
2836 else
2837 ddf->anchor.secondary_lba =
2838 __cpu_to_be64(size - 32*1024*2);
0175cbf6 2839 ddf->anchor.seq = seq;
a322f70c
DW
2840 memcpy(&ddf->primary, &ddf->anchor, 512);
2841 memcpy(&ddf->secondary, &ddf->anchor, 512);
2842
2843 ddf->anchor.openflag = 0xFF; /* 'open' means nothing */
2844 ddf->anchor.seq = 0xFFFFFFFF; /* no sequencing in anchor */
2845 ddf->anchor.crc = calc_crc(&ddf->anchor, 512);
2846
7f798aca 2847 if (!__write_ddf_structure(d, ddf, DDF_HEADER_PRIMARY,
2848 null_aligned))
175593bf 2849 continue;
a322f70c 2850
7f798aca 2851 if (!__write_ddf_structure(d, ddf, DDF_HEADER_SECONDARY,
2852 null_aligned))
175593bf 2853 continue;
a322f70c 2854
a322f70c 2855 lseek64(fd, (size-1)*512, SEEK_SET);
175593bf
DW
2856 if (write(fd, &ddf->anchor, 512) < 0)
2857 continue;
2858 successes++;
2859 }
42d5dfd9 2860 free(null_aligned);
175593bf 2861
175593bf 2862 return attempts != successes;
a322f70c 2863}
7a7cc504
NB
2864
2865static int write_init_super_ddf(struct supertype *st)
2866{
9b1fb677
DW
2867 struct ddf_super *ddf = st->sb;
2868 struct vcl *currentconf = ddf->currentconf;
2869
2870 /* we are done with currentconf reset it to point st at the container */
2871 ddf->currentconf = NULL;
edd8d13c
NB
2872
2873 if (st->update_tail) {
2874 /* queue the virtual_disk and vd_config as metadata updates */
2875 struct virtual_disk *vd;
2876 struct vd_config *vc;
edd8d13c
NB
2877 int len;
2878
9b1fb677 2879 if (!currentconf) {
2cc2983d
N
2880 int len = (sizeof(struct phys_disk) +
2881 sizeof(struct phys_disk_entry));
2882
2883 /* adding a disk to the container. */
2884 if (!ddf->add_list)
2885 return 0;
2886
2887 append_metadata_update(st, ddf->add_list->mdupdate, len);
2888 ddf->add_list->mdupdate = NULL;
2889 return 0;
2890 }
2891
2892 /* Newly created VD */
2893
edd8d13c
NB
2894 /* First the virtual disk. We have a slightly fake header */
2895 len = sizeof(struct virtual_disk) + sizeof(struct virtual_entry);
503975b9 2896 vd = xmalloc(len);
edd8d13c 2897 *vd = *ddf->virt;
9b1fb677
DW
2898 vd->entries[0] = ddf->virt->entries[currentconf->vcnum];
2899 vd->populated_vdes = __cpu_to_be16(currentconf->vcnum);
edd8d13c
NB
2900 append_metadata_update(st, vd, len);
2901
2902 /* Then the vd_config */
2903 len = ddf->conf_rec_len * 512;
503975b9 2904 vc = xmalloc(len);
9b1fb677 2905 memcpy(vc, &currentconf->conf, len);
edd8d13c
NB
2906 append_metadata_update(st, vc, len);
2907
2908 /* FIXME I need to close the fds! */
2909 return 0;
613b0d17 2910 } else {
d682f344
N
2911 struct dl *d;
2912 for (d = ddf->dlist; d; d=d->next)
ba728be7 2913 while (Kill(d->devname, NULL, 0, -1, 1) == 0);
1cc7f4fe 2914 return __write_init_super_ddf(st);
d682f344 2915 }
7a7cc504
NB
2916}
2917
a322f70c
DW
2918#endif
2919
387fcd59
N
2920static __u64 avail_size_ddf(struct supertype *st, __u64 devsize,
2921 unsigned long long data_offset)
a322f70c
DW
2922{
2923 /* We must reserve the last 32Meg */
2924 if (devsize <= 32*1024*2)
2925 return 0;
2926 return devsize - 32*1024*2;
2927}
2928
2929#ifndef MDASSEMBLE
8592f29d
N
2930
2931static int reserve_space(struct supertype *st, int raiddisks,
2932 unsigned long long size, int chunk,
2933 unsigned long long *freesize)
2934{
2935 /* Find 'raiddisks' spare extents at least 'size' big (but
2936 * only caring about multiples of 'chunk') and remember
2937 * them.
2938 * If the cannot be found, fail.
2939 */
2940 struct dl *dl;
2941 struct ddf_super *ddf = st->sb;
2942 int cnt = 0;
2943
2944 for (dl = ddf->dlist; dl ; dl=dl->next) {
613b0d17 2945 dl->raiddisk = -1;
8592f29d
N
2946 dl->esize = 0;
2947 }
2948 /* Now find largest extent on each device */
2949 for (dl = ddf->dlist ; dl ; dl=dl->next) {
2950 struct extent *e = get_extents(ddf, dl);
2951 unsigned long long pos = 0;
2952 int i = 0;
2953 int found = 0;
2954 unsigned long long minsize = size;
2955
2956 if (size == 0)
2957 minsize = chunk;
2958
2959 if (!e)
2960 continue;
2961 do {
2962 unsigned long long esize;
2963 esize = e[i].start - pos;
2964 if (esize >= minsize) {
2965 found = 1;
2966 minsize = esize;
2967 }
2968 pos = e[i].start + e[i].size;
2969 i++;
2970 } while (e[i-1].size);
2971 if (found) {
2972 cnt++;
2973 dl->esize = minsize;
2974 }
2975 free(e);
2976 }
2977 if (cnt < raiddisks) {
e7b84f9d 2978 pr_err("not enough devices with space to create array.\n");
8592f29d
N
2979 return 0; /* No enough free spaces large enough */
2980 }
2981 if (size == 0) {
2982 /* choose the largest size of which there are at least 'raiddisk' */
2983 for (dl = ddf->dlist ; dl ; dl=dl->next) {
2984 struct dl *dl2;
2985 if (dl->esize <= size)
2986 continue;
2987 /* This is bigger than 'size', see if there are enough */
2988 cnt = 0;
7b80ad6a 2989 for (dl2 = ddf->dlist; dl2 ; dl2=dl2->next)
8592f29d
N
2990 if (dl2->esize >= dl->esize)
2991 cnt++;
2992 if (cnt >= raiddisks)
2993 size = dl->esize;
2994 }
2995 if (chunk) {
2996 size = size / chunk;
2997 size *= chunk;
2998 }
2999 *freesize = size;
3000 if (size < 32) {
e7b84f9d 3001 pr_err("not enough spare devices to create array.\n");
8592f29d
N
3002 return 0;
3003 }
3004 }
3005 /* We have a 'size' of which there are enough spaces.
3006 * We simply do a first-fit */
3007 cnt = 0;
3008 for (dl = ddf->dlist ; dl && cnt < raiddisks ; dl=dl->next) {
3009 if (dl->esize < size)
3010 continue;
613b0d17 3011
8592f29d
N
3012 dl->raiddisk = cnt;
3013 cnt++;
3014 }
3015 return 1;
3016}
3017
2c514b71
NB
3018static int
3019validate_geometry_ddf_container(struct supertype *st,
3020 int level, int layout, int raiddisks,
3021 int chunk, unsigned long long size,
af4348dd 3022 unsigned long long data_offset,
2c514b71
NB
3023 char *dev, unsigned long long *freesize,
3024 int verbose);
78e44928
NB
3025
3026static int validate_geometry_ddf_bvd(struct supertype *st,
3027 int level, int layout, int raiddisks,
c21e737b 3028 int *chunk, unsigned long long size,
af4348dd 3029 unsigned long long data_offset,
2c514b71
NB
3030 char *dev, unsigned long long *freesize,
3031 int verbose);
78e44928
NB
3032
3033static int validate_geometry_ddf(struct supertype *st,
2c514b71 3034 int level, int layout, int raiddisks,
c21e737b 3035 int *chunk, unsigned long long size,
af4348dd 3036 unsigned long long data_offset,
2c514b71
NB
3037 char *dev, unsigned long long *freesize,
3038 int verbose)
a322f70c
DW
3039{
3040 int fd;
3041 struct mdinfo *sra;
3042 int cfd;
3043
3044 /* ddf potentially supports lots of things, but it depends on
3045 * what devices are offered (and maybe kernel version?)
3046 * If given unused devices, we will make a container.
3047 * If given devices in a container, we will make a BVD.
3048 * If given BVDs, we make an SVD, changing all the GUIDs in the process.
3049 */
3050
bb7295f1
N
3051 if (chunk && *chunk == UnSet)
3052 *chunk = DEFAULT_CHUNK;
3053
542ef4ec 3054 if (level == -1000000) level = LEVEL_CONTAINER;
a322f70c 3055 if (level == LEVEL_CONTAINER) {
78e44928
NB
3056 /* Must be a fresh device to add to a container */
3057 return validate_geometry_ddf_container(st, level, layout,
c21e737b 3058 raiddisks, chunk?*chunk:0,
af4348dd
N
3059 size, data_offset, dev,
3060 freesize,
2c514b71 3061 verbose);
5f8097be
NB
3062 }
3063
78e44928 3064 if (!dev) {
a3163bf0 3065 mdu_array_info_t array = {
3066 .level = level, .layout = layout,
3067 .raid_disks = raiddisks
3068 };
3069 struct vd_config conf;
3070 if (layout_md2ddf(&array, &conf) == -1) {
b42f577a 3071 if (verbose)
e7b84f9d 3072 pr_err("DDF does not support level %d arrays\n",
613b0d17 3073 level);
78e44928 3074 return 0;
b42f577a 3075 }
78e44928 3076 /* Should check layout? etc */
8592f29d
N
3077
3078 if (st->sb && freesize) {
3079 /* --create was given a container to create in.
3080 * So we need to check that there are enough
3081 * free spaces and return the amount of space.
3082 * We may as well remember which drives were
3083 * chosen so that add_to_super/getinfo_super
3084 * can return them.
3085 */
c21e737b 3086 return reserve_space(st, raiddisks, size, chunk?*chunk:0, freesize);
8592f29d 3087 }
a322f70c 3088 return 1;
78e44928 3089 }
a322f70c 3090
8592f29d
N
3091 if (st->sb) {
3092 /* A container has already been opened, so we are
3093 * creating in there. Maybe a BVD, maybe an SVD.
3094 * Should make a distinction one day.
3095 */
3096 return validate_geometry_ddf_bvd(st, level, layout, raiddisks,
af4348dd
N
3097 chunk, size, data_offset, dev,
3098 freesize,
8592f29d
N
3099 verbose);
3100 }
78e44928
NB
3101 /* This is the first device for the array.
3102 * If it is a container, we read it in and do automagic allocations,
3103 * no other devices should be given.
3104 * Otherwise it must be a member device of a container, and we
3105 * do manual allocation.
3106 * Later we should check for a BVD and make an SVD.
a322f70c 3107 */
a322f70c
DW
3108 fd = open(dev, O_RDONLY|O_EXCL, 0);
3109 if (fd >= 0) {
4dd2df09 3110 sra = sysfs_read(fd, NULL, GET_VERSION);
a322f70c
DW
3111 close(fd);
3112 if (sra && sra->array.major_version == -1 &&
78e44928
NB
3113 strcmp(sra->text_version, "ddf") == 0) {
3114
3115 /* load super */
3116 /* find space for 'n' devices. */
3117 /* remember the devices */
3118 /* Somehow return the fact that we have enough */
a322f70c
DW
3119 }
3120
2c514b71 3121 if (verbose)
e7b84f9d
N
3122 pr_err("ddf: Cannot create this array "
3123 "on device %s - a container is required.\n",
3124 dev);
a322f70c
DW
3125 return 0;
3126 }
3127 if (errno != EBUSY || (fd = open(dev, O_RDONLY, 0)) < 0) {
2c514b71 3128 if (verbose)
e7b84f9d 3129 pr_err("ddf: Cannot open %s: %s\n",
613b0d17 3130 dev, strerror(errno));
a322f70c
DW
3131 return 0;
3132 }
3133 /* Well, it is in use by someone, maybe a 'ddf' container. */
3134 cfd = open_container(fd);
3135 if (cfd < 0) {
3136 close(fd);
2c514b71 3137 if (verbose)
e7b84f9d 3138 pr_err("ddf: Cannot use %s: %s\n",
613b0d17 3139 dev, strerror(EBUSY));
a322f70c
DW
3140 return 0;
3141 }
4dd2df09 3142 sra = sysfs_read(cfd, NULL, GET_VERSION);
a322f70c
DW
3143 close(fd);
3144 if (sra && sra->array.major_version == -1 &&
3145 strcmp(sra->text_version, "ddf") == 0) {
3146 /* This is a member of a ddf container. Load the container
3147 * and try to create a bvd
3148 */
3149 struct ddf_super *ddf;
e1902a7b 3150 if (load_super_ddf_all(st, cfd, (void **)&ddf, NULL) == 0) {
5f8097be 3151 st->sb = ddf;
4dd2df09 3152 strcpy(st->container_devnm, fd2devnm(cfd));
a322f70c 3153 close(cfd);
78e44928 3154 return validate_geometry_ddf_bvd(st, level, layout,
a322f70c 3155 raiddisks, chunk, size,
af4348dd 3156 data_offset,
2c514b71
NB
3157 dev, freesize,
3158 verbose);
a322f70c
DW
3159 }
3160 close(cfd);
c42ec1ed
DW
3161 } else /* device may belong to a different container */
3162 return 0;
3163
a322f70c
DW
3164 return 1;
3165}
3166
2c514b71
NB
3167static int
3168validate_geometry_ddf_container(struct supertype *st,
3169 int level, int layout, int raiddisks,
3170 int chunk, unsigned long long size,
af4348dd 3171 unsigned long long data_offset,
2c514b71
NB
3172 char *dev, unsigned long long *freesize,
3173 int verbose)
a322f70c
DW
3174{
3175 int fd;
3176 unsigned long long ldsize;
3177
3178 if (level != LEVEL_CONTAINER)
3179 return 0;
3180 if (!dev)
3181 return 1;
3182
3183 fd = open(dev, O_RDONLY|O_EXCL, 0);
3184 if (fd < 0) {
2c514b71 3185 if (verbose)
e7b84f9d 3186 pr_err("ddf: Cannot open %s: %s\n",
613b0d17 3187 dev, strerror(errno));
a322f70c
DW
3188 return 0;
3189 }
3190 if (!get_dev_size(fd, dev, &ldsize)) {
3191 close(fd);
3192 return 0;
3193 }
3194 close(fd);
3195
387fcd59 3196 *freesize = avail_size_ddf(st, ldsize >> 9, INVALID_SECTORS);
ea17e7aa
N
3197 if (*freesize == 0)
3198 return 0;
a322f70c
DW
3199
3200 return 1;
3201}
3202
78e44928
NB
3203static int validate_geometry_ddf_bvd(struct supertype *st,
3204 int level, int layout, int raiddisks,
c21e737b 3205 int *chunk, unsigned long long size,
af4348dd 3206 unsigned long long data_offset,
2c514b71
NB
3207 char *dev, unsigned long long *freesize,
3208 int verbose)
a322f70c
DW
3209{
3210 struct stat stb;
3211 struct ddf_super *ddf = st->sb;
3212 struct dl *dl;
5f8097be
NB
3213 unsigned long long pos = 0;
3214 unsigned long long maxsize;
3215 struct extent *e;
3216 int i;
a322f70c 3217 /* ddf/bvd supports lots of things, but not containers */
b42f577a
N
3218 if (level == LEVEL_CONTAINER) {
3219 if (verbose)
e7b84f9d 3220 pr_err("DDF cannot create a container within an container\n");
a322f70c 3221 return 0;
b42f577a 3222 }
a322f70c
DW
3223 /* We must have the container info already read in. */
3224 if (!ddf)
3225 return 0;
3226
5f8097be
NB
3227 if (!dev) {
3228 /* General test: make sure there is space for
3229 * 'raiddisks' device extents of size 'size'.
3230 */
3231 unsigned long long minsize = size;
3232 int dcnt = 0;
3233 if (minsize == 0)
3234 minsize = 8;
3235 for (dl = ddf->dlist; dl ; dl = dl->next)
3236 {
3237 int found = 0;
7e1432fb 3238 pos = 0;
5f8097be
NB
3239
3240 i = 0;
3241 e = get_extents(ddf, dl);
3242 if (!e) continue;
3243 do {
3244 unsigned long long esize;
3245 esize = e[i].start - pos;
3246 if (esize >= minsize)
3247 found = 1;
3248 pos = e[i].start + e[i].size;
3249 i++;
3250 } while (e[i-1].size);
3251 if (found)
3252 dcnt++;
3253 free(e);
3254 }
3255 if (dcnt < raiddisks) {
2c514b71 3256 if (verbose)
e7b84f9d
N
3257 pr_err("ddf: Not enough devices with "
3258 "space for this array (%d < %d)\n",
3259 dcnt, raiddisks);
5f8097be
NB
3260 return 0;
3261 }
3262 return 1;
3263 }
a322f70c
DW
3264 /* This device must be a member of the set */
3265 if (stat(dev, &stb) < 0)
3266 return 0;
3267 if ((S_IFMT & stb.st_mode) != S_IFBLK)
3268 return 0;
3269 for (dl = ddf->dlist ; dl ; dl = dl->next) {
f21e18ca
N
3270 if (dl->major == (int)major(stb.st_rdev) &&
3271 dl->minor == (int)minor(stb.st_rdev))
a322f70c
DW
3272 break;
3273 }
5f8097be 3274 if (!dl) {
2c514b71 3275 if (verbose)
e7b84f9d 3276 pr_err("ddf: %s is not in the "
613b0d17
N
3277 "same DDF set\n",
3278 dev);
5f8097be
NB
3279 return 0;
3280 }
3281 e = get_extents(ddf, dl);
3282 maxsize = 0;
3283 i = 0;
3284 if (e) do {
613b0d17
N
3285 unsigned long long esize;
3286 esize = e[i].start - pos;
3287 if (esize >= maxsize)
3288 maxsize = esize;
3289 pos = e[i].start + e[i].size;
3290 i++;
3291 } while (e[i-1].size);
5f8097be 3292 *freesize = maxsize;
a322f70c
DW
3293 // FIXME here I am
3294
3295 return 1;
3296}
59e36268 3297
a322f70c 3298static int load_super_ddf_all(struct supertype *st, int fd,
e1902a7b 3299 void **sbp, char *devname)
a322f70c
DW
3300{
3301 struct mdinfo *sra;
3302 struct ddf_super *super;
3303 struct mdinfo *sd, *best = NULL;
3304 int bestseq = 0;
3305 int seq;
3306 char nm[20];
3307 int dfd;
3308
b526e52d 3309 sra = sysfs_read(fd, 0, GET_LEVEL|GET_VERSION|GET_DEVS|GET_STATE);
a322f70c
DW
3310 if (!sra)
3311 return 1;
3312 if (sra->array.major_version != -1 ||
3313 sra->array.minor_version != -2 ||
3314 strcmp(sra->text_version, "ddf") != 0)
3315 return 1;
3316
6416d527 3317 if (posix_memalign((void**)&super, 512, sizeof(*super)) != 0)
a322f70c 3318 return 1;
a2349791 3319 memset(super, 0, sizeof(*super));
a322f70c
DW
3320
3321 /* first, try each device, and choose the best ddf */
3322 for (sd = sra->devs ; sd ; sd = sd->next) {
3323 int rv;
3324 sprintf(nm, "%d:%d", sd->disk.major, sd->disk.minor);
7a7cc504
NB
3325 dfd = dev_open(nm, O_RDONLY);
3326 if (dfd < 0)
a322f70c
DW
3327 return 2;
3328 rv = load_ddf_headers(dfd, super, NULL);
7a7cc504 3329 close(dfd);
a322f70c
DW
3330 if (rv == 0) {
3331 seq = __be32_to_cpu(super->active->seq);
3332 if (super->active->openflag)
3333 seq--;
3334 if (!best || seq > bestseq) {
3335 bestseq = seq;
3336 best = sd;
3337 }
3338 }
3339 }
3340 if (!best)
3341 return 1;
3342 /* OK, load this ddf */
3343 sprintf(nm, "%d:%d", best->disk.major, best->disk.minor);
3344 dfd = dev_open(nm, O_RDONLY);
7a7cc504 3345 if (dfd < 0)
a322f70c
DW
3346 return 1;
3347 load_ddf_headers(dfd, super, NULL);
3348 load_ddf_global(dfd, super, NULL);
3349 close(dfd);
3350 /* Now we need the device-local bits */
3351 for (sd = sra->devs ; sd ; sd = sd->next) {
3d2c4fc7
DW
3352 int rv;
3353
a322f70c 3354 sprintf(nm, "%d:%d", sd->disk.major, sd->disk.minor);
e1902a7b 3355 dfd = dev_open(nm, O_RDWR);
7a7cc504 3356 if (dfd < 0)
a322f70c 3357 return 2;
3d2c4fc7
DW
3358 rv = load_ddf_headers(dfd, super, NULL);
3359 if (rv == 0)
e1902a7b 3360 rv = load_ddf_local(dfd, super, NULL, 1);
3d2c4fc7
DW
3361 if (rv)
3362 return 1;
a322f70c 3363 }
33414a01 3364
a322f70c
DW
3365 *sbp = super;
3366 if (st->ss == NULL) {
78e44928 3367 st->ss = &super_ddf;
a322f70c
DW
3368 st->minor_version = 0;
3369 st->max_devs = 512;
3370 }
4dd2df09 3371 strcpy(st->container_devnm, fd2devnm(fd));
a322f70c
DW
3372 return 0;
3373}
2b959fbf
N
3374
3375static int load_container_ddf(struct supertype *st, int fd,
3376 char *devname)
3377{
3378 return load_super_ddf_all(st, fd, &st->sb, devname);
3379}
3380
0e600426 3381#endif /* MDASSEMBLE */
a322f70c 3382
a5c7adb3 3383static int check_secondary(const struct vcl *vc)
3384{
3385 const struct vd_config *conf = &vc->conf;
3386 int i;
3387
3388 /* The only DDF secondary RAID level md can support is
3389 * RAID 10, if the stripe sizes and Basic volume sizes
3390 * are all equal.
3391 * Other configurations could in theory be supported by exposing
3392 * the BVDs to user space and using device mapper for the secondary
3393 * mapping. So far we don't support that.
3394 */
3395
3396 __u64 sec_elements[4] = {0, 0, 0, 0};
3397#define __set_sec_seen(n) (sec_elements[(n)>>6] |= (1<<((n)&63)))
3398#define __was_sec_seen(n) ((sec_elements[(n)>>6] & (1<<((n)&63))) != 0)
3399
3400 if (vc->other_bvds == NULL) {
3401 pr_err("No BVDs for secondary RAID found\n");
3402 return -1;
3403 }
3404 if (conf->prl != DDF_RAID1) {
3405 pr_err("Secondary RAID level only supported for mirrored BVD\n");
3406 return -1;
3407 }
3408 if (conf->srl != DDF_2STRIPED && conf->srl != DDF_2SPANNED) {
3409 pr_err("Secondary RAID level %d is unsupported\n",
3410 conf->srl);
3411 return -1;
3412 }
3413 __set_sec_seen(conf->sec_elmnt_seq);
3414 for (i = 0; i < conf->sec_elmnt_count-1; i++) {
3415 const struct vd_config *bvd = vc->other_bvds[i];
3c48f7be 3416 if (bvd->sec_elmnt_seq == DDF_UNUSED_BVD)
c98567ba 3417 continue;
a5c7adb3 3418 if (bvd->srl != conf->srl) {
3419 pr_err("Inconsistent secondary RAID level across BVDs\n");
3420 return -1;
3421 }
3422 if (bvd->prl != conf->prl) {
3423 pr_err("Different RAID levels for BVDs are unsupported\n");
3424 return -1;
3425 }
3426 if (bvd->prim_elmnt_count != conf->prim_elmnt_count) {
3427 pr_err("All BVDs must have the same number of primary elements\n");
3428 return -1;
3429 }
3430 if (bvd->chunk_shift != conf->chunk_shift) {
3431 pr_err("Different strip sizes for BVDs are unsupported\n");
3432 return -1;
3433 }
3434 if (bvd->array_blocks != conf->array_blocks) {
3435 pr_err("Different BVD sizes are unsupported\n");
3436 return -1;
3437 }
3438 __set_sec_seen(bvd->sec_elmnt_seq);
3439 }
3440 for (i = 0; i < conf->sec_elmnt_count; i++) {
3441 if (!__was_sec_seen(i)) {
3442 pr_err("BVD %d is missing\n", i);
3443 return -1;
3444 }
3445 }
3446 return 0;
3447}
3448
8a38db86 3449static unsigned int get_pd_index_from_refnum(const struct vcl *vc,
4e587018 3450 __u32 refnum, unsigned int nmax,
3451 const struct vd_config **bvd,
3452 unsigned int *idx)
8a38db86 3453{
4e587018 3454 unsigned int i, j, n, sec, cnt;
3455
3456 cnt = __be16_to_cpu(vc->conf.prim_elmnt_count);
3457 sec = (vc->conf.sec_elmnt_count == 1 ? 0 : vc->conf.sec_elmnt_seq);
3458
3459 for (i = 0, j = 0 ; i < nmax ; i++) {
3460 /* j counts valid entries for this BVD */
3461 if (vc->conf.phys_refnum[i] != 0xffffffff)
3462 j++;
3463 if (vc->conf.phys_refnum[i] == refnum) {
3464 *bvd = &vc->conf;
3465 *idx = i;
3466 return sec * cnt + j - 1;
3467 }
3468 }
3469 if (vc->other_bvds == NULL)
3470 goto bad;
3471
3472 for (n = 1; n < vc->conf.sec_elmnt_count; n++) {
3473 struct vd_config *vd = vc->other_bvds[n-1];
4e587018 3474 sec = vd->sec_elmnt_seq;
3c48f7be 3475 if (sec == DDF_UNUSED_BVD)
3476 continue;
4e587018 3477 for (i = 0, j = 0 ; i < nmax ; i++) {
3478 if (vd->phys_refnum[i] != 0xffffffff)
3479 j++;
3480 if (vd->phys_refnum[i] == refnum) {
3481 *bvd = vd;
3482 *idx = i;
3483 return sec * cnt + j - 1;
3484 }
3485 }
3486 }
3487bad:
3488 *bvd = NULL;
d6e7b083 3489 return DDF_NOTFOUND;
8a38db86 3490}
3491
00bbdbda 3492static struct mdinfo *container_content_ddf(struct supertype *st, char *subarray)
598f0d58
NB
3493{
3494 /* Given a container loaded by load_super_ddf_all,
3495 * extract information about all the arrays into
3496 * an mdinfo tree.
3497 *
3498 * For each vcl in conflist: create an mdinfo, fill it in,
3499 * then look for matching devices (phys_refnum) in dlist
3500 * and create appropriate device mdinfo.
3501 */
3502 struct ddf_super *ddf = st->sb;
3503 struct mdinfo *rest = NULL;
3504 struct vcl *vc;
3505
3506 for (vc = ddf->conflist ; vc ; vc=vc->next)
3507 {
f21e18ca
N
3508 unsigned int i;
3509 unsigned int j;
598f0d58 3510 struct mdinfo *this;
00bbdbda 3511 char *ep;
90fa1a29 3512 __u32 *cptr;
8a38db86 3513 unsigned int pd;
00bbdbda
N
3514
3515 if (subarray &&
3516 (strtoul(subarray, &ep, 10) != vc->vcnum ||
3517 *ep != '\0'))
3518 continue;
3519
a5c7adb3 3520 if (vc->conf.sec_elmnt_count > 1) {
3521 if (check_secondary(vc) != 0)
3522 continue;
3523 }
3524
503975b9 3525 this = xcalloc(1, sizeof(*this));
598f0d58
NB
3526 this->next = rest;
3527 rest = this;
3528
8a2848a7 3529 if (layout_ddf2md(&vc->conf, &this->array))
3530 continue;
598f0d58 3531 this->array.md_minor = -1;
f35f2525
N
3532 this->array.major_version = -1;
3533 this->array.minor_version = -2;
90fa1a29
JS
3534 cptr = (__u32 *)(vc->conf.guid + 16);
3535 this->array.ctime = DECADE + __be32_to_cpu(*cptr);
598f0d58
NB
3536 this->array.utime = DECADE +
3537 __be32_to_cpu(vc->conf.timestamp);
3538 this->array.chunk_size = 512 << vc->conf.chunk_shift;
3539
59e36268 3540 i = vc->vcnum;
7a7cc504
NB
3541 if ((ddf->virt->entries[i].state & DDF_state_inconsistent) ||
3542 (ddf->virt->entries[i].init_state & DDF_initstate_mask) !=
ed9d66aa 3543 DDF_init_full) {
598f0d58 3544 this->array.state = 0;
ed9d66aa
NB
3545 this->resync_start = 0;
3546 } else {
598f0d58 3547 this->array.state = 1;
b7528a20 3548 this->resync_start = MaxSector;
ed9d66aa 3549 }
db42fa9b
N
3550 memcpy(this->name, ddf->virt->entries[i].name, 16);
3551 this->name[16]=0;
3552 for(j=0; j<16; j++)
3553 if (this->name[j] == ' ')
3554 this->name[j] = 0;
598f0d58
NB
3555
3556 memset(this->uuid, 0, sizeof(this->uuid));
3557 this->component_size = __be64_to_cpu(vc->conf.blocks);
3558 this->array.size = this->component_size / 2;
5f2aace8 3559 this->container_member = i;
598f0d58 3560
c5afc314
N
3561 ddf->currentconf = vc;
3562 uuid_from_super_ddf(st, this->uuid);
3563 ddf->currentconf = NULL;
3564
60f18132 3565 sprintf(this->text_version, "/%s/%d",
4dd2df09 3566 st->container_devnm, this->container_member);
60f18132 3567
8a38db86 3568 for (pd = 0; pd < __be16_to_cpu(ddf->phys->used_pdes); pd++) {
598f0d58
NB
3569 struct mdinfo *dev;
3570 struct dl *d;
4e587018 3571 const struct vd_config *bvd;
3572 unsigned int iphys;
3573 __u64 *lba_offset;
fa033bec 3574 int stt;
598f0d58 3575
8a38db86 3576 if (ddf->phys->entries[pd].refnum == 0xFFFFFFFF)
bc17324f 3577 continue;
0cf5ef67
N
3578
3579 stt = __be16_to_cpu(ddf->phys->entries[pd].state);
fa033bec
N
3580 if ((stt & (DDF_Online|DDF_Failed|DDF_Rebuilding))
3581 != DDF_Online)
3582 continue;
3583
8a38db86 3584 i = get_pd_index_from_refnum(
4e587018 3585 vc, ddf->phys->entries[pd].refnum,
3586 ddf->mppe, &bvd, &iphys);
d6e7b083 3587 if (i == DDF_NOTFOUND)
8a38db86 3588 continue;
3589
fa033bec 3590 this->array.working_disks++;
bc17324f 3591
0cf5ef67 3592 for (d = ddf->dlist; d ; d=d->next)
8a38db86 3593 if (d->disk.refnum ==
3594 ddf->phys->entries[pd].refnum)
0cf5ef67
N
3595 break;
3596 if (d == NULL)
3597 /* Haven't found that one yet, maybe there are others */
3598 continue;
3599
503975b9 3600 dev = xcalloc(1, sizeof(*dev));
598f0d58
NB
3601 dev->next = this->devs;
3602 this->devs = dev;
3603
3604 dev->disk.number = __be32_to_cpu(d->disk.refnum);
3605 dev->disk.major = d->major;
3606 dev->disk.minor = d->minor;
3607 dev->disk.raid_disk = i;
3608 dev->disk.state = (1<<MD_DISK_SYNC)|(1<<MD_DISK_ACTIVE);
d23534e4 3609 dev->recovery_start = MaxSector;
598f0d58 3610
120f7677 3611 dev->events = __be32_to_cpu(ddf->primary.seq);
4e587018 3612 lba_offset = (__u64 *)&bvd->phys_refnum[ddf->mppe];
3613 dev->data_offset = __be64_to_cpu(lba_offset[iphys]);
3614 dev->component_size = __be64_to_cpu(bvd->blocks);
598f0d58
NB
3615 if (d->devname)
3616 strcpy(dev->name, d->devname);
3617 }
3618 }
3619 return rest;
3620}
3621
955e9ea1 3622static int store_super_ddf(struct supertype *st, int fd)
a322f70c 3623{
955e9ea1 3624 struct ddf_super *ddf = st->sb;
a322f70c 3625 unsigned long long dsize;
6416d527 3626 void *buf;
3d2c4fc7 3627 int rc;
a322f70c 3628
955e9ea1
DW
3629 if (!ddf)
3630 return 1;
3631
a322f70c
DW
3632 if (!get_dev_size(fd, NULL, &dsize))
3633 return 1;
3634
dbf98368 3635 if (ddf->dlist || ddf->conflist) {
3636 struct stat sta;
3637 struct dl *dl;
3638 int ofd, ret;
3639
3640 if (fstat(fd, &sta) == -1 || !S_ISBLK(sta.st_mode)) {
3641 pr_err("%s: file descriptor for invalid device\n",
3642 __func__);
3643 return 1;
3644 }
3645 for (dl = ddf->dlist; dl; dl = dl->next)
3646 if (dl->major == (int)major(sta.st_rdev) &&
3647 dl->minor == (int)minor(sta.st_rdev))
3648 break;
3649 if (!dl) {
3650 pr_err("%s: couldn't find disk %d/%d\n", __func__,
3651 (int)major(sta.st_rdev),
3652 (int)minor(sta.st_rdev));
3653 return 1;
3654 }
3655 /*
3656 For DDF, writing to just one disk makes no sense.
3657 We would run the risk of writing inconsistent meta data
3658 to the devices. So just call __write_init_super_ddf and
3659 write to all devices, including this one.
3660 Use the fd passed to this function, just in case dl->fd
3661 is invalid.
3662 */
3663 ofd = dl->fd;
3664 dl->fd = fd;
3665 ret = __write_init_super_ddf(st);
3666 dl->fd = ofd;
3667 return ret;
3668 }
3669
3d2c4fc7
DW
3670 if (posix_memalign(&buf, 512, 512) != 0)
3671 return 1;
6416d527
NB
3672 memset(buf, 0, 512);
3673
a322f70c 3674 lseek64(fd, dsize-512, 0);
3d2c4fc7 3675 rc = write(fd, buf, 512);
6416d527 3676 free(buf);
3d2c4fc7
DW
3677 if (rc < 0)
3678 return 1;
a322f70c
DW
3679 return 0;
3680}
3681
a19c88b8
NB
3682static int compare_super_ddf(struct supertype *st, struct supertype *tst)
3683{
3684 /*
3685 * return:
3686 * 0 same, or first was empty, and second was copied
3687 * 1 second had wrong number
3688 * 2 wrong uuid
3689 * 3 wrong other info
3690 */
3691 struct ddf_super *first = st->sb;
3692 struct ddf_super *second = tst->sb;
4eefd651 3693 struct dl *dl1, *dl2;
3694 struct vcl *vl1, *vl2;
2d210697 3695 unsigned int max_vds, max_pds, pd, vd;
a19c88b8
NB
3696
3697 if (!first) {
3698 st->sb = tst->sb;
3699 tst->sb = NULL;
3700 return 0;
3701 }
3702
3703 if (memcmp(first->anchor.guid, second->anchor.guid, DDF_GUID_LEN) != 0)
3704 return 2;
3705
2d210697 3706 if (first->anchor.seq != second->anchor.seq) {
3707 dprintf("%s: sequence number mismatch %u/%u\n", __func__,
3708 __be32_to_cpu(first->anchor.seq),
3709 __be32_to_cpu(second->anchor.seq));
3710 return 3;
3711 }
3712 if (first->max_part != second->max_part ||
3713 first->phys->used_pdes != second->phys->used_pdes ||
3714 first->virt->populated_vdes != second->virt->populated_vdes) {
3715 dprintf("%s: PD/VD number mismatch\n", __func__);
3716 return 3;
3717 }
3718
3719 max_pds = __be16_to_cpu(first->phys->used_pdes);
3720 for (dl2 = second->dlist; dl2; dl2 = dl2->next) {
3721 for (pd = 0; pd < max_pds; pd++)
3722 if (first->phys->entries[pd].refnum == dl2->disk.refnum)
3723 break;
3724 if (pd == max_pds) {
3725 dprintf("%s: no match for disk %08x\n", __func__,
3726 __be32_to_cpu(dl2->disk.refnum));
3727 return 3;
3728 }
3729 }
3730
3731 max_vds = __be16_to_cpu(first->active->max_vd_entries);
3732 for (vl2 = second->conflist; vl2; vl2 = vl2->next) {
3733 if (vl2->conf.magic != DDF_VD_CONF_MAGIC)
3734 continue;
3735 for (vd = 0; vd < max_vds; vd++)
3736 if (!memcmp(first->virt->entries[vd].guid,
3737 vl2->conf.guid, DDF_GUID_LEN))
3738 break;
3739 if (vd == max_vds) {
3740 dprintf("%s: no match for VD config\n", __func__);
3741 return 3;
3742 }
3743 }
a19c88b8 3744 /* FIXME should I look at anything else? */
2d210697 3745
4eefd651 3746 /*
3747 At this point we are fairly sure that the meta data matches.
3748 But the new disk may contain additional local data.
3749 Add it to the super block.
3750 */
3751 for (vl2 = second->conflist; vl2; vl2 = vl2->next) {
3752 for (vl1 = first->conflist; vl1; vl1 = vl1->next)
3753 if (!memcmp(vl1->conf.guid, vl2->conf.guid,
3754 DDF_GUID_LEN))
3755 break;
3756 if (vl1) {
3757 if (vl1->other_bvds != NULL &&
3758 vl1->conf.sec_elmnt_seq !=
3759 vl2->conf.sec_elmnt_seq) {
3760 dprintf("%s: adding BVD %u\n", __func__,
3761 vl2->conf.sec_elmnt_seq);
3762 add_other_bvd(vl1, &vl2->conf,
3763 first->conf_rec_len*512);
3764 }
3765 continue;
3766 }
3767
3768 if (posix_memalign((void **)&vl1, 512,
3769 (first->conf_rec_len*512 +
3770 offsetof(struct vcl, conf))) != 0) {
3771 pr_err("%s could not allocate vcl buf\n",
3772 __func__);
3773 return 3;
3774 }
3775
3776 vl1->next = first->conflist;
3777 vl1->block_sizes = NULL;
4eefd651 3778 memcpy(&vl1->conf, &vl2->conf, first->conf_rec_len*512);
3c48f7be 3779 if (alloc_other_bvds(first, vl1) != 0) {
3780 pr_err("%s could not allocate other bvds\n",
3781 __func__);
3782 free(vl1);
3783 return 3;
3784 }
4eefd651 3785 vl1->lba_offset = (__u64 *)
3786 &vl1->conf.phys_refnum[first->mppe];
3787 for (vd = 0; vd < max_vds; vd++)
3788 if (!memcmp(first->virt->entries[vd].guid,
3789 vl1->conf.guid, DDF_GUID_LEN))
3790 break;
3791 vl1->vcnum = vd;
3792 dprintf("%s: added config for VD %u\n", __func__, vl1->vcnum);
3793 first->conflist = vl1;
3794 }
3795
3796 for (dl2 = second->dlist; dl2; dl2 = dl2->next) {
3797 for (dl1 = first->dlist; dl1; dl1 = dl1->next)
3798 if (dl1->disk.refnum == dl2->disk.refnum)
3799 break;
3800 if (dl1)
3801 continue;
3802
3803 if (posix_memalign((void **)&dl1, 512,
3804 sizeof(*dl1) + (first->max_part) * sizeof(dl1->vlist[0]))
3805 != 0) {
3806 pr_err("%s could not allocate disk info buffer\n",
3807 __func__);
3808 return 3;
3809 }
3810 memcpy(dl1, dl2, sizeof(*dl1));
3811 dl1->mdupdate = NULL;
3812 dl1->next = first->dlist;
3813 dl1->fd = -1;
3814 for (pd = 0; pd < max_pds; pd++)
3815 if (first->phys->entries[pd].refnum == dl1->disk.refnum)
3816 break;
3817 dl1->pdnum = pd;
3818 if (dl2->spare) {
3819 if (posix_memalign((void **)&dl1->spare, 512,
3820 first->conf_rec_len*512) != 0) {
3821 pr_err("%s could not allocate spare info buf\n",
3822 __func__);
3823 return 3;
3824 }
3825 memcpy(dl1->spare, dl2->spare, first->conf_rec_len*512);
3826 }
3827 for (vd = 0 ; vd < first->max_part ; vd++) {
3828 if (!dl2->vlist[vd]) {
3829 dl1->vlist[vd] = NULL;
3830 continue;
3831 }
3832 for (vl1 = first->conflist; vl1; vl1 = vl1->next) {
3833 if (!memcmp(vl1->conf.guid,
3834 dl2->vlist[vd]->conf.guid,
3835 DDF_GUID_LEN))
3836 break;
3837 dl1->vlist[vd] = vl1;
3838 }
3839 }
3840 first->dlist = dl1;
3841 dprintf("%s: added disk %d: %08x\n", __func__, dl1->pdnum,
3842 dl1->disk.refnum);
3843 }
3844
a19c88b8
NB
3845 return 0;
3846}
3847
0e600426 3848#ifndef MDASSEMBLE
4e5528c6
NB
3849/*
3850 * A new array 'a' has been started which claims to be instance 'inst'
3851 * within container 'c'.
3852 * We need to confirm that the array matches the metadata in 'c' so
3853 * that we don't corrupt any metadata.
3854 */
cba0191b 3855static int ddf_open_new(struct supertype *c, struct active_array *a, char *inst)
549e9569 3856{
a2aa439e 3857 struct ddf_super *ddf = c->sb;
3858 int n = atoi(inst);
fb9d0acb 3859 if (all_ff(ddf->virt->entries[n].guid)) {
3860 pr_err("%s: subarray %d doesn't exist\n", __func__, n);
a2aa439e 3861 return -ENODEV;
3862 }
3863 dprintf("ddf: open_new %d\n", n);
3864 a->info.container_member = n;
549e9569
NB
3865 return 0;
3866}
3867
4e5528c6
NB
3868/*
3869 * The array 'a' is to be marked clean in the metadata.
ed9d66aa 3870 * If '->resync_start' is not ~(unsigned long long)0, then the array is only
4e5528c6
NB
3871 * clean up to the point (in sectors). If that cannot be recorded in the
3872 * metadata, then leave it as dirty.
3873 *
3874 * For DDF, we need to clear the DDF_state_inconsistent bit in the
3875 * !global! virtual_disk.virtual_entry structure.
3876 */
01f157d7 3877static int ddf_set_array_state(struct active_array *a, int consistent)
549e9569 3878{
4e5528c6
NB
3879 struct ddf_super *ddf = a->container->sb;
3880 int inst = a->info.container_member;
18a2f463 3881 int old = ddf->virt->entries[inst].state;
01f157d7
N
3882 if (consistent == 2) {
3883 /* Should check if a recovery should be started FIXME */
3884 consistent = 1;
b7941fd6 3885 if (!is_resync_complete(&a->info))
01f157d7
N
3886 consistent = 0;
3887 }
ed9d66aa
NB
3888 if (consistent)
3889 ddf->virt->entries[inst].state &= ~DDF_state_inconsistent;
3890 else
4e5528c6 3891 ddf->virt->entries[inst].state |= DDF_state_inconsistent;
18a2f463 3892 if (old != ddf->virt->entries[inst].state)
7d5a7ff3 3893 ddf_set_updates_pending(ddf);
18a2f463
NB
3894
3895 old = ddf->virt->entries[inst].init_state;
ed9d66aa 3896 ddf->virt->entries[inst].init_state &= ~DDF_initstate_mask;
b7941fd6 3897 if (is_resync_complete(&a->info))
ed9d66aa 3898 ddf->virt->entries[inst].init_state |= DDF_init_full;
b7941fd6 3899 else if (a->info.resync_start == 0)
ed9d66aa 3900 ddf->virt->entries[inst].init_state |= DDF_init_not;
4e5528c6 3901 else
ed9d66aa 3902 ddf->virt->entries[inst].init_state |= DDF_init_quick;
18a2f463 3903 if (old != ddf->virt->entries[inst].init_state)
7d5a7ff3 3904 ddf_set_updates_pending(ddf);
ed9d66aa 3905
2c514b71 3906 dprintf("ddf mark %d %s %llu\n", inst, consistent?"clean":"dirty",
b7941fd6 3907 a->info.resync_start);
01f157d7 3908 return consistent;
fd7cde1b
DW
3909}
3910
5ec636b7 3911static int get_bvd_state(const struct ddf_super *ddf,
3912 const struct vd_config *vc)
3913{
3914 unsigned int i, n_bvd, working = 0;
3915 unsigned int n_prim = __be16_to_cpu(vc->prim_elmnt_count);
3916 int pd, st, state;
3917 for (i = 0; i < n_prim; i++) {
3918 if (!find_index_in_bvd(ddf, vc, i, &n_bvd))
3919 continue;
3920 pd = find_phys(ddf, vc->phys_refnum[n_bvd]);
3921 if (pd < 0)
3922 continue;
3923 st = __be16_to_cpu(ddf->phys->entries[pd].state);
3924 if ((st & (DDF_Online|DDF_Failed|DDF_Rebuilding))
3925 == DDF_Online)
3926 working++;
3927 }
3928
3929 state = DDF_state_degraded;
3930 if (working == n_prim)
3931 state = DDF_state_optimal;
3932 else
3933 switch (vc->prl) {
3934 case DDF_RAID0:
3935 case DDF_CONCAT:
3936 case DDF_JBOD:
3937 state = DDF_state_failed;
3938 break;
3939 case DDF_RAID1:
3940 if (working == 0)
3941 state = DDF_state_failed;
3942 else if (working >= 2)
3943 state = DDF_state_part_optimal;
3944 break;
3945 case DDF_RAID4:
3946 case DDF_RAID5:
3947 if (working < n_prim - 1)
3948 state = DDF_state_failed;
3949 break;
3950 case DDF_RAID6:
3951 if (working < n_prim - 2)
3952 state = DDF_state_failed;
3953 else if (working == n_prim - 1)
3954 state = DDF_state_part_optimal;
3955 break;
3956 }
3957 return state;
3958}
3959
0777d17d 3960static int secondary_state(int state, int other, int seclevel)
3961{
3962 if (state == DDF_state_optimal && other == DDF_state_optimal)
3963 return DDF_state_optimal;
3964 if (seclevel == DDF_2MIRRORED) {
3965 if (state == DDF_state_optimal || other == DDF_state_optimal)
3966 return DDF_state_part_optimal;
3967 if (state == DDF_state_failed && other == DDF_state_failed)
3968 return DDF_state_failed;
3969 return DDF_state_degraded;
3970 } else {
3971 if (state == DDF_state_failed || other == DDF_state_failed)
3972 return DDF_state_failed;
3973 if (state == DDF_state_degraded || other == DDF_state_degraded)
3974 return DDF_state_degraded;
3975 return DDF_state_part_optimal;
3976 }
3977}
3978
3979static int get_svd_state(const struct ddf_super *ddf, const struct vcl *vcl)
3980{
3981 int state = get_bvd_state(ddf, &vcl->conf);
3982 unsigned int i;
3983 for (i = 1; i < vcl->conf.sec_elmnt_count; i++) {
3984 state = secondary_state(
3985 state,
3986 get_bvd_state(ddf, vcl->other_bvds[i-1]),
3987 vcl->conf.srl);
3988 }
3989 return state;
3990}
3991
7a7cc504
NB
3992/*
3993 * The state of each disk is stored in the global phys_disk structure
3994 * in phys_disk.entries[n].state.
3995 * This makes various combinations awkward.
3996 * - When a device fails in any array, it must be failed in all arrays
3997 * that include a part of this device.
3998 * - When a component is rebuilding, we cannot include it officially in the
3999 * array unless this is the only array that uses the device.
4000 *
4001 * So: when transitioning:
4002 * Online -> failed, just set failed flag. monitor will propagate
4003 * spare -> online, the device might need to be added to the array.
4004 * spare -> failed, just set failed. Don't worry if in array or not.
4005 */
8d45d196 4006static void ddf_set_disk(struct active_array *a, int n, int state)
549e9569 4007{
7a7cc504 4008 struct ddf_super *ddf = a->container->sb;
baba3f4e 4009 unsigned int inst = a->info.container_member, n_bvd;
4010 struct vcl *vcl;
4011 struct vd_config *vc = find_vdcr(ddf, inst, (unsigned int)n,
4012 &n_bvd, &vcl);
4013 int pd;
e1316fab
N
4014 struct mdinfo *mdi;
4015 struct dl *dl;
7a7cc504
NB
4016
4017 if (vc == NULL) {
2c514b71 4018 dprintf("ddf: cannot find instance %d!!\n", inst);
7a7cc504
NB
4019 return;
4020 }
e1316fab
N
4021 /* Find the matching slot in 'info'. */
4022 for (mdi = a->info.devs; mdi; mdi = mdi->next)
4023 if (mdi->disk.raid_disk == n)
4024 break;
4025 if (!mdi)
4026 return;
4027
4028 /* and find the 'dl' entry corresponding to that. */
4029 for (dl = ddf->dlist; dl; dl = dl->next)
77632af9
N
4030 if (mdi->state_fd >= 0 &&
4031 mdi->disk.major == dl->major &&
e1316fab
N
4032 mdi->disk.minor == dl->minor)
4033 break;
4034 if (!dl)
4035 return;
4036
baba3f4e 4037 pd = find_phys(ddf, vc->phys_refnum[n_bvd]);
e1316fab
N
4038 if (pd < 0 || pd != dl->pdnum) {
4039 /* disk doesn't currently exist or has changed.
4040 * If it is now in_sync, insert it. */
baba3f4e 4041 dprintf("%s: phys disk not found for %d: %d/%d ref %08x\n",
4042 __func__, dl->pdnum, dl->major, dl->minor,
4043 dl->disk.refnum);
4044 dprintf("%s: array %u disk %u ref %08x pd %d\n",
4045 __func__, inst, n_bvd, vc->phys_refnum[n_bvd], pd);
7a7cc504 4046 if ((state & DS_INSYNC) && ! (state & DS_FAULTY)) {
baba3f4e 4047 __u64 *lba_offset;
4048 pd = dl->pdnum; /* FIXME: is this really correct ? */
4049 vc->phys_refnum[n_bvd] = dl->disk.refnum;
4050 lba_offset = (__u64 *)&vc->phys_refnum[ddf->mppe];
4051 lba_offset[n_bvd] = mdi->data_offset;
e1316fab
N
4052 ddf->phys->entries[pd].type &=
4053 ~__cpu_to_be16(DDF_Global_Spare);
4054 ddf->phys->entries[pd].type |=
4055 __cpu_to_be16(DDF_Active_in_VD);
7d5a7ff3 4056 ddf_set_updates_pending(ddf);
7a7cc504
NB
4057 }
4058 } else {
18a2f463 4059 int old = ddf->phys->entries[pd].state;
7a7cc504
NB
4060 if (state & DS_FAULTY)
4061 ddf->phys->entries[pd].state |= __cpu_to_be16(DDF_Failed);
4062 if (state & DS_INSYNC) {
4063 ddf->phys->entries[pd].state |= __cpu_to_be16(DDF_Online);
4064 ddf->phys->entries[pd].state &= __cpu_to_be16(~DDF_Rebuilding);
4065 }
18a2f463 4066 if (old != ddf->phys->entries[pd].state)
7d5a7ff3 4067 ddf_set_updates_pending(ddf);
7a7cc504
NB
4068 }
4069
2c514b71 4070 dprintf("ddf: set_disk %d to %x\n", n, state);
7e1432fb 4071
7a7cc504
NB
4072 /* Now we need to check the state of the array and update
4073 * virtual_disk.entries[n].state.
4074 * It needs to be one of "optimal", "degraded", "failed".
4075 * I don't understand 'deleted' or 'missing'.
4076 */
0777d17d 4077 state = get_svd_state(ddf, vcl);
7a7cc504 4078
18a2f463
NB
4079 if (ddf->virt->entries[inst].state !=
4080 ((ddf->virt->entries[inst].state & ~DDF_state_mask)
4081 | state)) {
4082
4083 ddf->virt->entries[inst].state =
4084 (ddf->virt->entries[inst].state & ~DDF_state_mask)
4085 | state;
7d5a7ff3 4086 ddf_set_updates_pending(ddf);
18a2f463 4087 }
7a7cc504 4088
549e9569
NB
4089}
4090
2e735d19 4091static void ddf_sync_metadata(struct supertype *st)
549e9569 4092{
7a7cc504
NB
4093
4094 /*
4095 * Write all data to all devices.
4096 * Later, we might be able to track whether only local changes
4097 * have been made, or whether any global data has been changed,
4098 * but ddf is sufficiently weird that it probably always
4099 * changes global data ....
4100 */
18a2f463
NB
4101 struct ddf_super *ddf = st->sb;
4102 if (!ddf->updates_pending)
4103 return;
4104 ddf->updates_pending = 0;
1cc7f4fe 4105 __write_init_super_ddf(st);
2c514b71 4106 dprintf("ddf: sync_metadata\n");
549e9569
NB
4107}
4108
88c164f4
NB
4109static void ddf_process_update(struct supertype *st,
4110 struct metadata_update *update)
4111{
4112 /* Apply this update to the metadata.
4113 * The first 4 bytes are a DDF_*_MAGIC which guides
4114 * our actions.
4115 * Possible update are:
4116 * DDF_PHYS_RECORDS_MAGIC
4dd968cc
N
4117 * Add a new physical device or remove an old one.
4118 * Changes to this record only happen implicitly.
88c164f4
NB
4119 * used_pdes is the device number.
4120 * DDF_VIRT_RECORDS_MAGIC
4121 * Add a new VD. Possibly also change the 'access' bits.
4122 * populated_vdes is the entry number.
4123 * DDF_VD_CONF_MAGIC
4124 * New or updated VD. the VIRT_RECORD must already
4125 * exist. For an update, phys_refnum and lba_offset
4126 * (at least) are updated, and the VD_CONF must
4127 * be written to precisely those devices listed with
4128 * a phys_refnum.
4129 * DDF_SPARE_ASSIGN_MAGIC
4130 * replacement Spare Assignment Record... but for which device?
4131 *
4132 * So, e.g.:
4133 * - to create a new array, we send a VIRT_RECORD and
4134 * a VD_CONF. Then assemble and start the array.
4135 * - to activate a spare we send a VD_CONF to add the phys_refnum
4136 * and offset. This will also mark the spare as active with
4137 * a spare-assignment record.
4138 */
4139 struct ddf_super *ddf = st->sb;
4140 __u32 *magic = (__u32*)update->buf;
4141 struct phys_disk *pd;
4142 struct virtual_disk *vd;
4143 struct vd_config *vc;
4144 struct vcl *vcl;
4145 struct dl *dl;
f21e18ca
N
4146 unsigned int mppe;
4147 unsigned int ent;
c7079c84 4148 unsigned int pdnum, pd2;
88c164f4 4149
2c514b71 4150 dprintf("Process update %x\n", *magic);
7e1432fb 4151
88c164f4
NB
4152 switch (*magic) {
4153 case DDF_PHYS_RECORDS_MAGIC:
4154
4155 if (update->len != (sizeof(struct phys_disk) +
4156 sizeof(struct phys_disk_entry)))
4157 return;
4158 pd = (struct phys_disk*)update->buf;
4159
4160 ent = __be16_to_cpu(pd->used_pdes);
4161 if (ent >= __be16_to_cpu(ddf->phys->max_pdes))
4162 return;
4dd968cc
N
4163 if (pd->entries[0].state & __cpu_to_be16(DDF_Missing)) {
4164 struct dl **dlp;
4165 /* removing this disk. */
4166 ddf->phys->entries[ent].state |= __cpu_to_be16(DDF_Missing);
4167 for (dlp = &ddf->dlist; *dlp; dlp = &(*dlp)->next) {
4168 struct dl *dl = *dlp;
4169 if (dl->pdnum == (signed)ent) {
4170 close(dl->fd);
4171 dl->fd = -1;
4172 /* FIXME this doesn't free
4173 * dl->devname */
4174 update->space = dl;
4175 *dlp = dl->next;
4176 break;
4177 }
4178 }
7d5a7ff3 4179 ddf_set_updates_pending(ddf);
4dd968cc
N
4180 return;
4181 }
88c164f4
NB
4182 if (!all_ff(ddf->phys->entries[ent].guid))
4183 return;
4184 ddf->phys->entries[ent] = pd->entries[0];
4185 ddf->phys->used_pdes = __cpu_to_be16(1 +
613b0d17 4186 __be16_to_cpu(ddf->phys->used_pdes));
7d5a7ff3 4187 ddf_set_updates_pending(ddf);
2cc2983d
N
4188 if (ddf->add_list) {
4189 struct active_array *a;
4190 struct dl *al = ddf->add_list;
4191 ddf->add_list = al->next;
4192
4193 al->next = ddf->dlist;
4194 ddf->dlist = al;
4195
4196 /* As a device has been added, we should check
4197 * for any degraded devices that might make
4198 * use of this spare */
4199 for (a = st->arrays ; a; a=a->next)
4200 a->check_degraded = 1;
4201 }
88c164f4
NB
4202 break;
4203
4204 case DDF_VIRT_RECORDS_MAGIC:
4205
4206 if (update->len != (sizeof(struct virtual_disk) +
4207 sizeof(struct virtual_entry)))
4208 return;
4209 vd = (struct virtual_disk*)update->buf;
4210
fb9d0acb 4211 ent = find_unused_vde(ddf);
4212 if (ent == DDF_NOTFOUND)
88c164f4
NB
4213 return;
4214 ddf->virt->entries[ent] = vd->entries[0];
4215 ddf->virt->populated_vdes = __cpu_to_be16(1 +
613b0d17 4216 __be16_to_cpu(ddf->virt->populated_vdes));
7d5a7ff3 4217 ddf_set_updates_pending(ddf);
88c164f4
NB
4218 break;
4219
4220 case DDF_VD_CONF_MAGIC:
2c514b71 4221 dprintf("len %d %d\n", update->len, ddf->conf_rec_len);
88c164f4
NB
4222
4223 mppe = __be16_to_cpu(ddf->anchor.max_primary_element_entries);
f21e18ca 4224 if ((unsigned)update->len != ddf->conf_rec_len * 512)
88c164f4
NB
4225 return;
4226 vc = (struct vd_config*)update->buf;
4227 for (vcl = ddf->conflist; vcl ; vcl = vcl->next)
4228 if (memcmp(vcl->conf.guid, vc->guid, DDF_GUID_LEN) == 0)
4229 break;
2c514b71 4230 dprintf("vcl = %p\n", vcl);
88c164f4
NB
4231 if (vcl) {
4232 /* An update, just copy the phys_refnum and lba_offset
4233 * fields
4234 */
4235 memcpy(vcl->conf.phys_refnum, vc->phys_refnum,
4236 mppe * (sizeof(__u32) + sizeof(__u64)));
4237 } else {
4238 /* A new VD_CONF */
e6b9548d
DW
4239 if (!update->space)
4240 return;
88c164f4
NB
4241 vcl = update->space;
4242 update->space = NULL;
4243 vcl->next = ddf->conflist;
edd8d13c 4244 memcpy(&vcl->conf, vc, update->len);
88c164f4
NB
4245 vcl->lba_offset = (__u64*)
4246 &vcl->conf.phys_refnum[mppe];
fb9d0acb 4247 ent = find_vde_by_guid(ddf, vc->guid);
4248 if (ent == DDF_NOTFOUND)
4249 return;
4250 vcl->vcnum = ent;
88c164f4
NB
4251 ddf->conflist = vcl;
4252 }
c7079c84
N
4253 /* Set DDF_Transition on all Failed devices - to help
4254 * us detect those that are no longer in use
4255 */
4256 for (pdnum = 0; pdnum < __be16_to_cpu(ddf->phys->used_pdes); pdnum++)
4257 if (ddf->phys->entries[pdnum].state
4258 & __be16_to_cpu(DDF_Failed))
4259 ddf->phys->entries[pdnum].state
4260 |= __be16_to_cpu(DDF_Transition);
88c164f4
NB
4261 /* Now make sure vlist is correct for each dl. */
4262 for (dl = ddf->dlist; dl; dl = dl->next) {
f21e18ca
N
4263 unsigned int dn;
4264 unsigned int vn = 0;
8401644c 4265 int in_degraded = 0;
88c164f4
NB
4266 for (vcl = ddf->conflist; vcl ; vcl = vcl->next)
4267 for (dn=0; dn < ddf->mppe ; dn++)
4268 if (vcl->conf.phys_refnum[dn] ==
4269 dl->disk.refnum) {
8401644c 4270 int vstate;
2c514b71
NB
4271 dprintf("dev %d has %p at %d\n",
4272 dl->pdnum, vcl, vn);
c7079c84
N
4273 /* Clear the Transition flag */
4274 if (ddf->phys->entries[dl->pdnum].state
4275 & __be16_to_cpu(DDF_Failed))
4276 ddf->phys->entries[dl->pdnum].state &=
4277 ~__be16_to_cpu(DDF_Transition);
4278
88c164f4 4279 dl->vlist[vn++] = vcl;
8401644c
N
4280 vstate = ddf->virt->entries[vcl->vcnum].state
4281 & DDF_state_mask;
4282 if (vstate == DDF_state_degraded ||
4283 vstate == DDF_state_part_optimal)
4284 in_degraded = 1;
88c164f4
NB
4285 break;
4286 }
4287 while (vn < ddf->max_part)
4288 dl->vlist[vn++] = NULL;
7e1432fb
NB
4289 if (dl->vlist[0]) {
4290 ddf->phys->entries[dl->pdnum].type &=
4291 ~__cpu_to_be16(DDF_Global_Spare);
8401644c
N
4292 if (!(ddf->phys->entries[dl->pdnum].type &
4293 __cpu_to_be16(DDF_Active_in_VD))) {
613b0d17
N
4294 ddf->phys->entries[dl->pdnum].type |=
4295 __cpu_to_be16(DDF_Active_in_VD);
4296 if (in_degraded)
4297 ddf->phys->entries[dl->pdnum].state |=
4298 __cpu_to_be16(DDF_Rebuilding);
4299 }
7e1432fb
NB
4300 }
4301 if (dl->spare) {
4302 ddf->phys->entries[dl->pdnum].type &=
4303 ~__cpu_to_be16(DDF_Global_Spare);
4304 ddf->phys->entries[dl->pdnum].type |=
4305 __cpu_to_be16(DDF_Spare);
4306 }
4307 if (!dl->vlist[0] && !dl->spare) {
4308 ddf->phys->entries[dl->pdnum].type |=
4309 __cpu_to_be16(DDF_Global_Spare);
4310 ddf->phys->entries[dl->pdnum].type &=
4311 ~__cpu_to_be16(DDF_Spare |
4312 DDF_Active_in_VD);
4313 }
88c164f4 4314 }
c7079c84
N
4315
4316 /* Now remove any 'Failed' devices that are not part
4317 * of any VD. They will have the Transition flag set.
4318 * Once done, we need to update all dl->pdnum numbers.
4319 */
4320 pd2 = 0;
4321 for (pdnum = 0; pdnum < __be16_to_cpu(ddf->phys->used_pdes); pdnum++)
4322 if ((ddf->phys->entries[pdnum].state
4323 & __be16_to_cpu(DDF_Failed))
4324 && (ddf->phys->entries[pdnum].state
4325 & __be16_to_cpu(DDF_Transition)))
4326 /* skip this one */;
4327 else if (pdnum == pd2)
4328 pd2++;
4329 else {
4330 ddf->phys->entries[pd2] = ddf->phys->entries[pdnum];
4331 for (dl = ddf->dlist; dl; dl = dl->next)
4332 if (dl->pdnum == (int)pdnum)
4333 dl->pdnum = pd2;
4334 pd2++;
4335 }
4336 ddf->phys->used_pdes = __cpu_to_be16(pd2);
4337 while (pd2 < pdnum) {
4338 memset(ddf->phys->entries[pd2].guid, 0xff, DDF_GUID_LEN);
4339 pd2++;
4340 }
4341
7d5a7ff3 4342 ddf_set_updates_pending(ddf);
88c164f4
NB
4343 break;
4344 case DDF_SPARE_ASSIGN_MAGIC:
4345 default: break;
4346 }
4347}
4348
edd8d13c
NB
4349static void ddf_prepare_update(struct supertype *st,
4350 struct metadata_update *update)
4351{
4352 /* This update arrived at managemon.
4353 * We are about to pass it to monitor.
4354 * If a malloc is needed, do it here.
4355 */
4356 struct ddf_super *ddf = st->sb;
4357 __u32 *magic = (__u32*)update->buf;
4358 if (*magic == DDF_VD_CONF_MAGIC)
e6b9548d 4359 if (posix_memalign(&update->space, 512,
613b0d17
N
4360 offsetof(struct vcl, conf)
4361 + ddf->conf_rec_len * 512) != 0)
e6b9548d 4362 update->space = NULL;
edd8d13c
NB
4363}
4364
7e1432fb
NB
4365/*
4366 * Check if the array 'a' is degraded but not failed.
4367 * If it is, find as many spares as are available and needed and
4368 * arrange for their inclusion.
4369 * We only choose devices which are not already in the array,
4370 * and prefer those with a spare-assignment to this array.
4371 * otherwise we choose global spares - assuming always that
4372 * there is enough room.
4373 * For each spare that we assign, we return an 'mdinfo' which
4374 * describes the position for the device in the array.
4375 * We also add to 'updates' a DDF_VD_CONF_MAGIC update with
4376 * the new phys_refnum and lba_offset values.
4377 *
4378 * Only worry about BVDs at the moment.
4379 */
4380static struct mdinfo *ddf_activate_spare(struct active_array *a,
4381 struct metadata_update **updates)
4382{
4383 int working = 0;
4384 struct mdinfo *d;
4385 struct ddf_super *ddf = a->container->sb;
4386 int global_ok = 0;
4387 struct mdinfo *rv = NULL;
4388 struct mdinfo *di;
4389 struct metadata_update *mu;
4390 struct dl *dl;
4391 int i;
baba3f4e 4392 struct vcl *vcl;
7e1432fb
NB
4393 struct vd_config *vc;
4394 __u64 *lba;
baba3f4e 4395 unsigned int n_bvd;
7e1432fb 4396
7e1432fb
NB
4397 for (d = a->info.devs ; d ; d = d->next) {
4398 if ((d->curr_state & DS_FAULTY) &&
613b0d17 4399 d->state_fd >= 0)
7e1432fb
NB
4400 /* wait for Removal to happen */
4401 return NULL;
4402 if (d->state_fd >= 0)
4403 working ++;
4404 }
4405
2c514b71
NB
4406 dprintf("ddf_activate: working=%d (%d) level=%d\n", working, a->info.array.raid_disks,
4407 a->info.array.level);
7e1432fb
NB
4408 if (working == a->info.array.raid_disks)
4409 return NULL; /* array not degraded */
4410 switch (a->info.array.level) {
4411 case 1:
4412 if (working == 0)
4413 return NULL; /* failed */
4414 break;
4415 case 4:
4416 case 5:
4417 if (working < a->info.array.raid_disks - 1)
4418 return NULL; /* failed */
4419 break;
4420 case 6:
4421 if (working < a->info.array.raid_disks - 2)
4422 return NULL; /* failed */
4423 break;
4424 default: /* concat or stripe */
4425 return NULL; /* failed */
4426 }
4427
4428 /* For each slot, if it is not working, find a spare */
4429 dl = ddf->dlist;
4430 for (i = 0; i < a->info.array.raid_disks; i++) {
4431 for (d = a->info.devs ; d ; d = d->next)
4432 if (d->disk.raid_disk == i)
4433 break;
2c514b71 4434 dprintf("found %d: %p %x\n", i, d, d?d->curr_state:0);
7e1432fb
NB
4435 if (d && (d->state_fd >= 0))
4436 continue;
4437
4438 /* OK, this device needs recovery. Find a spare */
4439 again:
4440 for ( ; dl ; dl = dl->next) {
4441 unsigned long long esize;
4442 unsigned long long pos;
4443 struct mdinfo *d2;
4444 int is_global = 0;
4445 int is_dedicated = 0;
4446 struct extent *ex;
f21e18ca 4447 unsigned int j;
7e1432fb
NB
4448 /* If in this array, skip */
4449 for (d2 = a->info.devs ; d2 ; d2 = d2->next)
7590d562
N
4450 if (d2->state_fd >= 0 &&
4451 d2->disk.major == dl->major &&
7e1432fb 4452 d2->disk.minor == dl->minor) {
2c514b71 4453 dprintf("%x:%x already in array\n", dl->major, dl->minor);
7e1432fb
NB
4454 break;
4455 }
4456 if (d2)
4457 continue;
4458 if (ddf->phys->entries[dl->pdnum].type &
4459 __cpu_to_be16(DDF_Spare)) {
4460 /* Check spare assign record */
4461 if (dl->spare) {
4462 if (dl->spare->type & DDF_spare_dedicated) {
4463 /* check spare_ents for guid */
4464 for (j = 0 ;
4465 j < __be16_to_cpu(dl->spare->populated);
4466 j++) {
4467 if (memcmp(dl->spare->spare_ents[j].guid,
4468 ddf->virt->entries[a->info.container_member].guid,
4469 DDF_GUID_LEN) == 0)
4470 is_dedicated = 1;
4471 }
4472 } else
4473 is_global = 1;
4474 }
4475 } else if (ddf->phys->entries[dl->pdnum].type &
4476 __cpu_to_be16(DDF_Global_Spare)) {
4477 is_global = 1;
e0e7aeaa
N
4478 } else if (!(ddf->phys->entries[dl->pdnum].state &
4479 __cpu_to_be16(DDF_Failed))) {
4480 /* we can possibly use some of this */
4481 is_global = 1;
7e1432fb
NB
4482 }
4483 if ( ! (is_dedicated ||
4484 (is_global && global_ok))) {
2c514b71 4485 dprintf("%x:%x not suitable: %d %d\n", dl->major, dl->minor,
613b0d17 4486 is_dedicated, is_global);
7e1432fb
NB
4487 continue;
4488 }
4489
4490 /* We are allowed to use this device - is there space?
4491 * We need a->info.component_size sectors */
4492 ex = get_extents(ddf, dl);
4493 if (!ex) {
2c514b71 4494 dprintf("cannot get extents\n");
7e1432fb
NB
4495 continue;
4496 }
4497 j = 0; pos = 0;
4498 esize = 0;
4499
4500 do {
4501 esize = ex[j].start - pos;
4502 if (esize >= a->info.component_size)
4503 break;
e5cc7d46
N
4504 pos = ex[j].start + ex[j].size;
4505 j++;
4506 } while (ex[j-1].size);
7e1432fb
NB
4507
4508 free(ex);
4509 if (esize < a->info.component_size) {
e5cc7d46
N
4510 dprintf("%x:%x has no room: %llu %llu\n",
4511 dl->major, dl->minor,
2c514b71 4512 esize, a->info.component_size);
7e1432fb
NB
4513 /* No room */
4514 continue;
4515 }
4516
4517 /* Cool, we have a device with some space at pos */
503975b9 4518 di = xcalloc(1, sizeof(*di));
7e1432fb
NB
4519 di->disk.number = i;
4520 di->disk.raid_disk = i;
4521 di->disk.major = dl->major;
4522 di->disk.minor = dl->minor;
4523 di->disk.state = 0;
d23534e4 4524 di->recovery_start = 0;
7e1432fb
NB
4525 di->data_offset = pos;
4526 di->component_size = a->info.component_size;
4527 di->container_member = dl->pdnum;
4528 di->next = rv;
4529 rv = di;
2c514b71
NB
4530 dprintf("%x:%x to be %d at %llu\n", dl->major, dl->minor,
4531 i, pos);
7e1432fb
NB
4532
4533 break;
4534 }
4535 if (!dl && ! global_ok) {
4536 /* not enough dedicated spares, try global */
4537 global_ok = 1;
4538 dl = ddf->dlist;
4539 goto again;
4540 }
4541 }
4542
4543 if (!rv)
4544 /* No spares found */
4545 return rv;
4546 /* Now 'rv' has a list of devices to return.
4547 * Create a metadata_update record to update the
4548 * phys_refnum and lba_offset values
4549 */
503975b9
N
4550 mu = xmalloc(sizeof(*mu));
4551 if (posix_memalign(&mu->space, 512, sizeof(struct vcl)) != 0) {
79244939
DW
4552 free(mu);
4553 mu = NULL;
4554 }
503975b9 4555 mu->buf = xmalloc(ddf->conf_rec_len * 512);
7590d562
N
4556 mu->len = ddf->conf_rec_len * 512;
4557 mu->space = NULL;
f50ae22e 4558 mu->space_list = NULL;
7e1432fb 4559 mu->next = *updates;
baba3f4e 4560 vc = find_vdcr(ddf, a->info.container_member, di->disk.raid_disk,
4561 &n_bvd, &vcl);
7e1432fb
NB
4562 memcpy(mu->buf, vc, ddf->conf_rec_len * 512);
4563
4564 vc = (struct vd_config*)mu->buf;
4565 lba = (__u64*)&vc->phys_refnum[ddf->mppe];
4566 for (di = rv ; di ; di = di->next) {
4567 vc->phys_refnum[di->disk.raid_disk] =
4568 ddf->phys->entries[dl->pdnum].refnum;
4569 lba[di->disk.raid_disk] = di->data_offset;
4570 }
4571 *updates = mu;
4572 return rv;
4573}
0e600426 4574#endif /* MDASSEMBLE */
7e1432fb 4575
b640a252
N
4576static int ddf_level_to_layout(int level)
4577{
4578 switch(level) {
4579 case 0:
4580 case 1:
4581 return 0;
4582 case 5:
4583 return ALGORITHM_LEFT_SYMMETRIC;
4584 case 6:
4585 return ALGORITHM_ROTATING_N_CONTINUE;
4586 case 10:
4587 return 0x102;
4588 default:
4589 return UnSet;
4590 }
4591}
4592
30f58b22
DW
4593static void default_geometry_ddf(struct supertype *st, int *level, int *layout, int *chunk)
4594{
4595 if (level && *level == UnSet)
4596 *level = LEVEL_CONTAINER;
4597
4598 if (level && layout && *layout == UnSet)
4599 *layout = ddf_level_to_layout(*level);
4600}
4601
a322f70c
DW
4602struct superswitch super_ddf = {
4603#ifndef MDASSEMBLE
4604 .examine_super = examine_super_ddf,
4605 .brief_examine_super = brief_examine_super_ddf,
4737ae25 4606 .brief_examine_subarrays = brief_examine_subarrays_ddf,
bceedeec 4607 .export_examine_super = export_examine_super_ddf,
a322f70c
DW
4608 .detail_super = detail_super_ddf,
4609 .brief_detail_super = brief_detail_super_ddf,
4610 .validate_geometry = validate_geometry_ddf,
78e44928 4611 .write_init_super = write_init_super_ddf,
0e600426 4612 .add_to_super = add_to_super_ddf,
4dd968cc 4613 .remove_from_super = remove_from_super_ddf,
2b959fbf 4614 .load_container = load_container_ddf,
74db60b0 4615 .copy_metadata = copy_metadata_ddf,
a322f70c
DW
4616#endif
4617 .match_home = match_home_ddf,
4618 .uuid_from_super= uuid_from_super_ddf,
4619 .getinfo_super = getinfo_super_ddf,
4620 .update_super = update_super_ddf,
4621
4622 .avail_size = avail_size_ddf,
4623
a19c88b8
NB
4624 .compare_super = compare_super_ddf,
4625
a322f70c 4626 .load_super = load_super_ddf,
ba7eb04f 4627 .init_super = init_super_ddf,
955e9ea1 4628 .store_super = store_super_ddf,
a322f70c
DW
4629 .free_super = free_super_ddf,
4630 .match_metadata_desc = match_metadata_desc_ddf,
78e44928 4631 .container_content = container_content_ddf,
30f58b22 4632 .default_geometry = default_geometry_ddf,
a322f70c 4633
a322f70c 4634 .external = 1,
549e9569 4635
0e600426 4636#ifndef MDASSEMBLE
549e9569
NB
4637/* for mdmon */
4638 .open_new = ddf_open_new,
ed9d66aa 4639 .set_array_state= ddf_set_array_state,
549e9569
NB
4640 .set_disk = ddf_set_disk,
4641 .sync_metadata = ddf_sync_metadata,
88c164f4 4642 .process_update = ddf_process_update,
edd8d13c 4643 .prepare_update = ddf_prepare_update,
7e1432fb 4644 .activate_spare = ddf_activate_spare,
0e600426 4645#endif
4cce4069 4646 .name = "ddf",
a322f70c 4647};