~xnox/ubuntu/quantal/mdadm/merge

« back to all changes in this revision

Viewing changes to super-ddf.c

  • Committer: Dmitrijs Ledkovs
  • Author(s): Surbhi Palande
  • Date: 2010-09-30 17:46:19 UTC
  • mfrom: (1.1.25 sid)
  • Revision ID: dmitrijs.ledkovs@canonical.com-20100930174619-cqsokylnluraiyr8
Tags: 3.1.4-1+8efb9d1ubuntu1
* Merge from debian unstable. (LP: #603582) 
* Remaining changes
  - Assemble.c, config.c: upgraded to the mdadm-3.1.4 version of these files
    from Debian.
  - debian/control: we need udev and util-linux in the right version. We
    also remove the build dependency from quilt and docbook-to-man as both
    are not used in Ubuntus mdadm.
  - debian/initramfs/hook: kept the Ubuntus version for handling the absence
    of active raid arrays in <initramfs>/etc/mdadm/mdadm.conf
  - debian/initramfs/script.local-top.DEBIAN, debian/mdadm-startall,
    debian/mdadm.raid.DEBIAN: removed. udev does its job now instead.
  - debian/mdadm-startall.sgml, debian/mdadm-startall.8: documentation of
    unused startall script
  - debian/mdadm.config, debian/mdadm.postinst - let udev do the handling
    instead. Resolved merge conflict by keeping Ubuntu's version.
  - debian/rules: kept debian's switch to using dh_lintian
  - debian/mdadm.links, debian/mdadm.manpages: dropped owing to the fact
    that these are not used in Ubuntu. Also dropped the build-dep on docbook
    to man)
  - debian/mdadm.postinst, debian/mdadm.config, initramfs/init-premount:
    boot-degraded enablement; maintain udev starting of RAID devices;
    init-premount hook script for the initramfs, to provide information at
    boot
  - debian/mkconf.in is the older mkconf. Kept the Ubuntus version.
  - debian/rules: Kept Ubuntus version for installing apport hooks, not
    installing un-used startall script and for adding a udev rule
    corresponding to mdadm.
  - debian/install-rc, check.d/_numbers, check.d/root_on_raid: Ubuntu partman
    installer changes
  - debian/presubj: Dropped this unused bug reporting file. Instead use
    source_mdadm.py act as an apport hook for bug handling.
  - rename debian/mdadm.vol_id.udev to debian/mdadm.mdadm-blkid.udev so that
    the rules file ends up with a more reasonable name

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * mdadm - manage Linux "md" devices aka RAID arrays.
 
3
 *
 
4
 * Copyright (C) 2006-2009 Neil Brown <neilb@suse.de>
 
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"
 
30
#include "mdmon.h"
 
31
#include "sha1.h"
 
32
#include <values.h>
 
33
 
 
34
/* a non-official T10 name for creation GUIDs */
 
35
static 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))
 
42
unsigned long crc32(
 
43
        unsigned long crc,
 
44
        const unsigned char *buf,
 
45
        unsigned len);
 
46
 
 
47
/* The DDF metadata handling.
 
48
 * DDF metadata lives at the end of the device.
 
49
 * The last 512 byte block provides an 'anchor' which is used to locate
 
50
 * the rest of the metadata which usually lives immediately behind the anchor.
 
51
 *
 
52
 * Note:
 
53
 *  - all multibyte numeric fields are bigendian.
 
54
 *  - all strings are space padded.
 
55
 *
 
56
 */
 
57
 
 
58
/* Primary Raid Level (PRL) */
 
59
#define DDF_RAID0       0x00
 
60
#define DDF_RAID1       0x01
 
61
#define DDF_RAID3       0x03
 
62
#define DDF_RAID4       0x04
 
63
#define DDF_RAID5       0x05
 
64
#define DDF_RAID1E      0x11
 
65
#define DDF_JBOD        0x0f
 
66
#define DDF_CONCAT      0x1f
 
67
#define DDF_RAID5E      0x15
 
68
#define DDF_RAID5EE     0x25
 
69
#define DDF_RAID6       0x06
 
70
 
 
71
/* Raid Level Qualifier (RLQ) */
 
72
#define DDF_RAID0_SIMPLE        0x00
 
73
#define DDF_RAID1_SIMPLE        0x00 /* just 2 devices in this plex */
 
74
#define DDF_RAID1_MULTI         0x01 /* exactly 3 devices in this plex */
 
75
#define DDF_RAID3_0             0x00 /* parity in first extent */
 
76
#define DDF_RAID3_N             0x01 /* parity in last extent */
 
77
#define DDF_RAID4_0             0x00 /* parity in first extent */
 
78
#define DDF_RAID4_N             0x01 /* parity in last extent */
 
79
/* these apply to raid5e and raid5ee as well */
 
80
#define DDF_RAID5_0_RESTART     0x00 /* same as 'right asymmetric' - layout 1 */
 
81
#define DDF_RAID6_0_RESTART     0x01 /* raid6 different from raid5 here!!! */
 
82
#define DDF_RAID5_N_RESTART     0x02 /* same as 'left asymmetric' - layout 0 */
 
83
#define DDF_RAID5_N_CONTINUE    0x03 /* same as 'left symmetric' - layout 2 */
 
84
 
 
85
#define DDF_RAID1E_ADJACENT     0x00 /* raid10 nearcopies==2 */
 
86
#define DDF_RAID1E_OFFSET       0x01 /* raid10 offsetcopies==2 */
 
87
 
 
88
/* Secondary RAID Level (SRL) */
 
89
#define DDF_2STRIPED    0x00    /* This is weirder than RAID0 !! */
 
90
#define DDF_2MIRRORED   0x01
 
91
#define DDF_2CONCAT     0x02
 
92
#define DDF_2SPANNED    0x03    /* This is also weird - be careful */
 
93
 
 
94
/* Magic numbers */
 
95
#define DDF_HEADER_MAGIC        __cpu_to_be32(0xDE11DE11)
 
96
#define DDF_CONTROLLER_MAGIC    __cpu_to_be32(0xAD111111)
 
97
#define DDF_PHYS_RECORDS_MAGIC  __cpu_to_be32(0x22222222)
 
98
#define DDF_PHYS_DATA_MAGIC     __cpu_to_be32(0x33333333)
 
99
#define DDF_VIRT_RECORDS_MAGIC  __cpu_to_be32(0xDDDDDDDD)
 
100
#define DDF_VD_CONF_MAGIC       __cpu_to_be32(0xEEEEEEEE)
 
101
#define DDF_SPARE_ASSIGN_MAGIC  __cpu_to_be32(0x55555555)
 
102
#define DDF_VU_CONF_MAGIC       __cpu_to_be32(0x88888888)
 
103
#define DDF_VENDOR_LOG_MAGIC    __cpu_to_be32(0x01dBEEF0)
 
104
#define DDF_BBM_LOG_MAGIC       __cpu_to_be32(0xABADB10C)
 
105
 
 
106
#define DDF_GUID_LEN    24
 
107
#define DDF_REVISION_0  "01.00.00"
 
108
#define DDF_REVISION_2  "01.02.00"
 
109
 
 
110
struct ddf_header {
 
111
        __u32   magic;          /* DDF_HEADER_MAGIC */
 
112
        __u32   crc;
 
113
        char    guid[DDF_GUID_LEN];
 
114
        char    revision[8];    /* 01.02.00 */
 
115
        __u32   seq;            /* starts at '1' */
 
116
        __u32   timestamp;
 
117
        __u8    openflag;
 
118
        __u8    foreignflag;
 
119
        __u8    enforcegroups;
 
120
        __u8    pad0;           /* 0xff */
 
121
        __u8    pad1[12];       /* 12 * 0xff */
 
122
        /* 64 bytes so far */
 
123
        __u8    header_ext[32]; /* reserved: fill with 0xff */
 
124
        __u64   primary_lba;
 
125
        __u64   secondary_lba;
 
126
        __u8    type;
 
127
        __u8    pad2[3];        /* 0xff */
 
128
        __u32   workspace_len;  /* sectors for vendor space -
 
129
                                 * at least 32768(sectors) */
 
130
        __u64   workspace_lba;
 
131
        __u16   max_pd_entries; /* one of 15, 63, 255, 1023, 4095 */
 
132
        __u16   max_vd_entries; /* 2^(4,6,8,10,12)-1 : i.e. as above */
 
133
        __u16   max_partitions; /* i.e. max num of configuration
 
134
                                   record entries per disk */
 
135
        __u16   config_record_len; /* 1 +ROUNDUP(max_primary_element_entries
 
136
                                                 *12/512) */
 
137
        __u16   max_primary_element_entries; /* 16, 64, 256, 1024, or 4096 */
 
138
        __u8    pad3[54];       /* 0xff */
 
139
        /* 192 bytes so far */
 
140
        __u32   controller_section_offset;
 
141
        __u32   controller_section_length;
 
142
        __u32   phys_section_offset;
 
143
        __u32   phys_section_length;
 
144
        __u32   virt_section_offset;
 
145
        __u32   virt_section_length;
 
146
        __u32   config_section_offset;
 
147
        __u32   config_section_length;
 
148
        __u32   data_section_offset;
 
149
        __u32   data_section_length;
 
150
        __u32   bbm_section_offset;
 
151
        __u32   bbm_section_length;
 
152
        __u32   diag_space_offset;
 
153
        __u32   diag_space_length;
 
154
        __u32   vendor_offset;
 
155
        __u32   vendor_length;
 
156
        /* 256 bytes so far */
 
157
        __u8    pad4[256];      /* 0xff */
 
158
};
 
159
 
 
160
/* type field */
 
161
#define DDF_HEADER_ANCHOR       0x00
 
162
#define DDF_HEADER_PRIMARY      0x01
 
163
#define DDF_HEADER_SECONDARY    0x02
 
164
 
 
165
/* The content of the 'controller section' - global scope */
 
166
struct ddf_controller_data {
 
167
        __u32   magic;                  /* DDF_CONTROLLER_MAGIC */
 
168
        __u32   crc;
 
169
        char    guid[DDF_GUID_LEN];
 
170
        struct controller_type {
 
171
                __u16 vendor_id;
 
172
                __u16 device_id;
 
173
                __u16 sub_vendor_id;
 
174
                __u16 sub_device_id;
 
175
        } type;
 
176
        char    product_id[16];
 
177
        __u8    pad[8]; /* 0xff */
 
178
        __u8    vendor_data[448];
 
179
};
 
180
 
 
181
/* The content of phys_section - global scope */
 
182
struct phys_disk {
 
183
        __u32   magic;          /* DDF_PHYS_RECORDS_MAGIC */
 
184
        __u32   crc;
 
185
        __u16   used_pdes;
 
186
        __u16   max_pdes;
 
187
        __u8    pad[52];
 
188
        struct phys_disk_entry {
 
189
                char    guid[DDF_GUID_LEN];
 
190
                __u32   refnum;
 
191
                __u16   type;
 
192
                __u16   state;
 
193
                __u64   config_size; /* DDF structures must be after here */
 
194
                char    path[18];       /* another horrible structure really */
 
195
                __u8    pad[6];
 
196
        } entries[0];
 
197
};
 
198
 
 
199
/* phys_disk_entry.type is a bitmap - bigendian remember */
 
200
#define DDF_Forced_PD_GUID              1
 
201
#define DDF_Active_in_VD                2
 
202
#define DDF_Global_Spare                4 /* VD_CONF records are ignored */
 
203
#define DDF_Spare                       8 /* overrides Global_spare */
 
204
#define DDF_Foreign                     16
 
205
#define DDF_Legacy                      32 /* no DDF on this device */
 
206
 
 
207
#define DDF_Interface_mask              0xf00
 
208
#define DDF_Interface_SCSI              0x100
 
209
#define DDF_Interface_SAS               0x200
 
210
#define DDF_Interface_SATA              0x300
 
211
#define DDF_Interface_FC                0x400
 
212
 
 
213
/* phys_disk_entry.state is a bigendian bitmap */
 
214
#define DDF_Online                      1
 
215
#define DDF_Failed                      2 /* overrides  1,4,8 */
 
216
#define DDF_Rebuilding                  4
 
217
#define DDF_Transition                  8
 
218
#define DDF_SMART                       16
 
219
#define DDF_ReadErrors                  32
 
220
#define DDF_Missing                     64
 
221
 
 
222
/* The content of the virt_section global scope */
 
223
struct virtual_disk {
 
224
        __u32   magic;          /* DDF_VIRT_RECORDS_MAGIC */
 
225
        __u32   crc;
 
226
        __u16   populated_vdes;
 
227
        __u16   max_vdes;
 
228
        __u8    pad[52];
 
229
        struct virtual_entry {
 
230
                char    guid[DDF_GUID_LEN];
 
231
                __u16   unit;
 
232
                __u16   pad0;   /* 0xffff */
 
233
                __u16   guid_crc;
 
234
                __u16   type;
 
235
                __u8    state;
 
236
                __u8    init_state;
 
237
                __u8    pad1[14];
 
238
                char    name[16];
 
239
        } entries[0];
 
240
};
 
241
 
 
242
/* virtual_entry.type is a bitmap - bigendian */
 
243
#define DDF_Shared              1
 
244
#define DDF_Enforce_Groups      2
 
245
#define DDF_Unicode             4
 
246
#define DDF_Owner_Valid         8
 
247
 
 
248
/* virtual_entry.state is a bigendian bitmap */
 
249
#define DDF_state_mask          0x7
 
250
#define DDF_state_optimal       0x0
 
251
#define DDF_state_degraded      0x1
 
252
#define DDF_state_deleted       0x2
 
253
#define DDF_state_missing       0x3
 
254
#define DDF_state_failed        0x4
 
255
#define DDF_state_part_optimal  0x5
 
256
 
 
257
#define DDF_state_morphing      0x8
 
258
#define DDF_state_inconsistent  0x10
 
259
 
 
260
/* virtual_entry.init_state is a bigendian bitmap */
 
261
#define DDF_initstate_mask      0x03
 
262
#define DDF_init_not            0x00
 
263
#define DDF_init_quick          0x01 /* initialisation is progress.
 
264
                                      * i.e. 'state_inconsistent' */
 
265
#define DDF_init_full           0x02
 
266
 
 
267
#define DDF_access_mask         0xc0
 
268
#define DDF_access_rw           0x00
 
269
#define DDF_access_ro           0x80
 
270
#define DDF_access_blocked      0xc0
 
271
 
 
272
/* The content of the config_section - local scope
 
273
 * It has multiple records each config_record_len sectors
 
274
 * They can be vd_config or spare_assign
 
275
 */
 
276
 
 
277
struct vd_config {
 
278
        __u32   magic;          /* DDF_VD_CONF_MAGIC */
 
279
        __u32   crc;
 
280
        char    guid[DDF_GUID_LEN];
 
281
        __u32   timestamp;
 
282
        __u32   seqnum;
 
283
        __u8    pad0[24];
 
284
        __u16   prim_elmnt_count;
 
285
        __u8    chunk_shift;    /* 0 == 512, 1==1024 etc */
 
286
        __u8    prl;
 
287
        __u8    rlq;
 
288
        __u8    sec_elmnt_count;
 
289
        __u8    sec_elmnt_seq;
 
290
        __u8    srl;
 
291
        __u64   blocks;         /* blocks per component could be different
 
292
                                 * on different component devices...(only
 
293
                                 * for concat I hope) */
 
294
        __u64   array_blocks;   /* blocks in array */
 
295
        __u8    pad1[8];
 
296
        __u32   spare_refs[8];
 
297
        __u8    cache_pol[8];
 
298
        __u8    bg_rate;
 
299
        __u8    pad2[3];
 
300
        __u8    pad3[52];
 
301
        __u8    pad4[192];
 
302
        __u8    v0[32]; /* reserved- 0xff */
 
303
        __u8    v1[32]; /* reserved- 0xff */
 
304
        __u8    v2[16]; /* reserved- 0xff */
 
305
        __u8    v3[16]; /* reserved- 0xff */
 
306
        __u8    vendor[32];
 
307
        __u32   phys_refnum[0]; /* refnum of each disk in sequence */
 
308
      /*__u64   lba_offset[0];  LBA offset in each phys.  Note extents in a
 
309
                                bvd are always the same size */
 
310
};
 
311
 
 
312
/* vd_config.cache_pol[7] is a bitmap */
 
313
#define DDF_cache_writeback     1       /* else writethrough */
 
314
#define DDF_cache_wadaptive     2       /* only applies if writeback */
 
315
#define DDF_cache_readahead     4
 
316
#define DDF_cache_radaptive     8       /* only if doing read-ahead */
 
317
#define DDF_cache_ifnobatt      16      /* even to write cache if battery is poor */
 
318
#define DDF_cache_wallowed      32      /* enable write caching */
 
319
#define DDF_cache_rallowed      64      /* enable read caching */
 
320
 
 
321
struct spare_assign {
 
322
        __u32   magic;          /* DDF_SPARE_ASSIGN_MAGIC */
 
323
        __u32   crc;
 
324
        __u32   timestamp;
 
325
        __u8    reserved[7];
 
326
        __u8    type;
 
327
        __u16   populated;      /* SAEs used */
 
328
        __u16   max;            /* max SAEs */
 
329
        __u8    pad[8];
 
330
        struct spare_assign_entry {
 
331
                char    guid[DDF_GUID_LEN];
 
332
                __u16   secondary_element;
 
333
                __u8    pad[6];
 
334
        } spare_ents[0];
 
335
};
 
336
/* spare_assign.type is a bitmap */
 
337
#define DDF_spare_dedicated     0x1     /* else global */
 
338
#define DDF_spare_revertible    0x2     /* else committable */
 
339
#define DDF_spare_active        0x4     /* else not active */
 
340
#define DDF_spare_affinity      0x8     /* enclosure affinity */
 
341
 
 
342
/* The data_section contents - local scope */
 
343
struct disk_data {
 
344
        __u32   magic;          /* DDF_PHYS_DATA_MAGIC */
 
345
        __u32   crc;
 
346
        char    guid[DDF_GUID_LEN];
 
347
        __u32   refnum;         /* crc of some magic drive data ... */
 
348
        __u8    forced_ref;     /* set when above was not result of magic */
 
349
        __u8    forced_guid;    /* set if guid was forced rather than magic */
 
350
        __u8    vendor[32];
 
351
        __u8    pad[442];
 
352
};
 
353
 
 
354
/* bbm_section content */
 
355
struct bad_block_log {
 
356
        __u32   magic;
 
357
        __u32   crc;
 
358
        __u16   entry_count;
 
359
        __u32   spare_count;
 
360
        __u8    pad[10];
 
361
        __u64   first_spare;
 
362
        struct mapped_block {
 
363
                __u64   defective_start;
 
364
                __u32   replacement_start;
 
365
                __u16   remap_count;
 
366
                __u8    pad[2];
 
367
        } entries[0];
 
368
};
 
369
 
 
370
/* Struct for internally holding ddf structures */
 
371
/* The DDF structure stored on each device is potentially
 
372
 * quite different, as some data is global and some is local.
 
373
 * The global data is:
 
374
 *   - ddf header
 
375
 *   - controller_data
 
376
 *   - Physical disk records
 
377
 *   - Virtual disk records
 
378
 * The local data is:
 
379
 *   - Configuration records
 
380
 *   - Physical Disk data section
 
381
 *  (  and Bad block and vendor which I don't care about yet).
 
382
 *
 
383
 * The local data is parsed into separate lists as it is read
 
384
 * and reconstructed for writing.  This means that we only need
 
385
 * to make config changes once and they are automatically
 
386
 * propagated to all devices.
 
387
 * Note that the ddf_super has space of the conf and disk data
 
388
 * for this disk and also for a list of all such data.
 
389
 * The list is only used for the superblock that is being
 
390
 * built in Create or Assemble to describe the whole array.
 
391
 */
 
392
struct ddf_super {
 
393
        struct ddf_header anchor, primary, secondary;
 
394
        struct ddf_controller_data controller;
 
395
        struct ddf_header *active;
 
396
        struct phys_disk        *phys;
 
397
        struct virtual_disk     *virt;
 
398
        int pdsize, vdsize;
 
399
        unsigned int max_part, mppe, conf_rec_len;
 
400
        int currentdev;
 
401
        int updates_pending;
 
402
        struct vcl {
 
403
                union {
 
404
                        char space[512];
 
405
                        struct {
 
406
                                struct vcl      *next;
 
407
                                __u64           *lba_offset; /* location in 'conf' of
 
408
                                                              * the lba table */
 
409
                                unsigned int    vcnum; /* index into ->virt */
 
410
                                __u64           *block_sizes; /* NULL if all the same */
 
411
                        };
 
412
                };
 
413
                struct vd_config conf;
 
414
        } *conflist, *currentconf;
 
415
        struct dl {
 
416
                union {
 
417
                        char space[512];
 
418
                        struct {
 
419
                                struct dl       *next;
 
420
                                int major, minor;
 
421
                                char *devname;
 
422
                                int fd;
 
423
                                unsigned long long size; /* sectors */
 
424
                                int pdnum;      /* index in ->phys */
 
425
                                struct spare_assign *spare;
 
426
                                void *mdupdate; /* hold metadata update */
 
427
 
 
428
                                /* These fields used by auto-layout */
 
429
                                int raiddisk; /* slot to fill in autolayout */
 
430
                                __u64 esize;
 
431
                        };
 
432
                };
 
433
                struct disk_data disk;
 
434
                struct vcl *vlist[0]; /* max_part in size */
 
435
        } *dlist, *add_list;
 
436
};
 
