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