437
 
 
438
#ifndef offsetof
 
439
#define offsetof(t,f) ((size_t)&(((t*)0)->f))
 
440
#endif
 
441
 
 
442
 
 
443
static unsigned int calc_crc(void *buf, int len)
 
444
{
 
445
        /* crcs are always at the same place as in the ddf_header */
 
446
        struct ddf_header *ddf = buf;
 
447
        __u32 oldcrc = ddf->crc;
 
448
        __u32 newcrc;
 
449
        ddf->crc = 0xffffffff;
 
450
 
 
451
        newcrc = crc32(0, buf, len);
 
452
        ddf->crc = oldcrc;
 
453
        /* The crc is store (like everything) bigendian, so convert
 
454
         * here for simplicity
 
455
         */
 
456
        return __cpu_to_be32(newcrc);
 
457
}
 
458
 
 
459
static int load_ddf_header(int fd, unsigned long long lba,
 
460
                           unsigned long long size,
 
461
                           int type,
 
462
                           struct ddf_header *hdr, struct ddf_header *anchor)
 
463
{
 
464
        /* read a ddf header (primary or secondary) from fd/lba
 
465
         * and check that it is consistent with anchor
 
466
         * Need to check:
 
467
         *   magic, crc, guid, rev, and LBA's header_type, and
 
468
         *  everything after header_type must be the same
 
469
         */
 
470
        if (lba >= size-1)
 
471
                return 0;
 
472
 
 
473
        if (lseek64(fd, lba<<9, 0) < 0)
 
474
                return 0;
 
475
 
 
476
        if (read(fd, hdr, 512) != 512)
 
477
                return 0;
 
478
 
 
479
        if (hdr->magic != DDF_HEADER_MAGIC)
 
480
                return 0;
 
481
        if (calc_crc(hdr, 512) != hdr->crc)
 
482
                return 0;
 
483
        if (memcmp(anchor->guid, hdr->guid, DDF_GUID_LEN) != 0 ||
 
484
            memcmp(anchor->revision, hdr->revision, 8) != 0 ||
 
485
            anchor->primary_lba != hdr->primary_lba ||
 
486
            anchor->secondary_lba != hdr->secondary_lba ||
 
487
            hdr->type != type ||
 
488
            memcmp(anchor->pad2, hdr->pad2, 512 -
 
489
                   offsetof(struct ddf_header, pad2)) != 0)
 
490
                return 0;
 
491
 
 
492
        /* Looks good enough to me... */
 
493
        return 1;
 
494
}
 
495
 
 
496
static void *load_section(int fd, struct ddf_super *super, void *buf,
 
497
                          __u32 offset_be, __u32 len_be, int check)
 
498
{
 
499
        unsigned long long offset = __be32_to_cpu(offset_be);
 
500
        unsigned long long len = __be32_to_cpu(len_be);
 
501
        int dofree = (buf == NULL);
 
502
 
 
503
        if (check)
 
504
                if (len != 2 && len != 8 && len != 32
 
505
                    && len != 128 && len != 512)
 
506
                        return NULL;
 
507
 
 
508
        if (len > 1024)
 
509
                return NULL;
 
510
        if (buf) {
 
511
                /* All pre-allocated sections are a single block */
 
512
                if (len != 1)
 
513
                        return NULL;
 
514
        } else if (posix_memalign(&buf, 512, len<<9) != 0)
 
515
                buf = NULL;
 
516
 
 
517
        if (!buf)
 
518
                return NULL;
 
519
 
 
520
        if (super->active->type == 1)
 
521
                offset += __be64_to_cpu(super->active->primary_lba);
 
522
        else
 
523
                offset += __be64_to_cpu(super->active->secondary_lba);
 
524
 
 
525
        if ((unsigned long long)lseek64(fd, offset<<9, 0) != (offset<<9)) {
 
526
                if (dofree)
 
527
                        free(buf);
 
528
                return NULL;
 
529
        }
 
530
        if ((unsigned long long)read(fd, buf, len<<9) != (len<<9)) {
 
531
                if (dofree)
 
532
                        free(buf);
 
533
                return NULL;
 
534
        }
 
535
        return buf;
 
536
}
 
537
 
 
538
static int load_ddf_headers(int fd, struct ddf_super *super, char *devname)
 
539
{
 
540
        unsigned long long dsize;
 
541
 
 
542
        get_dev_size(fd, NULL, &dsize);
 
543
 
 
544
        if (lseek64(fd, dsize-512, 0) < 0) {
 
545
                if (devname)
 
546
                        fprintf(stderr,
 
547
                                Name": Cannot seek to anchor block on %s: %s\n",
 
548
                                devname, strerror(errno));
 
549
                return 1;
 
550
        }
 
551
        if (read(fd, &super->anchor, 512) != 512) {
 
552
                if (devname)
 
553
                        fprintf(stderr,
 
554
                                Name ": Cannot read anchor block on %s: %s\n",
 
555
                                devname, strerror(errno));
 
556
                return 1;
 
557
        }
 
558
        if (super->anchor.magic != DDF_HEADER_MAGIC) {
 
559
                if (devname)
 
560
                        fprintf(stderr, Name ": no DDF anchor found on %s\n",
 
561
                                devname);
 
562
                return 2;
 
563
        }
 
564
        if (calc_crc(&super->anchor, 512) != super->anchor.crc) {
 
565
                if (devname)
 
566
                        fprintf(stderr, Name ": bad CRC on anchor on %s\n",
 
567
                                devname);
 
568
                return 2;
 
569
        }
 
570
        if (memcmp(super->anchor.revision, DDF_REVISION_0, 8) != 0 &&
 
571
            memcmp(super->anchor.revision, DDF_REVISION_2, 8) != 0) {
 
572
                if (devname)
 
573
                        fprintf(stderr, Name ": can only support super revision"
 
574
                                " %.8s and earlier, not %.8s on %s\n",
 
575
                                DDF_REVISION_2, super->anchor.revision,devname);
 
576
                return 2;
 
577
        }
 
578
        if (load_ddf_header(fd, __be64_to_cpu(super->anchor.primary_lba),
 
579
                            dsize >> 9,  1,
 
580
                            &super->primary, &super->anchor) == 0) {
 
581
                if (devname)
 
582
                        fprintf(stderr,
 
583
                                Name ": Failed to load primary DDF header "
 
584
                                "on %s\n", devname);
 
585
                return 2;
 
586
        }
 
587
        super->active = &super->primary;
 
588
        if (load_ddf_header(fd, __be64_to_cpu(super->anchor.secondary_lba),
 
589
                            dsize >> 9,  2,
 
590
                            &super->secondary, &super->anchor)) {
 
591
                if ((__be32_to_cpu(super->primary.seq)
 
592
                     < __be32_to_cpu(super->secondary.seq) &&
 
593
                     !super->secondary.openflag)
 
594
                    || (__be32_to_cpu(super->primary.seq)
 
595
                        == __be32_to_cpu(super->secondary.seq) &&
 
596
                        super->primary.openflag && !super->secondary.openflag)
 
597
                        )
 
598
                        super->active = &super->secondary;
 
599
        }
 
600
        return 0;
 
601
}
 
602
 
 
603
static int load_ddf_global(int fd, struct ddf_super *super, char *devname)
 
604
{
 
605
        void *ok;
 
606
        ok = load_section(fd, super, &super->controller,
 
607
                          super->active->controller_section_offset,
 
608
                          super->active->controller_section_length,
 
609
                          0);
 
610
        super->phys = load_section(fd, super, NULL,
 
611
                                   super->active->phys_section_offset,
 
612
                                   super->active->phys_section_length,
 
613
                                   1);
 
614
        super->pdsize = __be32_to_cpu(super->active->phys_section_length) * 512;
 
615
 
 
616
        super->virt = load_section(fd, super, NULL,
 
617
                                   super->active->virt_section_offset,
 
618
                                   super->active->virt_section_length,
 
619
                                   1);
 
620
        super->vdsize = __be32_to_cpu(super->active->virt_section_length) * 512;
 
621
        if (!ok ||
 
622
            !super->phys ||
 
623
            !super->virt) {
 
624
                free(super->phys);
 
625
                free(super->virt);
 
626
                super->phys = NULL;
 
627
                super->virt = NULL;
 
628
                return 2;
 
629
        }
 
630
        super->conflist = NULL;
 
631
        super->dlist = NULL;
 
632
 
 
633
        super->max_part = __be16_to_cpu(super->active->max_partitions);
 
634
        super->mppe = __be16_to_cpu(super->active->max_primary_element_entries);
 
635
        super->conf_rec_len = __be16_to_cpu(super->active->config_record_len);
 
636
        return 0;
 
637
}
 
638
 
 
639
static int load_ddf_local(int fd, struct ddf_super *super,
 
640
                          char *devname, int keep)
 
641
{
 
642
        struct dl *dl;
 
643
        struct stat stb;
 
644
        char *conf;
 
645
        unsigned int i;
 
646
        unsigned int confsec;
 
647
        int vnum;
 
648
        unsigned int max_virt_disks = __be16_to_cpu(super->active->max_vd_entries);
 
649
        unsigned long long dsize;
 
650
 
 
651
        /* First the local disk info */
 
652
        if (posix_memalign((void**)&dl, 512,
 
653
                       sizeof(*dl) +
 
654
                       (super->max_part) * sizeof(dl->vlist[0])) != 0) {
 
655
                fprintf(stderr, Name ": %s could not allocate disk info buffer\n",
 
656
                        __func__);
 
657
                return 1;
 
658
        }
 
659
 
 
660
        load_section(fd, super, &dl->disk,
 
661
                     super->active->data_section_offset,
 
662
                     super->active->data_section_length,
 
663
                     0);
 
664
        dl->devname = devname ? strdup(devname) : NULL;
 
665
 
 
666
        fstat(fd, &stb);
 
667
        dl->major = major(stb.st_rdev);
 
668
        dl->minor = minor(stb.st_rdev);
 
669
        dl->next = super->dlist;
 
670
        dl->fd = keep ? fd : -1;
 
671
 
 
672
        dl->size = 0;
 
673
        if (get_dev_size(fd, devname, &dsize))
 
674
                dl->size = dsize >> 9;
 
675
        dl->spare = NULL;
 
676
        for (i = 0 ; i < super->max_part ; i++)
 
677
                dl->vlist[i] = NULL;
 
678
        super->dlist = dl;
 
679
        dl->pdnum = -1;
 
680
        for (i = 0; i < __be16_to_cpu(super->active->max_pd_entries); i++)
 
681
                if (memcmp(super->phys->entries[i].guid,
 
682
                           dl->disk.guid, DDF_GUID_LEN) == 0)
 
683
                        dl->pdnum = i;
 
684
 
 
685
        /* Now the config list. */
 
686
        /* 'conf' is an array of config entries, some of which are
 
687
         * probably invalid.  Those which are good need to be copied into
 
688
         * the conflist
 
689
         */
 
690
 
 
691
        conf = load_section(fd, super, NULL,
 
692
                            super->active->config_section_offset,
 
693
                            super->active->config_section_length,
 
694
                            0);
 
695
 
 
696
        vnum = 0;
 
697
        for (confsec = 0;
 
698
             confsec < __be32_to_cpu(super->active->config_section_length);
 
699
             confsec += super->conf_rec_len) {
 
700
                struct vd_config *vd =
 
701
                        (struct vd_config *)((char*)conf + confsec*512);
 
702
                struct vcl *vcl;
 
703
 
 
704
                if (vd->magic == DDF_SPARE_ASSIGN_MAGIC) {
 
705
                        if (dl->spare)
 
706
                                continue;
 
707
                        if (posix_memalign((void**)&dl->spare, 512,
 
708
                                       super->conf_rec_len*512) != 0) {
 
709
                                fprintf(stderr, Name
 
710
                                        ": %s could not allocate spare info buf\n",
 
711
                                        __func__);
 
712
                                return 1;
 
713
                        }
 
714
                                
 
715
                        memcpy(dl->spare, vd, super->conf_rec_len*512);
 
716
                        continue;
 
717
                }
 
718
                if (vd->magic != DDF_VD_CONF_MAGIC)
 
719
                        continue;
 
720
                for (vcl = super->conflist; vcl; vcl = vcl->next) {
 
721
                        if (memcmp(vcl->conf.guid,
 
722
                                   vd->guid, DDF_GUID_LEN) == 0)
 
723
                                break;
 
724
                }
 
725
 
 
726
                if (vcl) {
 
727
                        dl->vlist[vnum++] = vcl;
 
728
                        if (__be32_to_cpu(vd->seqnum) <=
 
729
                            __be32_to_cpu(vcl->conf.seqnum))
 
730
                                continue;
 
731
                } else {
 
732
                        if (posix_memalign((void**)&vcl, 512,
 
733
                                       (super->conf_rec_len*512 +
 
734
                                        offsetof(struct vcl, conf))) != 0) {
 
735
                                fprintf(stderr, Name
 
736
                                        ": %s could not allocate vcl buf\n",
 
737
                                        __func__);
 
738
                                return 1;
 
739
                        }
 
740
                        vcl->next = super->conflist;
 
741
                        vcl->block_sizes = NULL; /* FIXME not for CONCAT */
 
742
                        super->conflist = vcl;
 
743
                        dl->vlist[vnum++] = vcl;
 
744
                }
 
745
                memcpy(&vcl->conf, vd, super->conf_rec_len*512);
 
746
                vcl->lba_offset = (__u64*)
 
747
                        &vcl->conf.phys_refnum[super->mppe];
 
748
 
 
749
                for (i=0; i < max_virt_disks ; i++)
 
750
                        if (memcmp(super->virt->entries[i].guid,
 
751
                                   vcl->conf.guid, DDF_GUID_LEN)==0)
 
752
                                break;
 
753
                if (i < max_virt_disks)
 
754
                        vcl->vcnum = i;
 
755
        }
 
756
        free(conf);
 
757
 
 
758
        return 0;
 
759
}
 
760
 
 
761
#ifndef MDASSEMBLE
 
762
static int load_super_ddf_all(struct supertype *st, int fd,
 
763
                              void **sbp, char *devname, int keep_fd);
 
764
#endif
 
765
 
 
766
static void free_super_ddf(struct supertype *st);
 
767
 
 
768
static int load_super_ddf(struct supertype *st, int fd,
 
769
                          char *devname)
 
770
{
 
771
        unsigned long long dsize;
 
772
        struct ddf_super *super;
 
773
        int rv;
 
774
 
 
775
#ifndef MDASSEMBLE
 
776
        /* if 'fd' is a container, load metadata from all the devices */
 
777
        if (load_super_ddf_all(st, fd, &st->sb, devname, 1) == 0)
 
778
                return 0;
 
779
#endif
 
780
        if (st->subarray[0])
 
781
                return 1; /* FIXME Is this correct */
 
782
 
 
783
        if (get_dev_size(fd, devname, &dsize) == 0)
 
784
                return 1;
 
785
 
 
786
        if (test_partition(fd))
 
787
                /* DDF is not allowed on partitions */
 
788
                return 1;
 
789
 
 
790
        /* 32M is a lower bound */
 
791
        if (dsize <= 32*1024*1024) {
 
792
                if (devname)
 
793
                        fprintf(stderr,
 
794
                                Name ": %s is too small for ddf: "
 
795
                                "size is %llu sectors.\n",
 
796
                                devname, dsize>>9);
 
797
                return 1;
 
798
        }
 
799
        if (dsize & 511) {
 
800
                if (devname)
 
801
                        fprintf(stderr,
 
802
                                Name ": %s is an odd size for ddf: "
 
803
                                "size is %llu bytes.\n",
 
804
                                devname, dsize);
 
805
                return 1;
 
806
        }
 
807
 
 
808
        free_super_ddf(st);
 
809
 
 
810
        if (posix_memalign((void**)&super, 512, sizeof(*super))!= 0) {
 
811
                fprintf(stderr, Name ": malloc of %zu failed.\n",
 
812
                        sizeof(*super));
 
813
                return 1;
 
814
        }
 
815
        memset(super, 0, sizeof(*super));
 
816
 
 
817
        rv = load_ddf_headers(fd, super, devname);
 
818
        if (rv) {
 
819
                free(super);
 
820
                return rv;
 
821
        }
 
822
 
 
823
        /* Have valid headers and have chosen the best. Let's read in the rest*/
 
824
 
 
825
        rv = load_ddf_global(fd, super, devname);
 
826
 
 
827
        if (rv) {
 
828
                if (devname)
 
829
                        fprintf(stderr,
 
830
                                Name ": Failed to load all information "
 
831
                                "sections on %s\n", devname);
 
832
                free(super);
 
833
                return rv;
 
834
        }
 
835
 
 
836
        rv = load_ddf_local(fd, super, devname, 0);
 
837
 
 
838
        if (rv) {
 
839
                if (devname)
 
840
                        fprintf(stderr,
 
841
                                Name ": Failed to load all information "
 
842
                                "sections on %s\n", devname);
 
843
                free(super);
 
844
                return rv;
 
845
        }
 
846
 
 
847
        if (st->subarray[0]) {
 
848
                unsigned long val;
 
849
                struct vcl *v;
 
850
                char *ep;
 
851
 
 
852
                val = strtoul(st->subarray, &ep, 10);
 
853
                if (*ep != '\0') {
 
854
                        free(super);
 
855
                        return 1;
 
856
                }
 
857
 
 
858
                for (v = super->conflist; v; v = v->next)
 
859
                        if (v->vcnum == val)
 
860
                                super->currentconf = v;
 
861
                if (!super->currentconf) {
 
862
                        free(super);
 
863
                        return 1;
 
864
                }
 
865
        }
 
866
 
 
867
        /* Should possibly check the sections .... */
 
868
 
 
869
        st->sb = super;
 
870
        if (st->ss == NULL) {
 
871
                st->ss = &super_ddf;
 
872
                st->minor_version = 0;
 
873
                st->max_devs = 512;
 
874
        }
 
875
        st->loaded_container = 0;
 
876
        return 0;
 
877
 
 
878
}
 
879
 
 
880
static void free_super_ddf(struct supertype *st)
 
881
{
 
882
        struct ddf_super *ddf = st->sb;
 
883
        if (ddf == NULL)
 
884
                return;
 
885
        free(ddf->phys);
 
886
        free(ddf->virt);
 
887
        while (ddf->conflist) {
 
888
                struct vcl *v = ddf->conflist;
 
889
                ddf->conflist = v->next;
 
890
                if (v->block_sizes)
 
891
                        free(v->block_sizes);
 
892
                free(v);
 
893
        }
 
894
        while (ddf->dlist) {
 
895
                struct dl *d = ddf->dlist;
 
896
                ddf->dlist = d->next;
 
897
                if (d->fd >= 0)
 
898
                        close(d->fd);
 
899
                if (d->spare)
 
900
                        free(d->spare);
 
901
                free(d);
 
902
        }
 
903
        free(ddf);
 
904
        st->sb = NULL;
 
905
}
 
906
 
 
907
static struct supertype *match_metadata_desc_ddf(char *arg)
 
908
{
 
909
        /* 'ddf' only support containers */
 
910
        struct supertype *st;
 
911
        if (strcmp(arg, "ddf") != 0 &&
 
912
            strcmp(arg, "default") != 0
 
913
                )
 
914
                return NULL;
 
915
 
 
916
        st = malloc(sizeof(*st));
 
917
        memset(st, 0, sizeof(*st));
 
918
        st->ss = &super_ddf;
 
919
        st->max_devs = 512;
 
920
        st->minor_version = 0;
 
921
        st->sb = NULL;
 
922
        return st;
 
923
}
 
924
 
 
925
 
 
926
#ifndef MDASSEMBLE
 
927
 
 
928
static mapping_t ddf_state[] = {
 
929
        { "Optimal", 0},
 
930
        { "Degraded", 1},
 
931
        { "Deleted", 2},
 
932
        { "Missing", 3},
 
933
        { "Failed", 4},
 
934
        { "Partially Optimal", 5},
 
935
        { "-reserved-", 6},
 
936
        { "-reserved-", 7},
 
937
        { NULL, 0}
 
938
};
 
939
 
 
940
static mapping_t ddf_init_state[] = {
 
941
        { "Not Initialised", 0},
 
942
        { "QuickInit in Progress", 1},
 
943
        { "Fully Initialised", 2},
 
944
        { "*UNKNOWN*", 3},
 
945
        { NULL, 0}
 
946
};
 
947
static mapping_t ddf_access[] = {
 
948
        { "Read/Write", 0},
 
949
        { "Reserved", 1},
 
950
        { "Read Only", 2},
 
951
        { "Blocked (no access)", 3},
 
952
        { NULL ,0}
 
953
};
 
954
 
 
955
static mapping_t ddf_level[] = {
 
956
        { "RAID0", DDF_RAID0},
 
957
        { "RAID1", DDF_RAID1},
 
958
        { "RAID3", DDF_RAID3},
 
959
        { "RAID4", DDF_RAID4},
 
960
        { "RAID5", DDF_RAID5},
 
961
        { "RAID1E",DDF_RAID1E},
 
962
        { "JBOD",  DDF_JBOD},
 
963
        { "CONCAT",DDF_CONCAT},
 
964
        { "RAID5E",DDF_RAID5E},
 
965
        { "RAID5EE",DDF_RAID5EE},
 
966
        { "RAID6", DDF_RAID6},
 
967
        { NULL, 0}
 
968
};
 
969
static mapping_t ddf_sec_level[] = {
 
970
        { "Striped", DDF_2STRIPED},
 
971
        { "Mirrored", DDF_2MIRRORED},
 
972
        { "Concat", DDF_2CONCAT},
 
973
        { "Spanned", DDF_2SPANNED},
 
974
        { NULL, 0}
 
975
};
 
976
#endif
 
977
 
 
978
struct num_mapping {
 
979
        int num1, num2;
 
980
};
 
981
static struct num_mapping ddf_level_num[] = {
 
982
        { DDF_RAID0, 0 },
 
983
        { DDF_RAID1, 1 },
 
984
        { DDF_RAID3, LEVEL_UNSUPPORTED },
 
985
        { DDF_RAID4, 4 },
 
986
        { DDF_RAID5, 5 },
 
987
        { DDF_RAID1E, LEVEL_UNSUPPORTED },
 
988
        { DDF_JBOD, LEVEL_UNSUPPORTED },
 
989
        { DDF_CONCAT, LEVEL_LINEAR },
 
990
        { DDF_RAID5E, LEVEL_UNSUPPORTED },
 
991
        { DDF_RAID5EE, LEVEL_UNSUPPORTED },
 
992
        { DDF_RAID6, 6},
 
993
        { MAXINT, MAXINT }
 
994
};
 
995
 
 
996
static int map_num1(struct num_mapping *map, int num)
 
997
{
 
998
        int i;
 
999
        for (i=0 ; map[i].num1 != MAXINT; i++)
 
1000
                if (map[i].num1 == num)
 
1001
                        break;
 
1002
        return map[i].num2;
 
1003
}
 
1004
 
 
1005
static int all_ff(char *guid)
 
1006
{
 
1007
        int i;
 
1008
        for (i = 0; i < DDF_GUID_LEN; i++)
 
1009
                if (guid[i] != (char)0xff)
 
1010
                        return 0;
 
1011
        return 1;
 
1012
}
 
1013
 
 
1014
#ifndef MDASSEMBLE
 
1015
static void print_guid(char *guid, int tstamp)
 
1016
{
 
1017
        /* A GUIDs are part (or all) ASCII and part binary.
 
1018
         * They tend to be space padded.
 
1019
         * We print the GUID in HEX, then in parentheses add
 
1020
         * any initial ASCII sequence, and a possible
 
1021
         * time stamp from bytes 16-19
 
1022
         */
 
1023
        int l = DDF_GUID_LEN;
 
1024
        int i;
 
1025
 
 
1026
        for (i=0 ; i<DDF_GUID_LEN ; i++) {
 
1027
                if ((i&3)==0 && i != 0) printf(":");
 
1028
                printf("%02X", guid[i]&255);
 
1029
        }
 
1030
 
 
1031
        printf("\n                  (");
 
1032
        while (l && guid[l-1] == ' ')
 
1033
                l--;
 
1034
        for (i=0 ; i<l ; i++) {
 
1035
                if (guid[i] >= 0x20 && guid[i] < 0x7f)
 
1036
                        fputc(guid[i], stdout);
 
1037
                else
 
1038
                        break;
 
1039
        }
 
1040
        if (tstamp) {
 
1041
                time_t then = __be32_to_cpu(*(__u32*)(guid+16)) + DECADE;
 
1042
                char tbuf[100];
 
1043
                struct tm *tm;
 
1044
                tm = localtime(&then);
 
1045
                strftime(tbuf, 100, " %D %T",tm);
 
1046
                fputs(tbuf, stdout);
 
1047
        }
 
1048
        printf(")");
 
1049
}
 
1050
 
 
1051
static void examine_vd(int n, struct ddf_super *sb, char *guid)
 
1052
{
 
1053
        int crl = sb->conf_rec_len;
 
1054
        struct vcl *vcl;
 
1055
 
 
1056
        for (vcl = sb->conflist ; vcl ; vcl = vcl->next) {
 
1057
                unsigned int i;
 
1058
                struct vd_config *vc = &vcl->conf;
 
1059
 
 
1060
                if (calc_crc(vc, crl*512) != vc->crc)
 
1061
                        continue;
 
1062
                if (memcmp(vc->guid, guid, DDF_GUID_LEN) != 0)
 
1063
                        continue;
 
1064
 
 
1065
                /* Ok, we know about this VD, let's give more details */
 
1066
                printf(" Raid Devices[%d] : %d (", n,
 
1067
                       __be16_to_cpu(vc->prim_elmnt_count));
 
1068
                for (i = 0; i < __be16_to_cpu(vc->prim_elmnt_count); i++) {
 
1069
                        int j;
 
1070
                        int cnt = __be16_to_cpu(sb->phys->used_pdes);
 
1071
                        for (j=0; j<cnt; j++)
 
1072
                                if (vc->phys_refnum[i] == sb->phys->entries[j].refnum)
 
1073
                                        break;
 
1074
                        if (i) printf(" ");
 
1075
                        if (j < cnt)
 
1076
                                printf("%d", j);
 
1077
                        else
 
1078
                                printf("--");
 
1079
                }
 
1080
                printf(")\n");
 
1081
                if (vc->chunk_shift != 255)
 
1082
                printf("   Chunk Size[%d] : %d sectors\n", n,
 
1083
                       1 << vc->chunk_shift);
 
1084
                printf("   Raid Level[%d] : %s\n", n,
 
1085
                       map_num(ddf_level, vc->prl)?:"-unknown-");
 
1086
                if (vc->sec_elmnt_count != 1) {
 
1087
                        printf("  Secondary Position[%d] : %d of %d\n", n,
 
1088
                               vc->sec_elmnt_seq, vc->sec_elmnt_count);
 
1089
                        printf("  Secondary Level[%d] : %s\n", n,
 
1090
                               map_num(ddf_sec_level, vc->srl) ?: "-unknown-");
 
1091
                }
 
1092
                printf("  Device Size[%d] : %llu\n", n,
 
1093
                       (unsigned long long)__be64_to_cpu(vc->blocks)/2);
 
1094
                printf("   Array Size[%d] : %llu\n", n,
 
1095
                       (unsigned long long)__be64_to_cpu(vc->array_blocks)/2);
 
1096
        }
 
1097
}
 
1098
 
 
1099
static void examine_vds(struct ddf_super *sb)
 
1100
{
 
1101
        int cnt = __be16_to_cpu(sb->virt->populated_vdes);
 
1102
        int i;
 
1103
        printf("  Virtual Disks : %d\n", cnt);
 
1104
 
 
1105
        for (i=0; i<cnt; i++) {
 
1106
                struct virtual_entry *ve = &sb->virt->entries[i];
 
1107
                printf("\n");
 
1108
                printf("      VD GUID[%d] : ", i); print_guid(ve->guid, 1);
 
1109
                printf("\n");
 
1110
                printf("         unit[%d] : %d\n", i, __be16_to_cpu(ve->unit));
 
1111
                printf("        state[%d] : %s, %s%s\n", i,
 
1112
                       map_num(ddf_state, ve->state & 7),
 
1113
                       (ve->state & 8) ? "Morphing, ": "",
 
1114
                       (ve->state & 16)? "Not Consistent" : "Consistent");
 
1115
                printf("   init state[%d] : %s\n", i,
 
1116
                       map_num(ddf_init_state, ve->init_state&3));
 
1117
                printf("       access[%d] : %s\n", i,
 
1118
                       map_num(ddf_access, (ve->init_state>>6) & 3));
 
1119
                printf("         Name[%d] : %.16s\n", i, ve->name);
 
1120
                examine_vd(i, sb, ve->guid);
 
1121
        }
 
1122
        if (cnt) printf("\n");
 
1123
}
 
1124
 
 
1125
static void examine_pds(struct ddf_super *sb)
 
1126
{
 
1127
        int cnt = __be16_to_cpu(sb->phys->used_pdes);
 
1128
        int i;
 
1129
        struct dl *dl;
 
1130
        printf(" Physical Disks : %d\n", cnt);
 
1131
        printf("      Number    RefNo      Size       Device      Type/State\n");
 
1132
 
 
1133
        for (i=0 ; i<cnt ; i++) {
 
1134
                struct phys_disk_entry *pd = &sb->phys->entries[i];
 
1135
                int type = __be16_to_cpu(pd->type);
 
1136
                int state = __be16_to_cpu(pd->state);
 
1137
 
 
1138
                //printf("      PD GUID[%d] : ", i); print_guid(pd->guid, 0);
 
1139
                //printf("\n");
 
1140
                printf("       %3d    %08x  ", i,
 
1141
                       __be32_to_cpu(pd->refnum));
 
1142
                printf("%8lluK ", 
 
1143
                       (unsigned long long)__be64_to_cpu(pd->config_size)>>1);
 
1144
                for (dl = sb->dlist; dl ; dl = dl->next) {
 
1145
                        if (dl->disk.refnum == pd->refnum) {
 
1146
                                char *dv = map_dev(dl->major, dl->minor, 0);
 
1147
                                if (dv) {
 
1148
                                        printf("%-15s", dv);
 
1149
                                        break;
 
1150
                                }
 
1151
                        }
 
1152
                }
 
1153
                if (!dl)
 
1154
                        printf("%15s","");
 
1155
                printf(" %s%s%s%s%s",
 
1156
                       (type&2) ? "active":"",
 
1157
                       (type&4) ? "Global-Spare":"",
 
1158
                       (type&8) ? "spare" : "",
 
1159
                       (type&16)? ", foreign" : "",
 
1160
                       (type&32)? "pass-through" : "");
 
1161
                printf("/%s%s%s%s%s%s%s",
 
1162
                       (state&1)? "Online": "Offline",
 
1163
                       (state&2)? ", Failed": "",
 
1164
                       (state&4)? ", Rebuilding": "",
 
1165
                       (state&8)? ", in-transition": "",
 
1166
                       (state&16)? ", SMART-errors": "",
 
1167
                       (state&32)? ", Unrecovered-Read-Errors": "",
 
1168
                       (state&64)? ", Missing" : "");
 
1169
                printf("\n");
 
1170
        }
 
1171
}
 
1172
 
 
1173
static void examine_super_ddf(struct supertype *st, char *homehost)
 
1174
{
 
1175
        struct ddf_super *sb = st->sb;
 
1176
 
 
1177
        printf("          Magic : %08x\n", __be32_to_cpu(sb->anchor.magic));
 
1178
        printf("        Version : %.8s\n", sb->anchor.revision);
 
1179
        printf("Controller GUID : "); print_guid(sb->controller.guid, 0);
 
1180
        printf("\n");
 
1181
        printf(" Container GUID : "); print_guid(sb->anchor.guid, 1);
 
1182
        printf("\n");
 
1183
        printf("            Seq : %08x\n", __be32_to_cpu(sb->active->seq));
 
1184
        printf("  Redundant hdr : %s\n", sb->secondary.magic == DDF_HEADER_MAGIC
 
1185
               ?"yes" : "no");
 
1186
        examine_vds(sb);
 
1187
        examine_pds(sb);
 
1188
}
 
1189
 
 
1190
static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info);
 
1191
 
 
1192
static void uuid_from_super_ddf(struct supertype *st, int uuid[4]);
 
1193
 
 
1194
static void brief_examine_super_ddf(struct supertype *st, int verbose)
 
1195
{
 
1196
        /* We just write a generic DDF ARRAY entry
 
1197
         */
 
1198
        struct mdinfo info;
 
1199
        char nbuf[64];
 
1200
        getinfo_super_ddf(st, &info);
 
1201
        fname_from_uuid(st, &info, nbuf, ':');
 
1202
 
 
1203
        printf("ARRAY metadata=ddf UUID=%s\n", nbuf + 5);
 
1204
}
 
1205
 
 
1206
static void brief_examine_subarrays_ddf(struct supertype *st, int verbose)
 
1207
{
 
1208
        /* We just write a generic DDF ARRAY entry
 
1209
         */
 
1210
        struct ddf_super *ddf = st->sb;
 
1211
        struct mdinfo info;
 
1212
        unsigned int i;
 
1213
        char nbuf[64];
 
1214
        getinfo_super_ddf(st, &info);
 
1215
        fname_from_uuid(st, &info, nbuf, ':');
 
1216
 
 
1217
        for (i = 0; i < __be16_to_cpu(ddf->virt->max_vdes); i++) {
 
1218
                struct virtual_entry *ve = &ddf->virt->entries[i];
 
1219
                struct vcl vcl;
 
1220
                char nbuf1[64];
 
1221
                if (all_ff(ve->guid))
 
1222
                        continue;
 
1223
                memcpy(vcl.conf.guid, ve->guid, DDF_GUID_LEN);
 
1224
                ddf->currentconf =&vcl;
 
1225
                uuid_from_super_ddf(st, info.uuid);
 
1226
                fname_from_uuid(st, &info, nbuf1, ':');
 
1227
                printf("ARRAY container=%s member=%d UUID=%s\n",
 
1228
                       nbuf+5, i, nbuf1+5);
 
1229
        }
 
1230
}
 
1231
 
 
1232
static void export_examine_super_ddf(struct supertype *st)
 
1233
{
 
1234
        struct mdinfo info;
 
1235
        char nbuf[64];
 
1236
        getinfo_super_ddf(st, &info);
 
1237
        fname_from_uuid(st, &info, nbuf, ':');
 
1238
        printf("MD_METADATA=ddf\n");
 
1239
        printf("MD_LEVEL=container\n");
 
1240
        printf("MD_UUID=%s\n", nbuf+5);
 
1241
}
 
1242
        
 
1243
 
 
1244
static void detail_super_ddf(struct supertype *st, char *homehost)
 
1245
{
 
1246
        /* FIXME later
 
1247
         * Could print DDF GUID
 
1248
         * Need to find which array
 
1249
         *  If whole, briefly list all arrays
 
1250
         *  If one, give name
 
1251
         */
 
1252
}
 
1253
 
 
1254
static void brief_detail_super_ddf(struct supertype *st)
 
1255
{
 
1256
        /* FIXME I really need to know which array we are detailing.
 
1257
         * Can that be stored in ddf_super??
 
1258
         */
 
1259
//      struct ddf_super *ddf = st->sb;
 
1260
        struct mdinfo info;
 
1261
        char nbuf[64];
 
1262
        getinfo_super_ddf(st, &info);
 
1263
        fname_from_uuid(st, &info, nbuf,':');
 
1264
        printf(" UUID=%s", nbuf + 5);
 
1265
}
 
1266
#endif
 
1267
 
 
1268
static int match_home_ddf(struct supertype *st, char *homehost)
 
1269
{
 
1270
        /* It matches 'this' host if the controller is a
 
1271
         * Linux-MD controller with vendor_data matching
 
1272
         * the hostname
 
1273
         */
 
1274
        struct ddf_super *ddf = st->sb;
 
1275
        unsigned int len;
 
1276
 
 
1277
        if (!homehost)
 
1278
                return 0;
 
1279
        len = strlen(homehost);
 
1280
 
 
1281
        return (memcmp(ddf->controller.guid, T10, 8) == 0 &&
 
1282
                len < sizeof(ddf->controller.vendor_data) &&
 
1283
                memcmp(ddf->controller.vendor_data, homehost,len) == 0 &&
 
1284
                ddf->controller.vendor_data[len] == 0);
 
1285
}
 
1286
 
 
1287
#ifndef MDASSEMBLE
 
1288
static struct vd_config *find_vdcr(struct ddf_super *ddf, unsigned int inst)
 
1289
{
 
1290
        struct vcl *v;
 
1291
 
 
1292
        for (v = ddf->conflist; v; v = v->next)
 
1293
                if (inst == v->vcnum)
 
1294
                        return &v->conf;
 
1295
        return NULL;
 
1296
}
 
1297
#endif
 
1298
 
 
1299
static int find_phys(struct ddf_super *ddf, __u32 phys_refnum)
 
1300
{
 
1301
        /* Find the entry in phys_disk which has the given refnum
 
1302
         * and return it's index
 
1303
         */
 
1304
        unsigned int i;
 
1305
        for (i = 0; i < __be16_to_cpu(ddf->phys->max_pdes); i++)
 
1306
                if (ddf->phys->entries[i].refnum == phys_refnum)
 
1307
                        return i;
 
1308
        return -1;
 
1309
}
 
1310
 
 
1311
static void uuid_from_super_ddf(struct supertype *st, int uuid[4])
 
1312
{
 
1313
        /* The uuid returned here is used for:
 
1314
         *  uuid to put into bitmap file (Create, Grow)
 
1315
         *  uuid for backup header when saving critical section (Grow)
 
1316
         *  comparing uuids when re-adding a device into an array
 
1317
         *    In these cases the uuid required is that of the data-array,
 
1318
         *    not the device-set.
 
1319
         *  uuid to recognise same set when adding a missing device back
 
1320
         *    to an array.   This is a uuid for the device-set.
 
1321
         *  
 
1322
         * For each of these we can make do with a truncated
 
1323
         * or hashed uuid rather than the original, as long as
 
1324
         * everyone agrees.
 
1325
         * In the case of SVD we assume the BVD is of interest,
 
1326
         * though that might be the case if a bitmap were made for
 
1327
         * a mirrored SVD - worry about that later.
 
1328
         * So we need to find the VD configuration record for the
 
1329
         * relevant BVD and extract the GUID and Secondary_Element_Seq.
 
1330
         * The first 16 bytes of the sha1 of these is used.
 
1331
         */
 
1332
        struct ddf_super *ddf = st->sb;
 
1333
        struct vcl *vcl = ddf->currentconf;
 
1334
        char *guid;
 
1335
        char buf[20];
 
1336
        struct sha1_ctx ctx;
 
1337
 
 
1338
        if (vcl)
 
1339
                guid = vcl->conf.guid;
 
1340
        else
 
1341
                guid = ddf->anchor.guid;
 
1342
 
 
1343
        sha1_init_ctx(&ctx);
 
1344
        sha1_process_bytes(guid, DDF_GUID_LEN, &ctx);
 
1345
        sha1_finish_ctx(&ctx, buf);
 
1346
        memcpy(uuid, buf, 4*4);
 
1347
}
 
1348
 
 
1349
static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info);
 
1350
 
 
1351
static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info)
 
1352
{
 
1353
        struct ddf_super *ddf = st->sb;
 
1354
 
 
1355
        if (ddf->currentconf) {
 
1356
                getinfo_super_ddf_bvd(st, info);
 
1357
                return;
 
1358
        }
 
1359
 
 
1360
        info->array.raid_disks    = __be16_to_cpu(ddf->phys->used_pdes);
 
1361
        info->array.level         = LEVEL_CONTAINER;
 
1362
        info->array.layout        = 0;
 
1363
        info->array.md_minor      = -1;
 
1364
        info->array.ctime         = DECADE + __be32_to_cpu(*(__u32*)
 
1365
                                                         (ddf->anchor.guid+16));
 
1366
        info->array.utime         = 0;
 
1367
        info->array.chunk_size    = 0;
 
1368
        info->container_enough    = 1;
 
1369
 
 
1370
 
 
1371
        info->disk.major = 0;
 
1372
        info->disk.minor = 0;
 
1373
        if (ddf->dlist) {
 
1374
                info->disk.number = __be32_to_cpu(ddf->dlist->disk.refnum);
 
1375
                info->disk.raid_disk = find_phys(ddf, ddf->dlist->disk.refnum);
 
1376
 
 
1377
                info->data_offset = __be64_to_cpu(ddf->phys->
 
1378
                                          entries[info->disk.raid_disk].
 
1379
                                          config_size);
 
1380
                info->component_size = ddf->dlist->size - info->data_offset;
 
1381
        } else {
 
1382
                info->disk.number = -1;
 
1383
                info->disk.raid_disk = -1;
 
1384
//              info->disk.raid_disk = find refnum in the table and use index;
 
1385
        }
 
1386
        info->disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE);
 
1387
 
 
1388
 
 
1389
        info->recovery_start = MaxSector;
 
1390
        info->reshape_active = 0;
 
1391
        info->name[0] = 0;
 
1392
 
 
1393
        info->array.major_version = -1;
 
1394
        info->array.minor_version = -2;
 
1395
        strcpy(info->text_version, "ddf");
 
1396
        info->safe_mode_delay = 0;
 
1397
 
 
1398
        uuid_from_super_ddf(st, info->uuid);
 
1399
 
 
1400
}
 
1401
 
 
1402
static int rlq_to_layout(int rlq, int prl, int raiddisks);
 
1403
 
 
1404
static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info)
 
1405
{
 
1406
        struct ddf_super *ddf = st->sb;
 
1407
        struct vcl *vc = ddf->currentconf;
 
1408
        int cd = ddf->currentdev;
 
1409
        int j;
 
1410
        struct dl *dl;
 
1411
 
 
1412
        /* FIXME this returns BVD info - what if we want SVD ?? */
 
1413
 
 
1414
        info->array.raid_disks    = __be16_to_cpu(vc->conf.prim_elmnt_count);
 
1415
        info->array.level         = map_num1(ddf_level_num, vc->conf.prl);
 
1416
        info->array.layout        = rlq_to_layout(vc->conf.rlq, vc->conf.prl,
 
1417
                                                  info->array.raid_disks);
 
1418
        info->array.md_minor      = -1;
 
1419
        info->array.ctime         = DECADE +
 
1420
                __be32_to_cpu(*(__u32*)(vc->conf.guid+16));
 
1421
        info->array.utime         = DECADE + __be32_to_cpu(vc->conf.timestamp);
 
1422
        info->array.chunk_size    = 512 << vc->conf.chunk_shift;
 
1423
        info->custom_array_size   = 0;
 
1424
 
 
1425
        if (cd >= 0 && (unsigned)cd < ddf->mppe) {
 
1426
                info->data_offset         = __be64_to_cpu(vc->lba_offset[cd]);
 
1427
                if (vc->block_sizes)
 
1428
                        info->component_size = vc->block_sizes[cd];
 
1429
                else
 
1430
                        info->component_size = __be64_to_cpu(vc->conf.blocks);
 
1431
        }
 
1432
 
 
1433
        for (dl = ddf->dlist; dl ; dl = dl->next)
 
1434
                if (dl->raiddisk == info->disk.raid_disk)
 
1435
                        break;
 
1436
        info->disk.major = 0;
 
1437
        info->disk.minor = 0;
 
1438
        if (dl) {
 
1439
                info->disk.major = dl->major;
 
1440
                info->disk.minor = dl->minor;
 
1441
        }
 
1442
//      info->disk.number = __be32_to_cpu(ddf->disk.refnum);
 
1443
//      info->disk.raid_disk = find refnum in the table and use index;
 
1444
//      info->disk.state = ???;
 
1445
 
 
1446
        info->container_member = ddf->currentconf->vcnum;
 
1447
 
 
1448
        info->recovery_start = MaxSector;
 
1449
        info->resync_start = 0;
 
1450
        info->reshape_active = 0;
 
1451
        if (!(ddf->virt->entries[info->container_member].state
 
1452
              & DDF_state_inconsistent)  &&
 
1453
            (ddf->virt->entries[info->container_member].init_state
 
1454
             & DDF_initstate_mask)
 
1455
            == DDF_init_full)
 
1456
                info->resync_start = MaxSector;
 
1457
 
 
1458
        uuid_from_super_ddf(st, info->uuid);
 
1459
 
 
1460
        info->container_member = atoi(st->subarray);
 
1461
        info->array.major_version = -1;
 
1462
        info->array.minor_version = -2;
 
1463
        sprintf(info->text_version, "/%s/%s",
 
1464
                devnum2devname(st->container_dev),
 
1465
                st->subarray);
 
1466
        info->safe_mode_delay = 200;
 
1467
 
 
1468
        memcpy(info->name, ddf->virt->entries[info->container_member].name, 16);
 
1469
        info->name[16]=0;
 
1470
        for(j=0; j<16; j++)
 
1471
                if (info->name[j] == ' ')
 
1472
                        info->name[j] = 0;
 
1473
}
 
1474
 
 
1475
 
 
1476
static int update_super_ddf(struct supertype *st, struct mdinfo *info,
 
1477
                            char *update,
 
1478
                            char *devname, int verbose,
 
1479
                            int uuid_set, char *homehost)
 
1480
{
 
1481
        /* For 'assemble' and 'force' we need to return non-zero if any
 
1482
         * change was made.  For others, the return value is ignored.
 
1483
         * Update options are:
 
1484
         *  force-one : This device looks a bit old but needs to be included,
 
1485
         *        update age info appropriately.
 
1486
         *  assemble: clear any 'faulty' flag to allow this device to
 
1487
         *              be assembled.
 
1488
         *  force-array: Array is degraded but being forced, mark it clean
 
1489
         *         if that will be needed to assemble it.
 
1490
         *
 
1491
         *  newdev:  not used ????
 
1492
         *  grow:  Array has gained a new device - this is currently for
 
1493
         *              linear only
 
1494
         *  resync: mark as dirty so a resync will happen.
 
1495
         *  uuid:  Change the uuid of the array to match what is given
 
1496
         *  homehost:  update the recorded homehost
 
1497
         *  name:  update the name - preserving the homehost
 
1498
         *  _reshape_progress: record new reshape_progress position.
 
1499
         *
 
1500
         * Following are not relevant for this version:
 
1501
         *  sparc2.2 : update from old dodgey metadata
 
1502
         *  super-minor: change the preferred_minor number
 
1503
         *  summaries:  update redundant counters.
 
1504
         */
 
1505
        int rv = 0;
 
1506
//      struct ddf_super *ddf = st->sb;
 
1507
//      struct vd_config *vd = find_vdcr(ddf, info->container_member);
 
1508
//      struct virtual_entry *ve = find_ve(ddf);
 
1509
 
 
1510
        /* we don't need to handle "force-*" or "assemble" as
 
1511
         * there is no need to 'trick' the kernel.  We the metadata is
 
1512
         * first updated to activate the array, all the implied modifications
 
1513
         * will just happen.
 
1514
         */
 
1515
 
 
1516
        if (strcmp(update, "grow") == 0) {
 
1517
                /* FIXME */
 
1518
        }
 
1519
        if (strcmp(update, "resync") == 0) {
 
1520
//              info->resync_checkpoint = 0;
 
1521
        }
 
1522
        /* We ignore UUID updates as they make even less sense
 
1523
         * with DDF
 
1524
         */
 
1525
        if (strcmp(update, "homehost") == 0) {
 
1526
                /* homehost is stored in controller->vendor_data,
 
1527
                 * or it is when we are the vendor
 
1528
                 */
 
1529
//              if (info->vendor_is_local)
 
1530
//                      strcpy(ddf->controller.vendor_data, homehost);
 
1531
        }
 
1532
        if (strcmp(update, "name") == 0) {
 
1533
                /* name is stored in virtual_entry->name */
 
1534
//              memset(ve->name, ' ', 16);
 
1535
//              strncpy(ve->name, info->name, 16);
 
1536
        }
 
1537
        if (strcmp(update, "_reshape_progress") == 0) {
 
1538
                /* We don't support reshape yet */
 
1539
        }
 
1540
 
 
1541
//      update_all_csum(ddf);
 
1542
 
 
1543
        return rv;
 
1544
}
 
1545
 
 
1546
static void make_header_guid(char *guid)
 
1547
{
 
1548
        __u32 stamp;
 
1549
        /* Create a DDF Header of Virtual Disk GUID */
 
1550
 
 
1551
        /* 24 bytes of fiction required.
 
1552
         * first 8 are a 'vendor-id'  - "Linux-MD"
 
1553
         * next 8 are controller type.. how about 0X DEAD BEEF 0000 0000
 
1554
         * Remaining 8 random number plus timestamp
 
1555
         */
 
1556
        memcpy(guid, T10, sizeof(T10));
 
1557
        stamp = __cpu_to_be32(0xdeadbeef);
 
1558
        memcpy(guid+8, &stamp, 4);
 
1559
        stamp = __cpu_to_be32(0);
 
1560
        memcpy(guid+12, &stamp, 4);
 
1561
        stamp = __cpu_to_be32(time(0) - DECADE);
 
1562
        memcpy(guid+16, &stamp, 4);
 
1563
        stamp = random32();
 
1564
        memcpy(guid+20, &stamp, 4);
 
1565
}
 
1566
 
 
1567
static int init_super_ddf_bvd(struct supertype *st,
 
1568
                              mdu_array_info_t *info,
 
1569
                              unsigned long long size,
 
1570
                              char *name, char *homehost,
 
1571
                              int *uuid);
 
1572
 
 
1573
static int init_super_ddf(struct supertype *st,
 
1574
                          mdu_array_info_t *info,
 
1575
                          unsigned long long size, char *name, char *homehost,
 
1576
                          int *uuid)
 
1577
{
 
1578
        /* This is primarily called by Create when creating a new array.
 
1579
         * We will then get add_to_super called for each component, and then
 
1580
         * write_init_super called to write it out to each device.
 
1581
         * For DDF, Create can create on fresh devices or on a pre-existing
 
1582
         * array.
 
1583
         * To create on a pre-existing array a different method will be called.
 
1584
         * This one is just for fresh drives.
 
1585
         *
 
1586
         * We need to create the entire 'ddf' structure which includes:
 
1587
         *  DDF headers - these are easy.
 
1588
         *  Controller data - a Sector describing this controller .. not that
 
1589
         *                  this is a controller exactly.
 
1590
         *  Physical Disk Record - one entry per device, so
 
1591
         *                      leave plenty of space.
 
1592
         *  Virtual Disk Records - again, just leave plenty of space.
 
1593
         *                   This just lists VDs, doesn't give details
 
1594
         *  Config records - describes the VDs that use this disk
 
1595
         *  DiskData  - describes 'this' device.
 
1596
         *  BadBlockManagement - empty
 
1597
         *  Diag Space - empty
 
1598
         *  Vendor Logs - Could we put bitmaps here?
 
1599
         *
 
1600
         */
 
1601
        struct ddf_super *ddf;
 
1602
        char hostname[17];
 
1603
        int hostlen;
 
1604
        int max_phys_disks, max_virt_disks;
 
1605
        unsigned long long sector;
 
1606
        int clen;
 
1607
        int i;
 
1608
        int pdsize, vdsize;
 
1609
        struct phys_disk *pd;
 
1610
        struct virtual_disk *vd;
 
1611
 
 
1612
        if (st->sb)
 
1613
                return init_super_ddf_bvd(st, info, size, name, homehost, uuid);
 
1614
 
 
1615
        if (posix_memalign((void**)&ddf, 512, sizeof(*ddf)) != 0) {
 
1616
                fprintf(stderr, Name ": %s could not allocate superblock\n", __func__);
 
1617
                return 0;
 
1618
        }
 
1619
        memset(ddf, 0, sizeof(*ddf));
 
1620
        ddf->dlist = NULL; /* no physical disks yet */
 
1621
        ddf->conflist = NULL; /* No virtual disks yet */
 
1622
        st->sb = ddf;
 
1623
 
 
1624
        if (info == NULL) {
 
1625
                /* zeroing superblock */
 
1626
                return 0;
 
1627
        }
 
1628
 
 
1629
        /* At least 32MB *must* be reserved for the ddf.  So let's just
 
1630
         * start 32MB from the end, and put the primary header there.
 
1631
         * Don't do secondary for now.
 
1632
         * We don't know exactly where that will be yet as it could be
 
1633
         * different on each device.  To just set up the lengths.
 
1634
         *
 
1635
         */
 
1636
 
 
1637
        ddf->anchor.magic = DDF_HEADER_MAGIC;
 
1638
        make_header_guid(ddf->anchor.guid);
 
1639
 
 
1640
        memcpy(ddf->anchor.revision, DDF_REVISION_2, 8);
 
1641
        ddf->anchor.seq = __cpu_to_be32(1);
 
1642
        ddf->anchor.timestamp = __cpu_to_be32(time(0) - DECADE);
 
1643
        ddf->anchor.openflag = 0xFF;
 
1644
        ddf->anchor.foreignflag = 0;
 
1645
        ddf->anchor.enforcegroups = 0; /* Is this best?? */
 
1646
        ddf->anchor.pad0 = 0xff;
 
1647
        memset(ddf->anchor.pad1, 0xff, 12);
 
1648
        memset(ddf->anchor.header_ext, 0xff, 32);
 
1649
        ddf->anchor.primary_lba = ~(__u64)0;
 
1650
        ddf->anchor.secondary_lba = ~(__u64)0;
 
1651
        ddf->anchor.type = DDF_HEADER_ANCHOR;
 
1652
        memset(ddf->anchor.pad2, 0xff, 3);
 
1653
        ddf->anchor.workspace_len = __cpu_to_be32(32768); /* Must be reserved */
 
1654
        ddf->anchor.workspace_lba = ~(__u64)0; /* Put this at bottom
 
1655
                                                  of 32M reserved.. */
 
1656
        max_phys_disks = 1023;   /* Should be enough */
 
1657
        ddf->anchor.max_pd_entries = __cpu_to_be16(max_phys_disks);
 
1658
        max_virt_disks = 255;
 
1659
        ddf->anchor.max_vd_entries = __cpu_to_be16(max_virt_disks); /* ?? */
 
1660
        ddf->anchor.max_partitions = __cpu_to_be16(64); /* ?? */
 
1661
        ddf->max_part = 64;
 
1662
        ddf->mppe = 256;
 
1663
        ddf->conf_rec_len = 1 + ROUND_UP(ddf->mppe * (4+8), 512)/512;
 
1664
        ddf->anchor.config_record_len = __cpu_to_be16(ddf->conf_rec_len);
 
1665
        ddf->anchor.max_primary_element_entries = __cpu_to_be16(ddf->mppe);
 
1666
        memset(ddf->anchor.pad3, 0xff, 54);
 
1667
        /* controller sections is one sector long immediately
 
1668
         * after the ddf header */
 
1669
        sector = 1;
 
1670
        ddf->anchor.controller_section_offset = __cpu_to_be32(sector);
 
1671
        ddf->anchor.controller_section_length = __cpu_to_be32(1);
 
1672
        sector += 1;
 
1673
 
 
1674
        /* phys is 8 sectors after that */
 
1675
        pdsize = ROUND_UP(sizeof(struct phys_disk) +
 
1676
                          sizeof(struct phys_disk_entry)*max_phys_disks,
 
1677
                          512);
 
1678
        switch(pdsize/512) {
 
1679
        case 2: case 8: case 32: case 128: case 512: break;
 
1680
        default: abort();
 
1681
        }
 
1682
        ddf->anchor.phys_section_offset = __cpu_to_be32(sector);
 
1683
        ddf->anchor.phys_section_length =
 
1684
                __cpu_to_be32(pdsize/512); /* max_primary_element_entries/8 */
 
1685
        sector += pdsize/512;
 
1686
 
 
1687
        /* virt is another 32 sectors */
 
1688
        vdsize = ROUND_UP(sizeof(struct virtual_disk) +
 
1689
                          sizeof(struct virtual_entry) * max_virt_disks,
 
1690
                          512);
 
1691
        switch(vdsize/512) {
 
1692
        case 2: case 8: case 32: case 128: case 512: break;
 
1693
        default: abort();
 
1694
        }
 
1695
        ddf->anchor.virt_section_offset = __cpu_to_be32(sector);
 
1696
        ddf->anchor.virt_section_length =
 
1697
                __cpu_to_be32(vdsize/512); /* max_vd_entries/8 */
 
1698
        sector += vdsize/512;
 
1699
 
 
1700
        clen = ddf->conf_rec_len * (ddf->max_part+1);
 
1701
        ddf->anchor.config_section_offset = __cpu_to_be32(sector);
 
1702
        ddf->anchor.config_section_length = __cpu_to_be32(clen);
 
1703
        sector += clen;
 
1704
 
 
1705
        ddf->anchor.data_section_offset = __cpu_to_be32(sector);
 
1706
        ddf->anchor.data_section_length = __cpu_to_be32(1);
 
1707
        sector += 1;
 
1708
 
 
1709
        ddf->anchor.bbm_section_length = __cpu_to_be32(0);
 
1710
        ddf->anchor.bbm_section_offset = __cpu_to_be32(0xFFFFFFFF);
 
1711
        ddf->anchor.diag_space_length = __cpu_to_be32(0);
 
1712
        ddf->anchor.diag_space_offset = __cpu_to_be32(0xFFFFFFFF);
 
1713
        ddf->anchor.vendor_length = __cpu_to_be32(0);
 
1714
        ddf->anchor.vendor_offset = __cpu_to_be32(0xFFFFFFFF);
 
1715
 
 
1716
        memset(ddf->anchor.pad4, 0xff, 256);
 
1717
 
 
1718
        memcpy(&ddf->primary, &ddf->anchor, 512);
 
1719
        memcpy(&ddf->secondary, &ddf->anchor, 512);
 
1720
 
 
1721
        ddf->primary.openflag = 1; /* I guess.. */
 
1722
        ddf->primary.type = DDF_HEADER_PRIMARY;
 
1723
 
 
1724
        ddf->secondary.openflag = 1; /* I guess.. */
 
1725
        ddf->secondary.type = DDF_HEADER_SECONDARY;
 
1726
 
 
1727
        ddf->active = &ddf->primary;
 
1728
 
 
1729
        ddf->controller.magic = DDF_CONTROLLER_MAGIC;
 
1730
 
 
1731
        /* 24 more bytes of fiction required.
 
1732
         * first 8 are a 'vendor-id'  - "Linux-MD"
 
1733
         * Remaining 16 are serial number.... maybe a hostname would do?
 
1734
         */
 
1735
        memcpy(ddf->controller.guid, T10, sizeof(T10));
 
1736
        gethostname(hostname, sizeof(hostname));
 
1737
        hostname[sizeof(hostname) - 1] = 0;
 
1738
        hostlen = strlen(hostname);
 
1739
        memcpy(ddf->controller.guid + 24 - hostlen, hostname, hostlen);
 
1740
        for (i = strlen(T10) ; i+hostlen < 24; i++)
 
1741
                ddf->controller.guid[i] = ' ';
 
1742
 
 
1743
        ddf->controller.type.vendor_id = __cpu_to_be16(0xDEAD);
 
1744
        ddf->controller.type.device_id = __cpu_to_be16(0xBEEF);
 
1745
        ddf->controller.type.sub_vendor_id = 0;
 
1746
        ddf->controller.type.sub_device_id = 0;
 
1747
        memcpy(ddf->controller.product_id, "What Is My PID??", 16);
 
1748
        memset(ddf->controller.pad, 0xff, 8);
 
1749
        memset(ddf->controller.vendor_data, 0xff, 448);
 
1750
        if (homehost && strlen(homehost) < 440)
 
1751
                strcpy((char*)ddf->controller.vendor_data, homehost);
 
1752
 
 
1753
        if (posix_memalign((void**)&pd, 512, pdsize) != 0) {
 
1754
                fprintf(stderr, Name ": %s could not allocate pd\n", __func__);
 
1755
                return 0;
 
1756
        }
 
1757
        ddf->phys = pd;
 
1758
        ddf->pdsize = pdsize;
 
1759
 
 
1760
        memset(pd, 0xff, pdsize);
 
1761
        memset(pd, 0, sizeof(*pd));
 
1762
        pd->magic = DDF_PHYS_RECORDS_MAGIC;
 
1763
        pd->used_pdes = __cpu_to_be16(0);
 
1764
        pd->max_pdes = __cpu_to_be16(max_phys_disks);
 
1765
        memset(pd->pad, 0xff, 52);
 
1766
 
 
1767
        if (posix_memalign((void**)&vd, 512, vdsize) != 0) {
 
1768
                fprintf(stderr, Name ": %s could not allocate vd\n", __func__);
 
1769
                return 0;
 
1770
        }
 
1771
        ddf->virt = vd;
 
1772
        ddf->vdsize = vdsize;
 
1773
        memset(vd, 0, vdsize);
 
1774
        vd->magic = DDF_VIRT_RECORDS_MAGIC;
 
1775
        vd->populated_vdes = __cpu_to_be16(0);
 
1776
        vd->max_vdes = __cpu_to_be16(max_virt_disks);
 
1777
        memset(vd->pad, 0xff, 52);
 
1778
 
 
1779
        for (i=0; i<max_virt_disks; i++)
 
1780
                memset(&vd->entries[i], 0xff, sizeof(struct virtual_entry));
 
1781
 
 
1782
        st->sb = ddf;
 
1783
        ddf->updates_pending = 1;
 
1784
        return 1;
 
1785
}
 
1786
 
 
1787
static int chunk_to_shift(int chunksize)
 
1788
{
 
1789
        return ffs(chunksize/512)-1;
 
1790
}
 
1791
 
 
1792
static int level_to_prl(int level)
 
1793
{
 
1794
        switch (level) {
 
1795
        case LEVEL_LINEAR: return DDF_CONCAT;
 
1796
        case 0: return DDF_RAID0;
 
1797
        case 1: return DDF_RAID1;
 
1798
        case 4: return DDF_RAID4;
 
1799
        case 5: return DDF_RAID5;
 
1800
        case 6: return DDF_RAID6;
 
1801
        default: return -1;
 
1802
        }
 
1803
}
 
1804
static int layout_to_rlq(int level, int layout, int raiddisks)
 
1805
{
 
1806
        switch(level) {
 
1807
        case 0:
 
1808
                return DDF_RAID0_SIMPLE;
 
1809
        case 1:
 
1810
                switch(raiddisks) {
 
1811
                case 2: return DDF_RAID1_SIMPLE;
 
1812
                case 3: return DDF_RAID1_MULTI;
 
1813
                default: return -1;
 
1814
                }
 
1815
        case 4:
 
1816
                switch(layout) {
 
1817
                case 0: return DDF_RAID4_N;
 
1818
                }
 
1819
                break;
 
1820
        case 5:
 
1821
                switch(layout) {
 
1822
                case ALGORITHM_LEFT_ASYMMETRIC:
 
1823
                        return DDF_RAID5_N_RESTART;
 
1824
                case ALGORITHM_RIGHT_ASYMMETRIC:
 
1825
                        return DDF_RAID5_0_RESTART;
 
1826
                case ALGORITHM_LEFT_SYMMETRIC:
 
1827
                        return DDF_RAID5_N_CONTINUE;
 
1828
                case ALGORITHM_RIGHT_SYMMETRIC:
 
1829
                        return -1; /* not mentioned in standard */
 
1830
                }
 
1831
        case 6:
 
1832
                switch(layout) {
 
1833
                case ALGORITHM_ROTATING_N_RESTART:
 
1834
                        return DDF_RAID5_N_RESTART;
 
1835
                case ALGORITHM_ROTATING_ZERO_RESTART:
 
1836
                        return DDF_RAID6_0_RESTART;
 
1837
                case ALGORITHM_ROTATING_N_CONTINUE:
 
1838
                        return DDF_RAID5_N_CONTINUE;
 
1839
                }
 
1840
        }
 
1841
        return -1;
 
1842
}
 
1843
 
 
1844
static int rlq_to_layout(int rlq, int prl, int raiddisks)
 
1845
{
 
1846
        switch(prl) {
 
1847
        case DDF_RAID0:
 
1848
                return 0; /* hopefully rlq == DDF_RAID0_SIMPLE */
 
1849
        case DDF_RAID1:
 
1850
                return 0; /* hopefully rlq == SIMPLE or MULTI depending
 
1851
                             on raiddisks*/
 
1852
        case DDF_RAID4:
 
1853
                switch(rlq) {
 
1854
                case DDF_RAID4_N:
 
1855
                        return 0;
 
1856
                default:
 
1857
                        /* not supported */
 
1858
                        return -1; /* FIXME this isn't checked */
 
1859
                }
 
1860
        case DDF_RAID5:
 
1861
                switch(rlq) {
 
1862
                case DDF_RAID5_N_RESTART:
 
1863
                        return ALGORITHM_LEFT_ASYMMETRIC;
 
1864
                case DDF_RAID5_0_RESTART:
 
1865
                        return ALGORITHM_RIGHT_ASYMMETRIC;
 
1866
                case DDF_RAID5_N_CONTINUE:
 
1867
                        return ALGORITHM_LEFT_SYMMETRIC;
 
1868
                default:
 
1869
                        return -1;
 
1870
                }
 
1871
        case DDF_RAID6:
 
1872
                switch(rlq) {
 
1873
                case DDF_RAID5_N_RESTART:
 
1874
                        return ALGORITHM_ROTATING_N_RESTART;
 
1875
                case DDF_RAID6_0_RESTART:
 
1876
                        return ALGORITHM_ROTATING_ZERO_RESTART;
 
1877
                case DDF_RAID5_N_CONTINUE:
 
1878
                        return ALGORITHM_ROTATING_N_CONTINUE;
 
1879
                default:
 
1880
                        return -1;
 
1881
                }
 
1882
        }
 
1883
        return -1;
 
1884
}
 
1885
 
 
1886
#ifndef MDASSEMBLE
 
1887
struct extent {
 
1888
        unsigned long long start, size;
 
1889
};
 
1890
static int cmp_extent(const void *av, const void *bv)
 
1891
{
 
1892
        const struct extent *a = av;
 
1893
        const struct extent *b = bv;
 
1894
        if (a->start < b->start)
 
1895
                return -1;
 
1896
        if (a->start > b->start)
 
1897
                return 1;
 
1898
        return 0;
 
1899
}
 
1900
 
 
1901
static struct extent *get_extents(struct ddf_super *ddf, struct dl *dl)
 
1902
{
 
1903
        /* find a list of used extents on the give physical device
 
1904
         * (dnum) of the given ddf.
 
1905
         * Return a malloced array of 'struct extent'
 
1906
 
 
1907
FIXME ignore DDF_Legacy devices?
 
1908
 
 
1909
         */
 
1910
        struct extent *rv;
 
1911
        int n = 0;
 
1912
        unsigned int i, j;
 
1913
 
 
1914
        rv = malloc(sizeof(struct extent) * (ddf->max_part + 2));
 
1915
        if (!rv)
 
1916
                return NULL;
 
1917
 
 
1918
        for (i = 0; i < ddf->max_part; i++) {
 
1919
                struct vcl *v = dl->vlist[i];
 
1920
                if (v == NULL)
 
1921
                        continue;
 
1922
                for (j = 0; j < v->conf.prim_elmnt_count; j++)
 
1923
                        if (v->conf.phys_refnum[j] == dl->disk.refnum) {
 
1924
                                /* This device plays role 'j' in  'v'. */
 
1925
                                rv[n].start = __be64_to_cpu(v->lba_offset[j]);
 
1926
                                rv[n].size = __be64_to_cpu(v->conf.blocks);
 
1927
                                n++;
 
1928
                                break;
 
1929
                        }
 
1930
        }
 
1931
        qsort(rv, n, sizeof(*rv), cmp_extent);
 
1932
 
 
1933
        rv[n].start = __be64_to_cpu(ddf->phys->entries[dl->pdnum].config_size);
 
1934
        rv[n].size = 0;
 
1935
        return rv;
 
1936
}
 
1937
#endif
 
1938
 
 
1939
static int init_super_ddf_bvd(struct supertype *st,
 
1940
                              mdu_array_info_t *info,
 
1941
                              unsigned long long size,
 
1942
                              char *name, char *homehost,
 
1943
                              int *uuid)
 
1944
{
 
1945
        /* We are creating a BVD inside a pre-existing container.
 
1946
         * so st->sb is already set.
 
1947
         * We need to create a new vd_config and a new virtual_entry
 
1948
         */
 
1949
        struct ddf_super *ddf = st->sb;
 
1950
        unsigned int venum;
 
1951
        struct virtual_entry *ve;
 
1952
        struct vcl *vcl;
 
1953
        struct vd_config *vc;
 
1954
 
 
1955
        if (__be16_to_cpu(ddf->virt->populated_vdes)
 
1956
            >= __be16_to_cpu(ddf->virt->max_vdes)) {
 
1957
                fprintf(stderr, Name": This ddf already has the "
 
1958
                        "maximum of %d virtual devices\n",
 
1959
                        __be16_to_cpu(ddf->virt->max_vdes));
 
1960
                return 0;
 
1961
        }
 
1962
 
 
1963
        for (venum = 0; venum < __be16_to_cpu(ddf->virt->max_vdes); venum++)
 
1964
                if (all_ff(ddf->virt->entries[venum].guid))
 
1965
                        break;
 
1966
        if (venum == __be16_to_cpu(ddf->virt->max_vdes)) {
 
1967
                fprintf(stderr, Name ": Cannot find spare slot for "
 
1968
                        "virtual disk - DDF is corrupt\n");
 
1969
                return 0;
 
1970
        }
 
1971
        ve = &ddf->virt->entries[venum];
 
1972
 
 
1973
        /* A Virtual Disk GUID contains the T10 Vendor ID, controller type,
 
1974
         * timestamp, random number
 
1975
         */
 
1976
        make_header_guid(ve->guid);
 
1977
        ve->unit = __cpu_to_be16(info->md_minor);
 
1978
        ve->pad0 = 0xFFFF;
 
1979
        ve->guid_crc = crc32(0, (unsigned char*)ddf->anchor.guid, DDF_GUID_LEN);
 
1980
        ve->type = 0;
 
1981
        ve->state = DDF_state_degraded; /* Will be modified as devices are added */
 
1982
        if (info->state & 1) /* clean */
 
1983
                ve->init_state = DDF_init_full;
 
1984
        else
 
1985
                ve->init_state = DDF_init_not;
 
1986
 
 
1987
        memset(ve->pad1, 0xff, 14);
 
1988
        memset(ve->name, ' ', 16);
 
1989
        if (name)
 
1990
                strncpy(ve->name, name, 16);
 
1991
        ddf->virt->populated_vdes =
 
1992
                __cpu_to_be16(__be16_to_cpu(ddf->virt->populated_vdes)+1);
 
1993
 
 
1994
        /* Now create a new vd_config */
 
1995
        if (posix_memalign((void**)&vcl, 512,
 
1996
                           (offsetof(struct vcl, conf) + ddf->conf_rec_len * 512)) != 0) {
 
1997
                fprintf(stderr, Name ": %s could not allocate vd_config\n", __func__);
 
1998
                return 0;
 
1999
        }
 
2000
        vcl->lba_offset = (__u64*) &vcl->conf.phys_refnum[ddf->mppe];
 
2001
        vcl->vcnum = venum;
 
2002
        sprintf(st->subarray, "%d", venum);
 
2003
        vcl->block_sizes = NULL; /* FIXME not for CONCAT */
 
2004
 
 
2005
        vc = &vcl->conf;
 
2006
 
 
2007
        vc->magic = DDF_VD_CONF_MAGIC;
 
2008
        memcpy(vc->guid, ve->guid, DDF_GUID_LEN);
 
2009
        vc->timestamp = __cpu_to_be32(time(0)-DECADE);
 
2010
        vc->seqnum = __cpu_to_be32(1);
 
2011
        memset(vc->pad0, 0xff, 24);
 
2012
        vc->prim_elmnt_count = __cpu_to_be16(info->raid_disks);
 
2013
        vc->chunk_shift = chunk_to_shift(info->chunk_size);
 
2014
        vc->prl = level_to_prl(info->level);
 
2015
        vc->rlq = layout_to_rlq(info->level, info->layout, info->raid_disks);
 
2016
        vc->sec_elmnt_count = 1;
 
2017
        vc->sec_elmnt_seq = 0;
 
2018
        vc->srl = 0;
 
2019
        vc->blocks = __cpu_to_be64(info->size * 2);
 
2020
        vc->array_blocks = __cpu_to_be64(
 
2021
                calc_array_size(info->level, info->raid_disks, info->layout,
 
2022
                                info->chunk_size, info->size*2));
 
2023
        memset(vc->pad1, 0xff, 8);
 
2024
        vc->spare_refs[0] = 0xffffffff;
 
2025
        vc->spare_refs[1] = 0xffffffff;
 
2026
        vc->spare_refs[2] = 0xffffffff;
 
2027
        vc->spare_refs[3] = 0xffffffff;
 
2028
        vc->spare_refs[4] = 0xffffffff;
 
2029
        vc->spare_refs[5] = 0xffffffff;
 
2030
        vc->spare_refs[6] = 0xffffffff;
 
2031
        vc->spare_refs[7] = 0xffffffff;
 
2032
        memset(vc->cache_pol, 0, 8);
 
2033
        vc->bg_rate = 0x80;
 
2034
        memset(vc->pad2, 0xff, 3);
 
2035
        memset(vc->pad3, 0xff, 52);
 
2036
        memset(vc->pad4, 0xff, 192);
 
2037
        memset(vc->v0, 0xff, 32);
 
2038
        memset(vc->v1, 0xff, 32);
 
2039
        memset(vc->v2, 0xff, 16);
 
2040
        memset(vc->v3, 0xff, 16);
 
2041
        memset(vc->vendor, 0xff, 32);
 
2042
 
 
2043
        memset(vc->phys_refnum, 0xff, 4*ddf->mppe);
 
2044
        memset(vc->phys_refnum+ddf->mppe, 0x00, 8*ddf->mppe);
 
2045
 
 
2046
        vcl->next = ddf->conflist;
 
2047
        ddf->conflist = vcl;
 
2048
        ddf->currentconf = vcl;
 
2049
        ddf->updates_pending = 1;
 
2050
        return 1;
 
2051
}
 
2052
 
 
2053
#ifndef MDASSEMBLE
 
2054
static void add_to_super_ddf_bvd(struct supertype *st,
 
2055
                                 mdu_disk_info_t *dk, int fd, char *devname)
 
2056
{
 
2057
        /* fd and devname identify a device with-in the ddf container (st).
 
2058
         * dk identifies a location in the new BVD.
 
2059
         * We need to find suitable free space in that device and update
 
2060
         * the phys_refnum and lba_offset for the newly created vd_config.
 
2061
         * We might also want to update the type in the phys_disk
 
2062
         * section.
 
2063
         *
 
2064
         * Alternately: fd == -1 and we have already chosen which device to
 
2065
         * use and recorded in dlist->raid_disk;
 
2066
         */
 
2067
        struct dl *dl;
 
2068
        struct ddf_super *ddf = st->sb;
 
2069
        struct vd_config *vc;
 
2070
        __u64 *lba_offset;
 
2071
        unsigned int working;
 
2072
        unsigned int i;
 
2073
        unsigned long long blocks, pos, esize;
 
2074
        struct extent *ex;
 
2075
 
 
2076
        if (fd == -1) {
 
2077
                for (dl = ddf->dlist; dl ; dl = dl->next)
 
2078
                        if (dl->raiddisk == dk->raid_disk)
 
2079
                                break;
 
2080
        } else {
 
2081
                for (dl = ddf->dlist; dl ; dl = dl->next)
 
2082
                        if (dl->major == dk->major &&
 
2083
                            dl->minor == dk->minor)
 
2084
                                break;
 
2085
        }
 
2086
        if (!dl || ! (dk->state & (1<<MD_DISK_SYNC)))
 
2087
                return;
 
2088
 
 
2089
        vc = &ddf->currentconf->conf;
 
2090
        lba_offset = ddf->currentconf->lba_offset;
 
2091
 
 
2092
        ex = get_extents(ddf, dl);
 
2093
        if (!ex)
 
2094
                return;
 
2095
 
 
2096
        i = 0; pos = 0;
 
2097
        blocks = __be64_to_cpu(vc->blocks);
 
2098
        if (ddf->currentconf->block_sizes)
 
2099
                blocks = ddf->currentconf->block_sizes[dk->raid_disk];
 
2100
 
 
2101
        do {
 
2102
                esize = ex[i].start - pos;
 
2103
                if (esize >= blocks)
 
2104
                        break;
 
2105
                pos = ex[i].start + ex[i].size;
 
2106
                i++;
 
2107
        } while (ex[i-1].size);
 
2108
 
 
2109
        free(ex);
 
2110
        if (esize < blocks)
 
2111
                return;
 
2112
 
 
2113
        ddf->currentdev = dk->raid_disk;
 
2114
        vc->phys_refnum[dk->raid_disk] = dl->disk.refnum;
 
2115
        lba_offset[dk->raid_disk] = __cpu_to_be64(pos);
 
2116
 
 
2117
        for (i = 0; i < ddf->max_part ; i++)
 
2118
                if (dl->vlist[i] == NULL)
 
2119
                        break;
 
2120
        if (i == ddf->max_part)
 
2121
                return;
 
2122
        dl->vlist[i] = ddf->currentconf;
 
2123
 
 
2124
        if (fd >= 0)
 
2125
                dl->fd = fd;
 
2126
        if (devname)
 
2127
                dl->devname = devname;
 
2128
 
 
2129
        /* Check how many working raid_disks, and if we can mark
 
2130
         * array as optimal yet
 
2131
         */
 
2132
        working = 0;
 
2133
 
 
2134
        for (i = 0; i < __be16_to_cpu(vc->prim_elmnt_count); i++)
 
2135
                if (vc->phys_refnum[i] != 0xffffffff)
 
2136
                        working++;
 
2137
 
 
2138
        /* Find which virtual_entry */
 
2139
        i = ddf->currentconf->vcnum;
 
2140
        if (working == __be16_to_cpu(vc->prim_elmnt_count))
 
2141
                ddf->virt->entries[i].state =
 
2142
                        (ddf->virt->entries[i].state & ~DDF_state_mask)
 
2143
                        | DDF_state_optimal;
 
2144
 
 
2145
        if (vc->prl == DDF_RAID6 &&
 
2146
            working+1 == __be16_to_cpu(vc->prim_elmnt_count))
 
2147
                ddf->virt->entries[i].state =
 
2148
                        (ddf->virt->entries[i].state & ~DDF_state_mask)
 
2149
                        | DDF_state_part_optimal;
 
2150
 
 
2151
        ddf->phys->entries[dl->pdnum].type &= ~__cpu_to_be16(DDF_Global_Spare);
 
2152
        ddf->phys->entries[dl->pdnum].type |= __cpu_to_be16(DDF_Active_in_VD);
 
2153
        ddf->updates_pending = 1;
 
2154
}
 
2155
 
 
2156
/* add a device to a container, either while creating it or while
 
2157
 * expanding a pre-existing container
 
2158
 */
 
2159
static int add_to_super_ddf(struct supertype *st,
 
2160
                             mdu_disk_info_t *dk, int fd, char *devname)
 
2161
{
 
2162
        struct ddf_super *ddf = st->sb;
 
2163
        struct dl *dd;
 
2164
        time_t now;
 
2165
        struct tm *tm;
 
2166
        unsigned long long size;
 
2167
        struct phys_disk_entry *pde;
 
2168
        unsigned int n, i;
 
2169
        struct stat stb;
 
2170
 
 
2171
        if (ddf->currentconf) {
 
2172
                add_to_super_ddf_bvd(st, dk, fd, devname);
 
2173
                return 0;
 
2174
        }
 
2175
 
 
2176
        /* This is device numbered dk->number.  We need to create
 
2177
         * a phys_disk entry and a more detailed disk_data entry.
 
2178
         */
 
2179
        fstat(fd, &stb);
 
2180
        if (posix_memalign((void**)&dd, 512,
 
2181
                           sizeof(*dd) + sizeof(dd->vlist[0]) * ddf->max_part) != 0) {
 
2182
                fprintf(stderr, Name
 
2183
                        ": %s could allocate buffer for new disk, aborting\n",
 
2184
                        __func__);
 
2185
                return 1;
 
2186
        }
 
2187
        dd->major = major(stb.st_rdev);
 
2188
        dd->minor = minor(stb.st_rdev);
 
2189
        dd->devname = devname;
 
2190
        dd->fd = fd;
 
2191
        dd->spare = NULL;
 
2192
 
 
2193
        dd->disk.magic = DDF_PHYS_DATA_MAGIC;
 
2194
        now = time(0);
 
2195
        tm = localtime(&now);
 
2196
        sprintf(dd->disk.guid, "%8s%04d%02d%02d",
 
2197
                T10, tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
 
2198
        *(__u32*)(dd->disk.guid + 16) = random32();
 
2199
        *(__u32*)(dd->disk.guid + 20) = random32();
 
2200
 
 
2201
        do {
 
2202
                /* Cannot be bothered finding a CRC of some irrelevant details*/
 
2203
                dd->disk.refnum = random32();
 
2204
                for (i = __be16_to_cpu(ddf->active->max_pd_entries);
 
2205
                     i > 0; i--)
 
2206
                        if (ddf->phys->entries[i-1].refnum == dd->disk.refnum)
 
2207
                                break;
 
2208
        } while (i > 0);
 
2209
 
 
2210
        dd->disk.forced_ref = 1;
 
2211
        dd->disk.forced_guid = 1;
 
2212
        memset(dd->disk.vendor, ' ', 32);
 
2213
        memcpy(dd->disk.vendor, "Linux", 5);
 
2214
        memset(dd->disk.pad, 0xff, 442);
 
2215
        for (i = 0; i < ddf->max_part ; i++)
 
2216
                dd->vlist[i] = NULL;
 
2217
 
 
2218
        n = __be16_to_cpu(ddf->phys->used_pdes);
 
2219
        pde = &ddf->phys->entries[n];
 
2220
        dd->pdnum = n;
 
2221
 
 
2222
        if (st->update_tail) {
 
2223
                int len = (sizeof(struct phys_disk) +
 
2224
                           sizeof(struct phys_disk_entry));
 
2225
                struct phys_disk *pd;
 
2226
 
 
2227
                pd = malloc(len);
 
2228
                pd->magic = DDF_PHYS_RECORDS_MAGIC;
 
2229
                pd->used_pdes = __cpu_to_be16(n);
 
2230
                pde = &pd->entries[0];
 
2231
                dd->mdupdate = pd;
 
2232
        } else {
 
2233
                n++;
 
2234
                ddf->phys->used_pdes = __cpu_to_be16(n);
 
2235
        }
 
2236
 
 
2237
        memcpy(pde->guid, dd->disk.guid, DDF_GUID_LEN);
 
2238
        pde->refnum = dd->disk.refnum;
 
2239
        pde->type = __cpu_to_be16(DDF_Forced_PD_GUID | DDF_Global_Spare);
 
2240
        pde->state = __cpu_to_be16(DDF_Online);
 
2241
        get_dev_size(fd, NULL, &size);
 
2242
        /* We are required to reserve 32Meg, and record the size in sectors */
 
2243
        pde->config_size = __cpu_to_be64( (size - 32*1024*1024) / 512);
 
2244
        sprintf(pde->path, "%17.17s","Information: nil") ;
 
2245
        memset(pde->pad, 0xff, 6);
 
2246
 
 
2247
        dd->size = size >> 9;
 
2248
        if (st->update_tail) {
 
2249
                dd->next = ddf->add_list;
 
2250
                ddf->add_list = dd;
 
2251
        } else {
 
2252
                dd->next = ddf->dlist;
 
2253
                ddf->dlist = dd;
 
2254
                ddf->updates_pending = 1;
 
2255
        }
 
2256
 
 
2257
        return 0;
 
2258
}
 
2259
 
 
2260
/*
 
2261
 * This is the write_init_super method for a ddf container.  It is
 
2262
 * called when creating a container or adding another device to a
 
2263
 * container.
 
2264
 */
 
2265
 
 
2266
static unsigned char null_conf[4096+512];
 
2267
 
 
2268
static int __write_init_super_ddf(struct supertype *st, int do_close)
 
2269
{
 
2270
 
 
2271
        struct ddf_super *ddf = st->sb;
 
2272
        int i;
 
2273
        struct dl *d;
 
2274
        int n_config;
 
2275
        int conf_size;
 
2276
        int attempts = 0;
 
2277
        int successes = 0;
 
2278
        unsigned long long size, sector;
 
2279
 
 
2280
        /* try to write updated metadata,
 
2281
         * if we catch a failure move on to the next disk
 
2282
         */
 
2283
        for (d = ddf->dlist; d; d=d->next) {
 
2284
                int fd = d->fd;
 
2285
 
 
2286
                if (fd < 0)
 
2287
                        continue;
 
2288
 
 
2289
                attempts++;
 
2290
                /* We need to fill in the primary, (secondary) and workspace
 
2291
                 * lba's in the headers, set their checksums,
 
2292
                 * Also checksum phys, virt....
 
2293
                 *
 
2294
                 * Then write everything out, finally the anchor is written.
 
2295
                 */
 
2296
                get_dev_size(fd, NULL, &size);
 
2297
                size /= 512;
 
2298
                ddf->anchor.workspace_lba = __cpu_to_be64(size - 32*1024*2);
 
2299
                ddf->anchor.primary_lba = __cpu_to_be64(size - 16*1024*2);
 
2300
                ddf->anchor.seq = __cpu_to_be32(1);
 
2301
                memcpy(&ddf->primary, &ddf->anchor, 512);
 
2302
                memcpy(&ddf->secondary, &ddf->anchor, 512);
 
2303
 
 
2304
                ddf->anchor.openflag = 0xFF; /* 'open' means nothing */
 
2305
                ddf->anchor.seq = 0xFFFFFFFF; /* no sequencing in anchor */
 
2306
                ddf->anchor.crc = calc_crc(&ddf->anchor, 512);
 
2307
 
 
2308
                ddf->primary.openflag = 0;
 
2309
                ddf->primary.type = DDF_HEADER_PRIMARY;
 
2310
 
 
2311
                ddf->secondary.openflag = 0;
 
2312
                ddf->secondary.type = DDF_HEADER_SECONDARY;
 
2313
 
 
2314
                ddf->primary.crc = calc_crc(&ddf->primary, 512);
 
2315
                ddf->secondary.crc = calc_crc(&ddf->secondary, 512);
 
2316
 
 
2317
                sector = size - 16*1024*2;
 
2318
                lseek64(fd, sector<<9, 0);
 
2319
                if (write(fd, &ddf->primary, 512) < 0)
 
2320
                        continue;
 
2321
 
 
2322
                ddf->controller.crc = calc_crc(&ddf->controller, 512);
 
2323
                if (write(fd, &ddf->controller, 512) < 0)
 
2324
                        continue;
 
2325
 
 
2326
                ddf->phys->crc = calc_crc(ddf->phys, ddf->pdsize);
 
2327
 
 
2328
                if (write(fd, ddf->phys, ddf->pdsize) < 0)
 
2329
                        continue;
 
2330
 
 
2331
                ddf->virt->crc = calc_crc(ddf->virt, ddf->vdsize);
 
2332
                if (write(fd, ddf->virt, ddf->vdsize) < 0)
 
2333
                        continue;
 
2334
 
 
2335
                /* Now write lots of config records. */
 
2336
                n_config = ddf->max_part;
 
2337
                conf_size = ddf->conf_rec_len * 512;
 
2338
                for (i = 0 ; i <= n_config ; i++) {
 
2339
                        struct vcl *c = d->vlist[i];
 
2340
                        if (i == n_config)
 
2341
                                c = (struct vcl*)d->spare;
 
2342
 
 
2343
                        if (c) {
 
2344
                                c->conf.crc = calc_crc(&c->conf, conf_size);
 
2345
                                if (write(fd, &c->conf, conf_size) < 0)
 
2346
                                        break;
 
2347
                        } else {
 
2348
                                char *null_aligned = (char*)((((unsigned long)null_conf)+511)&~511UL);
 
2349
                                if (null_conf[0] != 0xff)
 
2350
                                        memset(null_conf, 0xff, sizeof(null_conf));
 
2351
                                unsigned int togo = conf_size;
 
2352
                                while (togo > sizeof(null_conf)-512) {
 
2353
                                        if (write(fd, null_aligned, sizeof(null_conf)-512) < 0)
 
2354
                                                break;
 
2355
                                        togo -= sizeof(null_conf)-512;
 
2356
                                }
 
2357
                                if (write(fd, null_aligned, togo) < 0)
 
2358
                                        break;
 
2359
                        }
 
2360
                }
 
2361
                if (i <= n_config)
 
2362
                        continue;
 
2363
                d->disk.crc = calc_crc(&d->disk, 512);
 
2364
                if (write(fd, &d->disk, 512) < 0)
 
2365
                        continue;
 
2366
 
 
2367
                /* Maybe do the same for secondary */
 
2368
 
 
2369
                lseek64(fd, (size-1)*512, SEEK_SET);
 
2370
                if (write(fd, &ddf->anchor, 512) < 0)
 
2371
                        continue;
 
2372
                successes++;
 
2373
        }
 
2374
 
 
2375
        if (do_close)
 
2376
                for (d = ddf->dlist; d; d=d->next) {
 
2377
                        close(d->fd);
 
2378
                        d->fd = -1;
 
2379
                }
 
2380
 
 
2381
        return attempts != successes;
 
2382
}
 
2383
 
 
2384
static int write_init_super_ddf(struct supertype *st)
 
2385
{
 
2386
        struct ddf_super *ddf = st->sb;
 
2387
        struct vcl *currentconf = ddf->currentconf;
 
2388
 
 
2389
        /* we are done with currentconf reset it to point st at the container */
 
2390
        ddf->currentconf = NULL;
 
2391
 
 
2392
        if (st->update_tail) {
 
2393
                /* queue the virtual_disk and vd_config as metadata updates */
 
2394
                struct virtual_disk *vd;
 
2395
                struct vd_config *vc;
 
2396
                int len;
 
2397
 
 
2398
                if (!currentconf) {
 
2399
                        int len = (sizeof(struct phys_disk) +
 
2400
                                   sizeof(struct phys_disk_entry));
 
2401
 
 
2402
                        /* adding a disk to the container. */
 
2403
                        if (!ddf->add_list)
 
2404
                                return 0;
 
2405
 
 
2406
                        append_metadata_update(st, ddf->add_list->mdupdate, len);
 
2407
                        ddf->add_list->mdupdate = NULL;
 
2408
                        return 0;
 
2409
                }
 
2410
 
 
2411
                /* Newly created VD */
 
2412
 
 
2413
                /* First the virtual disk.  We have a slightly fake header */
 
2414
                len = sizeof(struct virtual_disk) + sizeof(struct virtual_entry);
 
2415
                vd = malloc(len);
 
2416
                *vd = *ddf->virt;
 
2417
                vd->entries[0] = ddf->virt->entries[currentconf->vcnum];
 
2418
                vd->populated_vdes = __cpu_to_be16(currentconf->vcnum);
 
2419
                append_metadata_update(st, vd, len);
 
2420
 
 
2421
                /* Then the vd_config */
 
2422
                len = ddf->conf_rec_len * 512;
 
2423
                vc = malloc(len);
 
2424
                memcpy(vc, &currentconf->conf, len);
 
2425
                append_metadata_update(st, vc, len);
 
2426
 
 
2427
                /* FIXME I need to close the fds! */
 
2428
                return 0;
 
2429
        } else {        
 
2430
                struct dl *d;
 
2431
                for (d = ddf->dlist; d; d=d->next)
 
2432
                        while (Kill(d->devname, NULL, 0, 1, 1) == 0);
 
2433
                return __write_init_super_ddf(st, 1);
 
2434
        }
 
2435
}
 
2436
 
 
2437
#endif
 
2438
 
 
2439
static __u64 avail_size_ddf(struct supertype *st, __u64 devsize)
 
2440
{
 
2441
        /* We must reserve the last 32Meg */
 
2442
        if (devsize <= 32*1024*2)
 
2443
                return 0;
 
2444
        return devsize - 32*1024*2;
 
2445
}
 
2446
 
 
2447
#ifndef MDASSEMBLE
 
2448
 
 
2449
static int reserve_space(struct supertype *st, int raiddisks,
 
2450
                         unsigned long long size, int chunk,
 
2451
                         unsigned long long *freesize)
 
2452
{
 
2453
        /* Find 'raiddisks' spare extents at least 'size' big (but
 
2454
         * only caring about multiples of 'chunk') and remember
 
2455
         * them.
 
2456
         * If the cannot be found, fail.
 
2457
         */
 
2458
        struct dl *dl;
 
2459
        struct ddf_super *ddf = st->sb;
 
2460
        int cnt = 0;
 
2461
 
 
2462
        for (dl = ddf->dlist; dl ; dl=dl->next) {
 
2463
                dl->raiddisk = -1;      
 
2464
                dl->esize = 0;
 
2465
        }
 
2466
        /* Now find largest extent on each device */
 
2467
        for (dl = ddf->dlist ; dl ; dl=dl->next) {
 
2468
                struct extent *e = get_extents(ddf, dl);
 
2469
                unsigned long long pos = 0;
 
2470
                int i = 0;
 
2471
                int found = 0;
 
2472
                unsigned long long minsize = size;
 
2473
 
 
2474
                if (size == 0)
 
2475
                        minsize = chunk;
 
2476
 
 
2477
                if (!e)
 
2478
                        continue;
 
2479
                do {
 
2480
                        unsigned long long esize;
 
2481
                        esize = e[i].start - pos;
 
2482
                        if (esize >= minsize) {
 
2483
                                found = 1;
 
2484
                                minsize = esize;
 
2485
                        }
 
2486
                        pos = e[i].start + e[i].size;
 
2487
                        i++;
 
2488
                } while (e[i-1].size);
 
2489
                if (found) {
 
2490
                        cnt++;
 
2491
                        dl->esize = minsize;
 
2492
                }
 
2493
                free(e);
 
2494
        }
 
2495
        if (cnt < raiddisks) {
 
2496
                fprintf(stderr, Name ": not enough devices with space to create array.\n");
 
2497
                return 0; /* No enough free spaces large enough */
 
2498
        }
 
2499
        if (size == 0) {
 
2500
                /* choose the largest size of which there are at least 'raiddisk' */
 
2501
                for (dl = ddf->dlist ; dl ; dl=dl->next) {
 
2502
                        struct dl *dl2;
 
2503
                        if (dl->esize <= size)
 
2504
                                continue;
 
2505
                        /* This is bigger than 'size', see if there are enough */
 
2506
                        cnt = 0;
 
2507
                        for (dl2 = dl; dl2 ; dl2=dl2->next)
 
2508
                                if (dl2->esize >= dl->esize)
 
2509
                                        cnt++;
 
2510
                        if (cnt >= raiddisks)
 
2511
                                size = dl->esize;
 
2512
                }
 
2513
                if (chunk) {
 
2514
                        size = size / chunk;
 
2515
                        size *= chunk;
 
2516
                }
 
2517
                *freesize = size;
 
2518
                if (size < 32) {
 
2519
                        fprintf(stderr, Name ": not enough spare devices to create array.\n");
 
2520
                        return 0;
 
2521
                }
 
2522
        }
 
2523
        /* We have a 'size' of which there are enough spaces.
 
2524
         * We simply do a first-fit */
 
2525
        cnt = 0;
 
2526
        for (dl = ddf->dlist ; dl && cnt < raiddisks ; dl=dl->next) {
 
2527
                if (dl->esize < size)
 
2528
                        continue;
 
2529
                
 
2530
                dl->raiddisk = cnt;
 
2531
                cnt++;
 
2532
        }
 
2533
        return 1;
 
2534
}
 
2535
 
 
2536
 
 
2537
 
 
2538
static int
 
2539
validate_geometry_ddf_container(struct supertype *st,
 
2540
                                int level, int layout, int raiddisks,
 
2541
                                int chunk, unsigned long long size,
 
2542
                                char *dev, unsigned long long *freesize,
 
2543
                                int verbose);
 
2544
 
 
2545
static int validate_geometry_ddf_bvd(struct supertype *st,
 
2546
                                     int level, int layout, int raiddisks,
 
2547
                                     int chunk, unsigned long long size,
 
2548
                                     char *dev, unsigned long long *freesize,
 
2549
                                     int verbose);
 
2550
 
 
2551
static int validate_geometry_ddf(struct supertype *st,
 
2552
                                 int level, int layout, int raiddisks,
 
2553
                                 int chunk, unsigned long long size,
 
2554
                                 char *dev, unsigned long long *freesize,
 
2555
                                 int verbose)
 
2556
{
 
2557
        int fd;
 
2558
        struct mdinfo *sra;
 
2559
        int cfd;
 
2560
 
 
2561
        /* ddf potentially supports lots of things, but it depends on
 
2562
         * what devices are offered (and maybe kernel version?)
 
2563
         * If given unused devices, we will make a container.
 
2564
         * If given devices in a container, we will make a BVD.
 
2565
         * If given BVDs, we make an SVD, changing all the GUIDs in the process.
 
2566
         */
 
2567
 
 
2568
        if (level == LEVEL_CONTAINER) {
 
2569
                /* Must be a fresh device to add to a container */
 
2570
                return validate_geometry_ddf_container(st, level, layout,
 
2571
                                                       raiddisks, chunk,
 
2572
                                                       size, dev, freesize,
 
2573
                                                       verbose);
 
2574
        }
 
2575
 
 
2576
        if (!dev) {
 
2577
                /* Initial sanity check.  Exclude illegal levels. */
 
2578
                int i;
 
2579
                for (i=0; ddf_level_num[i].num1 != MAXINT; i++)
 
2580
                        if (ddf_level_num[i].num2 == level)
 
2581
                                break;
 
2582
                if (ddf_level_num[i].num1 == MAXINT) {
 
2583
                        if (verbose)
 
2584
                                fprintf(stderr, Name ": DDF does not support level %d arrays\n",
 
2585
                                        level);
 
2586
                        return 0;
 
2587
                }
 
2588
                /* Should check layout? etc */
 
2589
 
 
2590
                if (st->sb && freesize) {
 
2591
                        /* --create was given a container to create in.
 
2592
                         * So we need to check that there are enough
 
2593
                         * free spaces and return the amount of space.
 
2594
                         * We may as well remember which drives were
 
2595
                         * chosen so that add_to_super/getinfo_super
 
2596
                         * can return them.
 
2597
                         */
 
2598
                        return reserve_space(st, raiddisks, size, chunk, freesize);
 
2599
                }
 
2600
                return 1;
 
2601
        }
 
2602
 
 
2603
        if (st->sb) {
 
2604
                /* A container has already been opened, so we are
 
2605
                 * creating in there.  Maybe a BVD, maybe an SVD.
 
2606
                 * Should make a distinction one day.
 
2607
                 */
 
2608
                return validate_geometry_ddf_bvd(st, level, layout, raiddisks,
 
2609
                                                 chunk, size, dev, freesize,
 
2610
                                                 verbose);
 
2611
        }
 
2612
        /* This is the first device for the array.
 
2613
         * If it is a container, we read it in and do automagic allocations,
 
2614
         * no other devices should be given.
 
2615
         * Otherwise it must be a member device of a container, and we
 
2616
         * do manual allocation.
 
2617
         * Later we should check for a BVD and make an SVD.
 
2618
         */
 
2619
        fd = open(dev, O_RDONLY|O_EXCL, 0);
 
2620
        if (fd >= 0) {
 
2621
                sra = sysfs_read(fd, 0, GET_VERSION);
 
2622
                close(fd);
 
2623
                if (sra && sra->array.major_version == -1 &&
 
2624
                    strcmp(sra->text_version, "ddf") == 0) {
 
2625
 
 
2626
                        /* load super */
 
2627
                        /* find space for 'n' devices. */
 
2628
                        /* remember the devices */
 
2629
                        /* Somehow return the fact that we have enough */
 
2630
                }
 
2631
 
 
2632
                if (verbose)
 
2633
                        fprintf(stderr,
 
2634
                                Name ": ddf: Cannot create this array "
 
2635
                                "on device %s - a container is required.\n",
 
2636
                                dev);
 
2637
                return 0;
 
2638
        }
 
2639
        if (errno != EBUSY || (fd = open(dev, O_RDONLY, 0)) < 0) {
 
2640
                if (verbose)
 
2641
                        fprintf(stderr, Name ": ddf: Cannot open %s: %s\n",
 
2642
                                dev, strerror(errno));
 
2643
                return 0;
 
2644
        }
 
2645
        /* Well, it is in use by someone, maybe a 'ddf' container. */
 
2646
        cfd = open_container(fd);
 
2647
        if (cfd < 0) {
 
2648
                close(fd);
 
2649
                if (verbose)
 
2650
                        fprintf(stderr, Name ": ddf: Cannot use %s: %s\n",
 
2651
                                dev, strerror(EBUSY));
 
2652
                return 0;
 
2653
        }
 
2654
        sra = sysfs_read(cfd, 0, GET_VERSION);
 
2655
        close(fd);
 
2656
        if (sra && sra->array.major_version == -1 &&
 
2657
            strcmp(sra->text_version, "ddf") == 0) {
 
2658
                /* This is a member of a ddf container.  Load the container
 
2659
                 * and try to create a bvd
 
2660
                 */
 
2661
                struct ddf_super *ddf;
 
2662
                if (load_super_ddf_all(st, cfd, (void **)&ddf, NULL, 1) == 0) {
 
2663
                        st->sb = ddf;
 
2664
                        st->container_dev = fd2devnum(cfd);
 
2665
                        close(cfd);
 
2666
                        return validate_geometry_ddf_bvd(st, level, layout,
 
2667
                                                         raiddisks, chunk, size,
 
2668
                                                         dev, freesize,
 
2669
                                                         verbose);
 
2670
                }
 
2671
                close(cfd);
 
2672
        } else /* device may belong to a different container */
 
2673
                return 0;
 
2674
 
 
2675
        return 1;
 
2676
}
 
2677
 
 
2678
static int
 
2679
validate_geometry_ddf_container(struct supertype *st,
 
2680
                                int level, int layout, int raiddisks,
 
2681
                                int chunk, unsigned long long size,
 
2682
                                char *dev, unsigned long long *freesize,
 
2683
                                int verbose)
 
2684
{
 
2685
        int fd;
 
2686
        unsigned long long ldsize;
 
2687
 
 
2688
        if (level != LEVEL_CONTAINER)
 
2689
                return 0;
 
2690
        if (!dev)
 
2691
                return 1;
 
2692
 
 
2693
        fd = open(dev, O_RDONLY|O_EXCL, 0);
 
2694
        if (fd < 0) {
 
2695
                if (verbose)
 
2696
                        fprintf(stderr, Name ": ddf: Cannot open %s: %s\n",
 
2697
                                dev, strerror(errno));
 
2698
                return 0;
 
2699
        }
 
2700
        if (!get_dev_size(fd, dev, &ldsize)) {
 
2701
                close(fd);
 
2702
                return 0;
 
2703
        }
 
2704
        close(fd);
 
2705
 
 
2706
        *freesize = avail_size_ddf(st, ldsize >> 9);
 
2707
        if (*freesize == 0)
 
2708
                return 0;
 
2709
 
 
2710
        return 1;
 
2711
}
 
2712
 
 
2713
static int validate_geometry_ddf_bvd(struct supertype *st,
 
2714
                                     int level, int layout, int raiddisks,
 
2715
                                     int chunk, unsigned long long size,
 
2716
                                     char *dev, unsigned long long *freesize,
 
2717
                                     int verbose)
 
2718
{
 
2719
        struct stat stb;
 
2720
        struct ddf_super *ddf = st->sb;
 
2721
        struct dl *dl;
 
2722
        unsigned long long pos = 0;
 
2723
        unsigned long long maxsize;
 
2724
        struct extent *e;
 
2725
        int i;
 
2726
        /* ddf/bvd supports lots of things, but not containers */
 
2727
        if (level == LEVEL_CONTAINER) {
 
2728
                if (verbose)
 
2729
                        fprintf(stderr, Name ": DDF cannot create a container within an container\n");
 
2730
                return 0;
 
2731
        }
 
2732
        /* We must have the container info already read in. */
 
2733
        if (!ddf)
 
2734
                return 0;
 
2735
 
 
2736
        if (!dev) {
 
2737
                /* General test:  make sure there is space for
 
2738
                 * 'raiddisks' device extents of size 'size'.
 
2739
                 */
 
2740
                unsigned long long minsize = size;
 
2741
                int dcnt = 0;
 
2742
                if (minsize == 0)
 
2743
                        minsize = 8;
 
2744
                for (dl = ddf->dlist; dl ; dl = dl->next)
 
2745
                {
 
2746
                        int found = 0;
 
2747
                        pos = 0;
 
2748
 
 
2749
                        i = 0;
 
2750
                        e = get_extents(ddf, dl);
 
2751
                        if (!e) continue;
 
2752
                        do {
 
2753
                                unsigned long long esize;
 
2754
                                esize = e[i].start - pos;
 
2755
                                if (esize >= minsize)
 
2756
                                        found = 1;
 
2757
                                pos = e[i].start + e[i].size;
 
2758
                                i++;
 
2759
                        } while (e[i-1].size);
 
2760
                        if (found)
 
2761
                                dcnt++;
 
2762
                        free(e);
 
2763
                }
 
2764
                if (dcnt < raiddisks) {
 
2765
                        if (verbose)
 
2766
                                fprintf(stderr,
 
2767
                                        Name ": ddf: Not enough devices with "
 
2768
                                        "space for this array (%d < %d)\n",
 
2769
                                        dcnt, raiddisks);
 
2770
                        return 0;
 
2771
                }
 
2772
                return 1;
 
2773
        }
 
2774
        /* This device must be a member of the set */
 
2775
        if (stat(dev, &stb) < 0)
 
2776
                return 0;
 
2777
        if ((S_IFMT & stb.st_mode) != S_IFBLK)
 
2778
                return 0;
 
2779
        for (dl = ddf->dlist ; dl ; dl = dl->next) {
 
2780
                if (dl->major == (int)major(stb.st_rdev) &&
 
2781
                    dl->minor == (int)minor(stb.st_rdev))
 
2782
                        break;
 
2783
        }
 
2784
        if (!dl) {
 
2785
                if (verbose)
 
2786
                        fprintf(stderr, Name ": ddf: %s is not in the "
 
2787
                                "same DDF set\n",
 
2788
                                dev);
 
2789
                return 0;
 
2790
        }
 
2791
        e = get_extents(ddf, dl);
 
2792
        maxsize = 0;
 
2793
        i = 0;
 
2794
        if (e) do {
 
2795
                unsigned long long esize;
 
2796
                esize = e[i].start - pos;
 
2797
                if (esize >= maxsize)
 
2798
                        maxsize = esize;
 
2799
                pos = e[i].start + e[i].size;
 
2800
                i++;
 
2801
        } while (e[i-1].size);
 
2802
        *freesize = maxsize;
 
2803
        // FIXME here I am
 
2804
 
 
2805
        return 1;
 
2806
}
 
2807
 
 
2808
static int load_super_ddf_all(struct supertype *st, int fd,
 
2809
                              void **sbp, char *devname, int keep_fd)
 
2810
{
 
2811
        struct mdinfo *sra;
 
2812
        struct ddf_super *super;
 
2813
        struct mdinfo *sd, *best = NULL;
 
2814
        int bestseq = 0;
 
2815
        int seq;
 
2816
        char nm[20];
 
2817
        int dfd;
 
2818
 
 
2819
        sra = sysfs_read(fd, 0, GET_LEVEL|GET_VERSION|GET_DEVS|GET_STATE);
 
2820
        if (!sra)
 
2821
                return 1;
 
2822
        if (sra->array.major_version != -1 ||
 
2823
            sra->array.minor_version != -2 ||
 
2824
            strcmp(sra->text_version, "ddf") != 0)
 
2825
                return 1;
 
2826
 
 
2827
        if (posix_memalign((void**)&super, 512, sizeof(*super)) != 0)
 
2828
                return 1;
 
2829
        memset(super, 0, sizeof(*super));
 
2830
 
 
2831
        /* first, try each device, and choose the best ddf */
 
2832
        for (sd = sra->devs ; sd ; sd = sd->next) {
 
2833
                int rv;
 
2834
                sprintf(nm, "%d:%d", sd->disk.major, sd->disk.minor);
 
2835
                dfd = dev_open(nm, O_RDONLY);
 
2836
                if (dfd < 0)
 
2837
                        return 2;
 
2838
                rv = load_ddf_headers(dfd, super, NULL);
 
2839
                close(dfd);
 
2840
                if (rv == 0) {
 
2841
                        seq = __be32_to_cpu(super->active->seq);
 
2842
                        if (super->active->openflag)
 
2843
                                seq--;
 
2844
                        if (!best || seq > bestseq) {
 
2845
                                bestseq = seq;
 
2846
                                best = sd;
 
2847
                        }
 
2848
                }
 
2849
        }
 
2850
        if (!best)
 
2851
                return 1;
 
2852
        /* OK, load this ddf */
 
2853
        sprintf(nm, "%d:%d", best->disk.major, best->disk.minor);
 
2854
        dfd = dev_open(nm, O_RDONLY);
 
2855
        if (dfd < 0)
 
2856
                return 1;
 
2857
        load_ddf_headers(dfd, super, NULL);
 
2858
        load_ddf_global(dfd, super, NULL);
 
2859
        close(dfd);
 
2860
        /* Now we need the device-local bits */
 
2861
        for (sd = sra->devs ; sd ; sd = sd->next) {
 
2862
                int rv;
 
2863
 
 
2864
                sprintf(nm, "%d:%d", sd->disk.major, sd->disk.minor);
 
2865
                dfd = dev_open(nm, keep_fd? O_RDWR : O_RDONLY);
 
2866
                if (dfd < 0)
 
2867
                        return 2;
 
2868
                rv = load_ddf_headers(dfd, super, NULL);
 
2869
                if (rv == 0)
 
2870
                        rv = load_ddf_local(dfd, super, NULL, keep_fd);
 
2871
                if (!keep_fd) close(dfd);
 
2872
                if (rv)
 
2873
                        return 1;
 
2874
        }
 
2875
        if (st->subarray[0]) {
 
2876
                unsigned long val;
 
2877
                struct vcl *v;
 
2878
                char *ep;
 
2879
 
 
2880
                val = strtoul(st->subarray, &ep, 10);
 
2881
                if (*ep != '\0') {
 
2882
                        free(super);
 
2883
                        return 1;
 
2884
                }
 
2885
 
 
2886
                for (v = super->conflist; v; v = v->next)
 
2887
                        if (v->vcnum == val)
 
2888
                                super->currentconf = v;
 
2889
                if (!super->currentconf) {
 
2890
                        free(super);
 
2891
                        return 1;
 
2892
                }
 
2893
        }
 
2894
 
 
2895
        *sbp = super;
 
2896
        if (st->ss == NULL) {
 
2897
                st->ss = &super_ddf;
 
2898
                st->minor_version = 0;
 
2899
                st->max_devs = 512;
 
2900
                st->container_dev = fd2devnum(fd);
 
2901
        }
 
2902
        st->loaded_container = 1;
 
2903
        return 0;
 
2904
}
 
2905
#endif /* MDASSEMBLE */
 
2906
 
 
2907
static struct mdinfo *container_content_ddf(struct supertype *st)
 
2908
{
 
2909
        /* Given a container loaded by load_super_ddf_all,
 
2910
         * extract information about all the arrays into
 
2911
         * an mdinfo tree.
 
2912
         *
 
2913
         * For each vcl in conflist: create an mdinfo, fill it in,
 
2914
         *  then look for matching devices (phys_refnum) in dlist
 
2915
         *  and create appropriate device mdinfo.
 
2916
         */
 
2917
        struct ddf_super *ddf = st->sb;
 
2918
        struct mdinfo *rest = NULL;
 
2919
        struct vcl *vc;
 
2920
 
 
2921
        for (vc = ddf->conflist ; vc ; vc=vc->next)
 
2922
        {
 
2923
                unsigned int i;
 
2924
                unsigned int j;
 
2925
                struct mdinfo *this;
 
2926
                this = malloc(sizeof(*this));
 
2927
                memset(this, 0, sizeof(*this));
 
2928
                this->next = rest;
 
2929
                rest = this;
 
2930
 
 
2931
                this->array.level = map_num1(ddf_level_num, vc->conf.prl);
 
2932
                this->array.raid_disks =
 
2933
                        __be16_to_cpu(vc->conf.prim_elmnt_count);
 
2934
                this->array.layout = rlq_to_layout(vc->conf.rlq, vc->conf.prl,
 
2935
                                                   this->array.raid_disks);
 
2936
                this->array.md_minor      = -1;
 
2937
                this->array.major_version = -1;
 
2938
                this->array.minor_version = -2;
 
2939
                this->array.ctime         = DECADE +
 
2940
                        __be32_to_cpu(*(__u32*)(vc->conf.guid+16));
 
2941
                this->array.utime         = DECADE +
 
2942
                        __be32_to_cpu(vc->conf.timestamp);
 
2943
                this->array.chunk_size    = 512 << vc->conf.chunk_shift;
 
2944
 
 
2945
                i = vc->vcnum;
 
2946
                if ((ddf->virt->entries[i].state & DDF_state_inconsistent) ||
 
2947
                    (ddf->virt->entries[i].init_state & DDF_initstate_mask) !=
 
2948
                    DDF_init_full) {
 
2949
                        this->array.state = 0;
 
2950
                        this->resync_start = 0;
 
2951
                } else {
 
2952
                        this->array.state = 1;
 
2953
                        this->resync_start = MaxSector;
 
2954
                }
 
2955
                memcpy(this->name, ddf->virt->entries[i].name, 16);
 
2956
                this->name[16]=0;
 
2957
                for(j=0; j<16; j++)
 
2958
                        if (this->name[j] == ' ')
 
2959
                                this->name[j] = 0;
 
2960
 
 
2961
                memset(this->uuid, 0, sizeof(this->uuid));
 
2962
                this->component_size = __be64_to_cpu(vc->conf.blocks);
 
2963
                this->array.size = this->component_size / 2;
 
2964
                this->container_member = i;
 
2965
 
 
2966
                ddf->currentconf = vc;
 
2967
                uuid_from_super_ddf(st, this->uuid);
 
2968
                ddf->currentconf = NULL;
 
2969
 
 
2970
                sprintf(this->text_version, "/%s/%d",
 
2971
                        devnum2devname(st->container_dev),
 
2972
                        this->container_member);
 
2973
 
 
2974
                for (i = 0 ; i < ddf->mppe ; i++) {
 
2975
                        struct mdinfo *dev;
 
2976
                        struct dl *d;
 
2977
 
 
2978
                        if (vc->conf.phys_refnum[i] == 0xFFFFFFFF)
 
2979
                                continue;
 
2980
 
 
2981
                        this->array.working_disks++;
 
2982
 
 
2983
                        for (d = ddf->dlist; d ; d=d->next)
 
2984
                                if (d->disk.refnum == vc->conf.phys_refnum[i])
 
2985
                                        break;
 
2986
                        if (d == NULL)
 
2987
                                /* Haven't found that one yet, maybe there are others */
 
2988
                                continue;
 
2989
 
 
2990
                        dev = malloc(sizeof(*dev));
 
2991
                        memset(dev, 0, sizeof(*dev));
 
2992
                        dev->next = this->devs;
 
2993
                        this->devs = dev;
 
2994
 
 
2995
                        dev->disk.number = __be32_to_cpu(d->disk.refnum);
 
2996
                        dev->disk.major = d->major;
 
2997
                        dev->disk.minor = d->minor;
 
2998
                        dev->disk.raid_disk = i;
 
2999
                        dev->disk.state = (1<<MD_DISK_SYNC)|(1<<MD_DISK_ACTIVE);
 
3000
                        dev->recovery_start = MaxSector;
 
3001
 
 
3002
                        dev->events = __be32_to_cpu(ddf->primary.seq);
 
3003
                        dev->data_offset = __be64_to_cpu(vc->lba_offset[i]);
 
3004
                        dev->component_size = __be64_to_cpu(vc->conf.blocks);
 
3005
                        if (d->devname)
 
3006
                                strcpy(dev->name, d->devname);
 
3007
                }
 
3008
        }
 
3009
        return rest;
 
3010
}
 
3011
 
 
3012
static int store_super_ddf(struct supertype *st, int fd)
 
3013
{
 
3014
        struct ddf_super *ddf = st->sb;
 
3015
        unsigned long long dsize;
 
3016
        void *buf;
 
3017
        int rc;
 
3018
 
 
3019
        if (!ddf)
 
3020
                return 1;
 
3021
 
 
3022
        /* ->dlist and ->conflist will be set for updates, currently not
 
3023
         * supported
 
3024
         */
 
3025
        if (ddf->dlist || ddf->conflist)
 
3026
                return 1;
 
3027
 
 
3028
        if (!get_dev_size(fd, NULL, &dsize))
 
3029
                return 1;
 
3030
 
 
3031
        if (posix_memalign(&buf, 512, 512) != 0)
 
3032
                return 1;
 
3033
        memset(buf, 0, 512);
 
3034
 
 
3035
        lseek64(fd, dsize-512, 0);
 
3036
        rc = write(fd, buf, 512);
 
3037
        free(buf);
 
3038
        if (rc < 0)
 
3039
                return 1;
 
3040
        return 0;
 
3041
}
 
3042
 
 
3043
static int compare_super_ddf(struct supertype *st, struct supertype *tst)
 
3044
{
 
3045
        /*
 
3046
         * return:
 
3047
         *  0 same, or first was empty, and second was copied
 
3048
         *  1 second had wrong number
 
3049
         *  2 wrong uuid
 
3050
         *  3 wrong other info
 
3051
         */
 
3052
        struct ddf_super *first = st->sb;
 
3053
        struct ddf_super *second = tst->sb;
 
3054
 
 
3055
        if (!first) {
 
3056
                st->sb = tst->sb;
 
3057
                tst->sb = NULL;
 
3058
                return 0;
 
3059
        }
 
3060
 
 
3061
        if (memcmp(first->anchor.guid, second->anchor.guid, DDF_GUID_LEN) != 0)
 
3062
                return 2;
 
3063
 
 
3064
        /* FIXME should I look at anything else? */
 
3065
        return 0;
 
3066
}
 
3067
 
 
3068
#ifndef MDASSEMBLE
 
3069
/*
 
3070
 * A new array 'a' has been started which claims to be instance 'inst'
 
3071
 * within container 'c'.
 
3072
 * We need to confirm that the array matches the metadata in 'c' so
 
3073
 * that we don't corrupt any metadata.
 
3074
 */
 
3075
static int ddf_open_new(struct supertype *c, struct active_array *a, char *inst)
 
3076
{
 
3077
        dprintf("ddf: open_new %s\n", inst);
 
3078
        a->info.container_member = atoi(inst);
 
3079
        return 0;
 
3080
}
 
3081
 
 
3082
/*
 
3083
 * The array 'a' is to be marked clean in the metadata.
 
3084
 * If '->resync_start' is not ~(unsigned long long)0, then the array is only
 
3085
 * clean up to the point (in sectors).  If that cannot be recorded in the
 
3086
 * metadata, then leave it as dirty.
 
3087
 *
 
3088
 * For DDF, we need to clear the DDF_state_inconsistent bit in the
 
3089
 * !global! virtual_disk.virtual_entry structure.
 
3090
 */
 
3091
static int ddf_set_array_state(struct active_array *a, int consistent)
 
3092
{
 
3093
        struct ddf_super *ddf = a->container->sb;
 
3094
        int inst = a->info.container_member;
 
3095
        int old = ddf->virt->entries[inst].state;
 
3096
        if (consistent == 2) {
 
3097
                /* Should check if a recovery should be started FIXME */
 
3098
                consistent = 1;
 
3099
                if (!is_resync_complete(&a->info))
 
3100
                        consistent = 0;
 
3101
        }
 
3102
        if (consistent)
 
3103
                ddf->virt->entries[inst].state &= ~DDF_state_inconsistent;
 
3104
        else
 
3105
                ddf->virt->entries[inst].state |= DDF_state_inconsistent;
 
3106
        if (old != ddf->virt->entries[inst].state)
 
3107
                ddf->updates_pending = 1;
 
3108
 
 
3109
        old = ddf->virt->entries[inst].init_state;
 
3110
        ddf->virt->entries[inst].init_state &= ~DDF_initstate_mask;
 
3111
        if (is_resync_complete(&a->info))
 
3112
                ddf->virt->entries[inst].init_state |= DDF_init_full;
 
3113
        else if (a->info.resync_start == 0)
 
3114
                ddf->virt->entries[inst].init_state |= DDF_init_not;
 
3115
        else
 
3116
                ddf->virt->entries[inst].init_state |= DDF_init_quick;
 
3117
        if (old != ddf->virt->entries[inst].init_state)
 
3118
                ddf->updates_pending = 1;
 
3119
 
 
3120
        dprintf("ddf mark %d %s %llu\n", inst, consistent?"clean":"dirty",
 
3121
                a->info.resync_start);
 
3122
        return consistent;
 
3123
}
 
3124
 
 
3125
/*
 
3126
 * The state of each disk is stored in the global phys_disk structure
 
3127
 * in phys_disk.entries[n].state.
 
3128
 * This makes various combinations awkward.
 
3129
 * - When a device fails in any array, it must be failed in all arrays
 
3130
 *   that include a part of this device.
 
3131
 * - When a component is rebuilding, we cannot include it officially in the
 
3132
 *   array unless this is the only array that uses the device.
 
3133
 *
 
3134
 * So: when transitioning:
 
3135
 *   Online -> failed,  just set failed flag.  monitor will propagate
 
3136
 *   spare -> online,   the device might need to be added to the array.
 
3137
 *   spare -> failed,   just set failed.  Don't worry if in array or not.
 
3138
 */
 
3139
static void ddf_set_disk(struct active_array *a, int n, int state)
 
3140
{
 
3141
        struct ddf_super *ddf = a->container->sb;
 
3142
        unsigned int inst = a->info.container_member;
 
3143
        struct vd_config *vc = find_vdcr(ddf, inst);
 
3144
        int pd = find_phys(ddf, vc->phys_refnum[n]);
 
3145
        int i, st, working;
 
3146
 
 
3147
        if (vc == NULL) {
 
3148
                dprintf("ddf: cannot find instance %d!!\n", inst);
 
3149
                return;
 
3150
        }
 
3151
        if (pd < 0) {
 
3152
                /* disk doesn't currently exist. If it is now in_sync,
 
3153
                 * insert it. */
 
3154
                if ((state & DS_INSYNC) && ! (state & DS_FAULTY)) {
 
3155
                        /* Find dev 'n' in a->info->devs, determine the
 
3156
                         * ddf refnum, and set vc->phys_refnum and update
 
3157
                         * phys->entries[]
 
3158
                         */
 
3159
                        /* FIXME */
 
3160
                }
 
3161
        } else {
 
3162
                int old = ddf->phys->entries[pd].state;
 
3163
                if (state & DS_FAULTY)
 
3164
                        ddf->phys->entries[pd].state  |= __cpu_to_be16(DDF_Failed);
 
3165
                if (state & DS_INSYNC) {
 
3166
                        ddf->phys->entries[pd].state  |= __cpu_to_be16(DDF_Online);
 
3167
                        ddf->phys->entries[pd].state  &= __cpu_to_be16(~DDF_Rebuilding);
 
3168
                }
 
3169
                if (old != ddf->phys->entries[pd].state)
 
3170
                        ddf->updates_pending = 1;
 
3171
        }
 
3172
 
 
3173
        dprintf("ddf: set_disk %d to %x\n", n, state);
 
3174
 
 
3175
        /* Now we need to check the state of the array and update
 
3176
         * virtual_disk.entries[n].state.
 
3177
         * It needs to be one of "optimal", "degraded", "failed".
 
3178
         * I don't understand 'deleted' or 'missing'.
 
3179
         */
 
3180
        working = 0;
 
3181
        for (i=0; i < a->info.array.raid_disks; i++) {
 
3182
                pd = find_phys(ddf, vc->phys_refnum[i]);
 
3183
                if (pd < 0)
 
3184
                        continue;
 
3185
                st = __be16_to_cpu(ddf->phys->entries[pd].state);
 
3186
                if ((st & (DDF_Online|DDF_Failed|DDF_Rebuilding))
 
3187
                    == DDF_Online)
 
3188
                        working++;
 
3189
        }
 
3190
        state = DDF_state_degraded;
 
3191
        if (working == a->info.array.raid_disks)
 
3192
                state = DDF_state_optimal;
 
3193
        else switch(vc->prl) {
 
3194
        case DDF_RAID0:
 
3195
        case DDF_CONCAT:
 
3196
        case DDF_JBOD:
 
3197
                state = DDF_state_failed;
 
3198
                break;
 
3199
        case DDF_RAID1:
 
3200
                if (working == 0)
 
3201
                        state = DDF_state_failed;
 
3202
                break;
 
3203
        case DDF_RAID4:
 
3204
        case DDF_RAID5:
 
3205
                if (working < a->info.array.raid_disks-1)
 
3206
                        state = DDF_state_failed;
 
3207
                break;
 
3208
        case DDF_RAID6:
 
3209
                if (working < a->info.array.raid_disks-2)
 
3210
                        state = DDF_state_failed;
 
3211
                else if (working == a->info.array.raid_disks-1)
 
3212
                        state = DDF_state_part_optimal;
 
3213
                break;
 
3214
        }
 
3215
 
 
3216
        if (ddf->virt->entries[inst].state !=
 
3217
            ((ddf->virt->entries[inst].state & ~DDF_state_mask)
 
3218
             | state)) {
 
3219
 
 
3220
                ddf->virt->entries[inst].state =
 
3221
                        (ddf->virt->entries[inst].state & ~DDF_state_mask)
 
3222
                        | state;
 
3223
                ddf->updates_pending = 1;
 
3224
        }
 
3225
 
 
3226
}
 
3227
 
 
3228
static void ddf_sync_metadata(struct supertype *st)
 
3229
{
 
3230
 
 
3231
        /*
 
3232
         * Write all data to all devices.
 
3233
         * Later, we might be able to track whether only local changes
 
3234
         * have been made, or whether any global data has been changed,
 
3235
         * but ddf is sufficiently weird that it probably always
 
3236
         * changes global data ....
 
3237
         */
 
3238
        struct ddf_super *ddf = st->sb;
 
3239
        if (!ddf->updates_pending)
 
3240
                return;
 
3241
        ddf->updates_pending = 0;
 
3242
        __write_init_super_ddf(st, 0);
 
3243
        dprintf("ddf: sync_metadata\n");
 
3244
}
 
3245
 
 
3246
static void ddf_process_update(struct supertype *st,
 
3247
                               struct metadata_update *update)
 
3248
{
 
3249
        /* Apply this update to the metadata.
 
3250
         * The first 4 bytes are a DDF_*_MAGIC which guides
 
3251
         * our actions.
 
3252
         * Possible update are:
 
3253
         *  DDF_PHYS_RECORDS_MAGIC
 
3254
         *    Add a new physical device.  Changes to this record
 
3255
         *    only happen implicitly.
 
3256
         *    used_pdes is the device number.
 
3257
         *  DDF_VIRT_RECORDS_MAGIC
 
3258
         *    Add a new VD.  Possibly also change the 'access' bits.
 
3259
         *    populated_vdes is the entry number.
 
3260
         *  DDF_VD_CONF_MAGIC
 
3261
         *    New or updated VD.  the VIRT_RECORD must already
 
3262
         *    exist.  For an update, phys_refnum and lba_offset
 
3263
         *    (at least) are updated, and the VD_CONF must
 
3264
         *    be written to precisely those devices listed with
 
3265
         *    a phys_refnum.
 
3266
         *  DDF_SPARE_ASSIGN_MAGIC
 
3267
         *    replacement Spare Assignment Record... but for which device?
 
3268
         *
 
3269
         * So, e.g.:
 
3270
         *  - to create a new array, we send a VIRT_RECORD and
 
3271
         *    a VD_CONF.  Then assemble and start the array.
 
3272
         *  - to activate a spare we send a VD_CONF to add the phys_refnum
 
3273
         *    and offset.  This will also mark the spare as active with
 
3274
         *    a spare-assignment record.
 
3275
         */
 
3276
        struct ddf_super *ddf = st->sb;
 
3277
        __u32 *magic = (__u32*)update->buf;
 
3278
        struct phys_disk *pd;
 
3279
        struct virtual_disk *vd;
 
3280
        struct vd_config *vc;
 
3281
        struct vcl *vcl;
 
3282
        struct dl *dl;
 
3283
        unsigned int mppe;
 
3284
        unsigned int ent;
 
3285
 
 
3286
        dprintf("Process update %x\n", *magic);
 
3287
 
 
3288
        switch (*magic) {
 
3289
        case DDF_PHYS_RECORDS_MAGIC:
 
3290
 
 
3291
                if (update->len != (sizeof(struct phys_disk) +
 
3292
                                    sizeof(struct phys_disk_entry)))
 
3293
                        return;
 
3294
                pd = (struct phys_disk*)update->buf;
 
3295
 
 
3296
                ent = __be16_to_cpu(pd->used_pdes);
 
3297
                if (ent >= __be16_to_cpu(ddf->phys->max_pdes))
 
3298
                        return;
 
3299
                if (!all_ff(ddf->phys->entries[ent].guid))
 
3300
                        return;
 
3301
                ddf->phys->entries[ent] = pd->entries[0];
 
3302
                ddf->phys->used_pdes = __cpu_to_be16(1 +
 
3303
                                           __be16_to_cpu(ddf->phys->used_pdes));
 
3304
                ddf->updates_pending = 1;
 
3305
                if (ddf->add_list) {
 
3306
                        struct active_array *a;
 
3307
                        struct dl *al = ddf->add_list;
 
3308
                        ddf->add_list = al->next;
 
3309
 
 
3310
                        al->next = ddf->dlist;
 
3311
                        ddf->dlist = al;
 
3312
 
 
3313
                        /* As a device has been added, we should check
 
3314
                         * for any degraded devices that might make
 
3315
                         * use of this spare */
 
3316
                        for (a = st->arrays ; a; a=a->next)
 
3317
                                a->check_degraded = 1;
 
3318
                }
 
3319
                break;
 
3320
 
 
3321
        case DDF_VIRT_RECORDS_MAGIC:
 
3322
 
 
3323
                if (update->len != (sizeof(struct virtual_disk) +
 
3324
                                    sizeof(struct virtual_entry)))
 
3325
                        return;
 
3326
                vd = (struct virtual_disk*)update->buf;
 
3327
 
 
3328
                ent = __be16_to_cpu(vd->populated_vdes);
 
3329
                if (ent >= __be16_to_cpu(ddf->virt->max_vdes))
 
3330
                        return;
 
3331
                if (!all_ff(ddf->virt->entries[ent].guid))
 
3332
                        return;
 
3333
                ddf->virt->entries[ent] = vd->entries[0];
 
3334
                ddf->virt->populated_vdes = __cpu_to_be16(1 +
 
3335
                              __be16_to_cpu(ddf->virt->populated_vdes));
 
3336
                ddf->updates_pending = 1;
 
3337
                break;
 
3338
 
 
3339
        case DDF_VD_CONF_MAGIC:
 
3340
                dprintf("len %d %d\n", update->len, ddf->conf_rec_len);
 
3341
 
 
3342
                mppe = __be16_to_cpu(ddf->anchor.max_primary_element_entries);
 
3343
                if ((unsigned)update->len != ddf->conf_rec_len * 512)
 
3344
                        return;
 
3345
                vc = (struct vd_config*)update->buf;
 
3346
                for (vcl = ddf->conflist; vcl ; vcl = vcl->next)
 
3347
                        if (memcmp(vcl->conf.guid, vc->guid, DDF_GUID_LEN) == 0)
 
3348
                                break;
 
3349
                dprintf("vcl = %p\n", vcl);
 
3350
                if (vcl) {
 
3351
                        /* An update, just copy the phys_refnum and lba_offset
 
3352
                         * fields
 
3353
                         */
 
3354
                        memcpy(vcl->conf.phys_refnum, vc->phys_refnum,
 
3355
                               mppe * (sizeof(__u32) + sizeof(__u64)));
 
3356
                } else {
 
3357
                        /* A new VD_CONF */
 
3358
                        if (!update->space)
 
3359
                                return;
 
3360
                        vcl = update->space;
 
3361
                        update->space = NULL;
 
3362
                        vcl->next = ddf->conflist;
 
3363
                        memcpy(&vcl->conf, vc, update->len);
 
3364
                        vcl->lba_offset = (__u64*)
 
3365
                                &vcl->conf.phys_refnum[mppe];
 
3366
                        ddf->conflist = vcl;
 
3367
                }
 
3368
                /* Now make sure vlist is correct for each dl. */
 
3369
                for (dl = ddf->dlist; dl; dl = dl->next) {
 
3370
                        unsigned int dn;
 
3371
                        unsigned int vn = 0;
 
3372
                        for (vcl = ddf->conflist; vcl ; vcl = vcl->next)
 
3373
                                for (dn=0; dn < ddf->mppe ; dn++)
 
3374
                                        if (vcl->conf.phys_refnum[dn] ==
 
3375
                                            dl->disk.refnum) {
 
3376
                                                dprintf("dev %d has %p at %d\n",
 
3377
                                                        dl->pdnum, vcl, vn);
 
3378
                                                dl->vlist[vn++] = vcl;
 
3379
                                                break;
 
3380
                                        }
 
3381
                        while (vn < ddf->max_part)
 
3382
                                dl->vlist[vn++] = NULL;
 
3383
                        if (dl->vlist[0]) {
 
3384
                                ddf->phys->entries[dl->pdnum].type &=
 
3385
                                        ~__cpu_to_be16(DDF_Global_Spare);
 
3386
                                ddf->phys->entries[dl->pdnum].type |=
 
3387
                                        __cpu_to_be16(DDF_Active_in_VD);
 
3388
                        }
 
3389
                        if (dl->spare) {
 
3390
                                ddf->phys->entries[dl->pdnum].type &=
 
3391
                                        ~__cpu_to_be16(DDF_Global_Spare);
 
3392
                                ddf->phys->entries[dl->pdnum].type |=
 
3393
                                        __cpu_to_be16(DDF_Spare);
 
3394
                        }
 
3395
                        if (!dl->vlist[0] && !dl->spare) {
 
3396
                                ddf->phys->entries[dl->pdnum].type |=
 
3397
                                        __cpu_to_be16(DDF_Global_Spare);
 
3398
                                ddf->phys->entries[dl->pdnum].type &=
 
3399
                                        ~__cpu_to_be16(DDF_Spare |
 
3400
                                                       DDF_Active_in_VD);
 
3401
                        }
 
3402
                }
 
3403
                ddf->updates_pending = 1;
 
3404
                break;
 
3405
        case DDF_SPARE_ASSIGN_MAGIC:
 
3406
        default: break;
 
3407
        }
 
3408
}
 
3409
 
 
3410
static void ddf_prepare_update(struct supertype *st,
 
3411
                               struct metadata_update *update)
 
3412
{
 
3413
        /* This update arrived at managemon.
 
3414
         * We are about to pass it to monitor.
 
3415
         * If a malloc is needed, do it here.
 
3416
         */
 
3417
        struct ddf_super *ddf = st->sb;
 
3418
        __u32 *magic = (__u32*)update->buf;
 
3419
        if (*magic == DDF_VD_CONF_MAGIC)
 
3420
                if (posix_memalign(&update->space, 512,
 
3421
                               offsetof(struct vcl, conf)
 
3422
                               + ddf->conf_rec_len * 512) != 0)
 
3423
                        update->space = NULL;
 
3424
}
 
3425
 
 
3426
/*
 
3427
 * Check if the array 'a' is degraded but not failed.
 
3428
 * If it is, find as many spares as are available and needed and
 
3429
 * arrange for their inclusion.
 
3430
 * We only choose devices which are not already in the array,
 
3431
 * and prefer those with a spare-assignment to this array.
 
3432
 * otherwise we choose global spares - assuming always that
 
3433
 * there is enough room.
 
3434
 * For each spare that we assign, we return an 'mdinfo' which
 
3435
 * describes the position for the device in the array.
 
3436
 * We also add to 'updates' a DDF_VD_CONF_MAGIC update with
 
3437
 * the new phys_refnum and lba_offset values.
 
3438
 *
 
3439
 * Only worry about BVDs at the moment.
 
3440
 */
 
3441
static struct mdinfo *ddf_activate_spare(struct active_array *a,
 
3442
                                         struct metadata_update **updates)
 
3443
{
 
3444
        int working = 0;
 
3445
        struct mdinfo *d;
 
3446
        struct ddf_super *ddf = a->container->sb;
 
3447
        int global_ok = 0;
 
3448
        struct mdinfo *rv = NULL;
 
3449
        struct mdinfo *di;
 
3450
        struct metadata_update *mu;
 
3451
        struct dl *dl;
 
3452
        int i;
 
3453
        struct vd_config *vc;
 
3454
        __u64 *lba;
 
3455
 
 
3456
        for (d = a->info.devs ; d ; d = d->next) {
 
3457
                if ((d->curr_state & DS_FAULTY) &&
 
3458
                        d->state_fd >= 0)
 
3459
                        /* wait for Removal to happen */
 
3460
                        return NULL;
 
3461
                if (d->state_fd >= 0)
 
3462
                        working ++;
 
3463
        }
 
3464
 
 
3465
        dprintf("ddf_activate: working=%d (%d) level=%d\n", working, a->info.array.raid_disks,
 
3466
                a->info.array.level);
 
3467
        if (working == a->info.array.raid_disks)
 
3468
                return NULL; /* array not degraded */
 
3469
        switch (a->info.array.level) {
 
3470
        case 1:
 
3471
                if (working == 0)
 
3472
                        return NULL; /* failed */
 
3473
                break;
 
3474
        case 4:
 
3475
        case 5:
 
3476
                if (working < a->info.array.raid_disks - 1)
 
3477
                        return NULL; /* failed */
 
3478
                break;
 
3479
        case 6:
 
3480
                if (working < a->info.array.raid_disks - 2)
 
3481
                        return NULL; /* failed */
 
3482
                break;
 
3483
        default: /* concat or stripe */
 
3484
                return NULL; /* failed */
 
3485
        }
 
3486
 
 
3487
        /* For each slot, if it is not working, find a spare */
 
3488
        dl = ddf->dlist;
 
3489
        for (i = 0; i < a->info.array.raid_disks; i++) {
 
3490
                for (d = a->info.devs ; d ; d = d->next)
 
3491
                        if (d->disk.raid_disk == i)
 
3492
                                break;
 
3493
                dprintf("found %d: %p %x\n", i, d, d?d->curr_state:0);
 
3494
                if (d && (d->state_fd >= 0))
 
3495
                        continue;
 
3496
 
 
3497
                /* OK, this device needs recovery.  Find a spare */
 
3498
        again:
 
3499
                for ( ; dl ; dl = dl->next) {
 
3500
                        unsigned long long esize;
 
3501
                        unsigned long long pos;
 
3502
                        struct mdinfo *d2;
 
3503
                        int is_global = 0;
 
3504
                        int is_dedicated = 0;
 
3505
                        struct extent *ex;
 
3506
                        unsigned int j;
 
3507
                        /* If in this array, skip */
 
3508
                        for (d2 = a->info.devs ; d2 ; d2 = d2->next)
 
3509
                                if (d2->disk.major == dl->major &&
 
3510
                                    d2->disk.minor == dl->minor) {
 
3511
                                        dprintf("%x:%x already in array\n", dl->major, dl->minor);
 
3512
                                        break;
 
3513
                                }
 
3514
                        if (d2)
 
3515
                                continue;
 
3516
                        if (ddf->phys->entries[dl->pdnum].type &
 
3517
                            __cpu_to_be16(DDF_Spare)) {
 
3518
                                /* Check spare assign record */
 
3519
                                if (dl->spare) {
 
3520
                                        if (dl->spare->type & DDF_spare_dedicated) {
 
3521
                                                /* check spare_ents for guid */
 
3522
                                                for (j = 0 ;
 
3523
                                                     j < __be16_to_cpu(dl->spare->populated);
 
3524
                                                     j++) {
 
3525
                                                        if (memcmp(dl->spare->spare_ents[j].guid,
 
3526
                                                                   ddf->virt->entries[a->info.container_member].guid,
 
3527
                                                                   DDF_GUID_LEN) == 0)
 
3528
                                                                is_dedicated = 1;
 
3529
                                                }
 
3530
                                        } else
 
3531
                                                is_global = 1;
 
3532
                                }
 
3533
                        } else if (ddf->phys->entries[dl->pdnum].type &
 
3534
                                   __cpu_to_be16(DDF_Global_Spare)) {
 
3535
                                is_global = 1;
 
3536
                        }
 
3537
                        if ( ! (is_dedicated ||
 
3538
                                (is_global && global_ok))) {
 
3539
                                dprintf("%x:%x not suitable: %d %d\n", dl->major, dl->minor,
 
3540
                                       is_dedicated, is_global);
 
3541
                                continue;
 
3542
                        }
 
3543
 
 
3544
                        /* We are allowed to use this device - is there space?
 
3545
                         * We need a->info.component_size sectors */
 
3546
                        ex = get_extents(ddf, dl);
 
3547
                        if (!ex) {
 
3548
                                dprintf("cannot get extents\n");
 
3549
                                continue;
 
3550
                        }
 
3551
                        j = 0; pos = 0;
 
3552
                        esize = 0;
 
3553
 
 
3554
                        do {
 
3555
                                esize = ex[j].start - pos;
 
3556
                                if (esize >= a->info.component_size)
 
3557
                                        break;
 
3558
                                pos = ex[i].start + ex[i].size;
 
3559
                                i++;
 
3560
                        } while (ex[i-1].size);
 
3561
 
 
3562
                        free(ex);
 
3563
                        if (esize < a->info.component_size) {
 
3564
                                dprintf("%x:%x has no room: %llu %llu\n", dl->major, dl->minor,
 
3565
                                        esize, a->info.component_size);
 
3566
                                /* No room */
 
3567
                                continue;
 
3568
                        }
 
3569
 
 
3570
                        /* Cool, we have a device with some space at pos */
 
3571
                        di = malloc(sizeof(*di));
 
3572
                        if (!di)
 
3573
                                continue;
 
3574
                        memset(di, 0, sizeof(*di));
 
3575
                        di->disk.number = i;
 
3576
                        di->disk.raid_disk = i;
 
3577
                        di->disk.major = dl->major;
 
3578
                        di->disk.minor = dl->minor;
 
3579
                        di->disk.state = 0;
 
3580
                        di->recovery_start = 0;
 
3581
                        di->data_offset = pos;
 
3582
                        di->component_size = a->info.component_size;
 
3583
                        di->container_member = dl->pdnum;
 
3584
                        di->next = rv;
 
3585
                        rv = di;
 
3586
                        dprintf("%x:%x to be %d at %llu\n", dl->major, dl->minor,
 
3587
                                i, pos);
 
3588
 
 
3589
                        break;
 
3590
                }
 
3591
                if (!dl && ! global_ok) {
 
3592
                        /* not enough dedicated spares, try global */
 
3593
                        global_ok = 1;
 
3594
                        dl = ddf->dlist;
 
3595
                        goto again;
 
3596
                }
 
3597
        }
 
3598
 
 
3599
        if (!rv)
 
3600
                /* No spares found */
 
3601
                return rv;
 
3602
        /* Now 'rv' has a list of devices to return.
 
3603
         * Create a metadata_update record to update the
 
3604
         * phys_refnum and lba_offset values
 
3605
         */
 
3606
        mu = malloc(sizeof(*mu));
 
3607
        if (mu && posix_memalign(&mu->space, 512, sizeof(struct vcl)) != 0) {
 
3608
                free(mu);
 
3609
                mu = NULL;
 
3610
        }
 
3611
        if (!mu) {
 
3612
                while (rv) {
 
3613
                        struct mdinfo *n = rv->next;
 
3614
 
 
3615
                        free(rv);
 
3616
                        rv = n;
 
3617
                }
 
3618
                return NULL;
 
3619
        }
 
3620
                
 
3621
        mu->buf = malloc(ddf->conf_rec_len * 512);
 
3622
        mu->len = ddf->conf_rec_len;
 
3623
        mu->next = *updates;
 
3624
        vc = find_vdcr(ddf, a->info.container_member);
 
3625
        memcpy(mu->buf, vc, ddf->conf_rec_len * 512);
 
3626
 
 
3627
        vc = (struct vd_config*)mu->buf;
 
3628
        lba = (__u64*)&vc->phys_refnum[ddf->mppe];
 
3629
        for (di = rv ; di ; di = di->next) {
 
3630
                vc->phys_refnum[di->disk.raid_disk] =
 
3631
                        ddf->phys->entries[dl->pdnum].refnum;
 
3632
                lba[di->disk.raid_disk] = di->data_offset;
 
3633
        }
 
3634
        *updates = mu;
 
3635
        return rv;
 
3636
}
 
3637
#endif /* MDASSEMBLE */
 
3638
 
 
3639
static int ddf_level_to_layout(int level)
 
3640
{
 
3641
        switch(level) {
 
3642
        case 0:
 
3643
        case 1:
 
3644
                return 0;
 
3645
        case 5:
 
3646
                return ALGORITHM_LEFT_SYMMETRIC;
 
3647
        case 6:
 
3648
                return ALGORITHM_ROTATING_N_CONTINUE;
 
3649
        case 10:
 
3650
                return 0x102;
 
3651
        default:
 
3652
                return UnSet;
 
3653
        }
 
3654
}
 
3655
 
 
3656
struct superswitch super_ddf = {
 
3657
#ifndef MDASSEMBLE
 
3658
        .examine_super  = examine_super_ddf,
 
3659
        .brief_examine_super = brief_examine_super_ddf,
 
3660
        .brief_examine_subarrays = brief_examine_subarrays_ddf,
 
3661
        .export_examine_super = export_examine_super_ddf,
 
3662
        .detail_super   = detail_super_ddf,
 
3663
        .brief_detail_super = brief_detail_super_ddf,
 
3664
        .validate_geometry = validate_geometry_ddf,
 
3665
        .write_init_super = write_init_super_ddf,
 
3666
        .add_to_super   = add_to_super_ddf,
 
3667
#endif
 
3668
        .match_home     = match_home_ddf,
 
3669
        .uuid_from_super= uuid_from_super_ddf,
 
3670
        .getinfo_super  = getinfo_super_ddf,
 
3671
        .update_super   = update_super_ddf,
 
3672
 
 
3673
        .avail_size     = avail_size_ddf,
 
3674
 
 
3675
        .compare_super  = compare_super_ddf,
 
3676
 
 
3677
        .load_super     = load_super_ddf,
 
3678
        .init_super     = init_super_ddf,
 
3679
        .store_super    = store_super_ddf,
 
3680
        .free_super     = free_super_ddf,
 
3681
        .match_metadata_desc = match_metadata_desc_ddf,
 
3682
        .container_content = container_content_ddf,
 
3683
        .default_layout = ddf_level_to_layout,
 
3684
 
 
3685
        .external       = 1,
 
3686
 
 
3687
#ifndef MDASSEMBLE
 
3688
/* for mdmon */
 
3689
        .open_new       = ddf_open_new,
 
3690
        .set_array_state= ddf_set_array_state,
 
3691
        .set_disk       = ddf_set_disk,
 
3692
        .sync_metadata  = ddf_sync_metadata,
 
3693
        .process_update = ddf_process_update,
 
3694
        .prepare_update = ddf_prepare_update,
 
3695
        .activate_spare = ddf_activate_spare,
 
3696
#endif
 
3697
        .name = "ddf",
 
3698
};