]> git.ipfire.org Git - thirdparty/mdadm.git/blame - super-intel.c
getinfo_super now clears the 'info' structure before filling it in.
[thirdparty/mdadm.git] / super-intel.c
CommitLineData
cdddbdbc
DW
1/*
2 * mdadm - Intel(R) Matrix Storage Manager Support
3 *
a54d5262 4 * Copyright (C) 2002-2008 Intel Corporation
cdddbdbc
DW
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
51006d85 20#define HAVE_STDINT_H 1
cdddbdbc 21#include "mdadm.h"
c2a1e7da 22#include "mdmon.h"
51006d85 23#include "sha1.h"
88c32bb1 24#include "platform-intel.h"
cdddbdbc
DW
25#include <values.h>
26#include <scsi/sg.h>
27#include <ctype.h>
d665cc31 28#include <dirent.h>
cdddbdbc
DW
29
30/* MPB == Metadata Parameter Block */
31#define MPB_SIGNATURE "Intel Raid ISM Cfg Sig. "
32#define MPB_SIG_LEN (strlen(MPB_SIGNATURE))
33#define MPB_VERSION_RAID0 "1.0.00"
34#define MPB_VERSION_RAID1 "1.1.00"
fe7ed8cb
DW
35#define MPB_VERSION_MANY_VOLUMES_PER_ARRAY "1.2.00"
36#define MPB_VERSION_3OR4_DISK_ARRAY "1.2.01"
cdddbdbc 37#define MPB_VERSION_RAID5 "1.2.02"
fe7ed8cb
DW
38#define MPB_VERSION_5OR6_DISK_ARRAY "1.2.04"
39#define MPB_VERSION_CNG "1.2.06"
40#define MPB_VERSION_ATTRIBS "1.3.00"
cdddbdbc
DW
41#define MAX_SIGNATURE_LENGTH 32
42#define MAX_RAID_SERIAL_LEN 16
fe7ed8cb
DW
43
44#define MPB_ATTRIB_CHECKSUM_VERIFY __cpu_to_le32(0x80000000)
45#define MPB_ATTRIB_PM __cpu_to_le32(0x40000000)
46#define MPB_ATTRIB_2TB __cpu_to_le32(0x20000000)
47#define MPB_ATTRIB_RAID0 __cpu_to_le32(0x00000001)
48#define MPB_ATTRIB_RAID1 __cpu_to_le32(0x00000002)
49#define MPB_ATTRIB_RAID10 __cpu_to_le32(0x00000004)
50#define MPB_ATTRIB_RAID1E __cpu_to_le32(0x00000008)
51#define MPB_ATTRIB_RAID5 __cpu_to_le32(0x00000010)
52#define MPB_ATTRIB_RAIDCNG __cpu_to_le32(0x00000020)
53
c2c087e6
DW
54#define MPB_SECTOR_CNT 418
55#define IMSM_RESERVED_SECTORS 4096
979d38be 56#define SECT_PER_MB_SHIFT 11
cdddbdbc
DW
57
58/* Disk configuration info. */
59#define IMSM_MAX_DEVICES 255
60struct imsm_disk {
61 __u8 serial[MAX_RAID_SERIAL_LEN];/* 0xD8 - 0xE7 ascii serial number */
62 __u32 total_blocks; /* 0xE8 - 0xEB total blocks */
63 __u32 scsi_id; /* 0xEC - 0xEF scsi ID */
f2f27e63
DW
64#define SPARE_DISK __cpu_to_le32(0x01) /* Spare */
65#define CONFIGURED_DISK __cpu_to_le32(0x02) /* Member of some RaidDev */
66#define FAILED_DISK __cpu_to_le32(0x04) /* Permanent failure */
cdddbdbc 67 __u32 status; /* 0xF0 - 0xF3 */
fe7ed8cb
DW
68 __u32 owner_cfg_num; /* which config 0,1,2... owns this disk */
69#define IMSM_DISK_FILLERS 4
cdddbdbc
DW
70 __u32 filler[IMSM_DISK_FILLERS]; /* 0xF4 - 0x107 MPB_DISK_FILLERS for future expansion */
71};
72
73/* RAID map configuration infos. */
74struct imsm_map {
75 __u32 pba_of_lba0; /* start address of partition */
76 __u32 blocks_per_member;/* blocks per member */
77 __u32 num_data_stripes; /* number of data stripes */
78 __u16 blocks_per_strip;
79 __u8 map_state; /* Normal, Uninitialized, Degraded, Failed */
80#define IMSM_T_STATE_NORMAL 0
81#define IMSM_T_STATE_UNINITIALIZED 1
e3bba0e0
DW
82#define IMSM_T_STATE_DEGRADED 2
83#define IMSM_T_STATE_FAILED 3
cdddbdbc
DW
84 __u8 raid_level;
85#define IMSM_T_RAID0 0
86#define IMSM_T_RAID1 1
87#define IMSM_T_RAID5 5 /* since metadata version 1.2.02 ? */
88 __u8 num_members; /* number of member disks */
fe7ed8cb
DW
89 __u8 num_domains; /* number of parity domains */
90 __u8 failed_disk_num; /* valid only when state is degraded */
252d23c0 91 __u8 ddf;
cdddbdbc 92 __u32 filler[7]; /* expansion area */
7eef0453 93#define IMSM_ORD_REBUILD (1 << 24)
cdddbdbc 94 __u32 disk_ord_tbl[1]; /* disk_ord_tbl[num_members],
7eef0453
DW
95 * top byte contains some flags
96 */
cdddbdbc
DW
97} __attribute__ ((packed));
98
99struct imsm_vol {
f8f603f1 100 __u32 curr_migr_unit;
fe7ed8cb 101 __u32 checkpoint_id; /* id to access curr_migr_unit */
cdddbdbc 102 __u8 migr_state; /* Normal or Migrating */
e3bba0e0
DW
103#define MIGR_INIT 0
104#define MIGR_REBUILD 1
105#define MIGR_VERIFY 2 /* analagous to echo check > sync_action */
106#define MIGR_GEN_MIGR 3
107#define MIGR_STATE_CHANGE 4
1484e727 108#define MIGR_REPAIR 5
cdddbdbc
DW
109 __u8 migr_type; /* Initializing, Rebuilding, ... */
110 __u8 dirty;
fe7ed8cb
DW
111 __u8 fs_state; /* fast-sync state for CnG (0xff == disabled) */
112 __u16 verify_errors; /* number of mismatches */
113 __u16 bad_blocks; /* number of bad blocks during verify */
114 __u32 filler[4];
cdddbdbc
DW
115 struct imsm_map map[1];
116 /* here comes another one if migr_state */
117} __attribute__ ((packed));
118
119struct imsm_dev {
fe7ed8cb 120 __u8 volume[MAX_RAID_SERIAL_LEN];
cdddbdbc
DW
121 __u32 size_low;
122 __u32 size_high;
fe7ed8cb
DW
123#define DEV_BOOTABLE __cpu_to_le32(0x01)
124#define DEV_BOOT_DEVICE __cpu_to_le32(0x02)
125#define DEV_READ_COALESCING __cpu_to_le32(0x04)
126#define DEV_WRITE_COALESCING __cpu_to_le32(0x08)
127#define DEV_LAST_SHUTDOWN_DIRTY __cpu_to_le32(0x10)
128#define DEV_HIDDEN_AT_BOOT __cpu_to_le32(0x20)
129#define DEV_CURRENTLY_HIDDEN __cpu_to_le32(0x40)
130#define DEV_VERIFY_AND_FIX __cpu_to_le32(0x80)
131#define DEV_MAP_STATE_UNINIT __cpu_to_le32(0x100)
132#define DEV_NO_AUTO_RECOVERY __cpu_to_le32(0x200)
133#define DEV_CLONE_N_GO __cpu_to_le32(0x400)
134#define DEV_CLONE_MAN_SYNC __cpu_to_le32(0x800)
135#define DEV_CNG_MASTER_DISK_NUM __cpu_to_le32(0x1000)
cdddbdbc
DW
136 __u32 status; /* Persistent RaidDev status */
137 __u32 reserved_blocks; /* Reserved blocks at beginning of volume */
fe7ed8cb
DW
138 __u8 migr_priority;
139 __u8 num_sub_vols;
140 __u8 tid;
141 __u8 cng_master_disk;
142 __u16 cache_policy;
143 __u8 cng_state;
144 __u8 cng_sub_state;
145#define IMSM_DEV_FILLERS 10
cdddbdbc
DW
146 __u32 filler[IMSM_DEV_FILLERS];
147 struct imsm_vol vol;
148} __attribute__ ((packed));
149
150struct imsm_super {
151 __u8 sig[MAX_SIGNATURE_LENGTH]; /* 0x00 - 0x1F */
152 __u32 check_sum; /* 0x20 - 0x23 MPB Checksum */
153 __u32 mpb_size; /* 0x24 - 0x27 Size of MPB */
154 __u32 family_num; /* 0x28 - 0x2B Checksum from first time this config was written */
155 __u32 generation_num; /* 0x2C - 0x2F Incremented each time this array's MPB is written */
604b746f
JD
156 __u32 error_log_size; /* 0x30 - 0x33 in bytes */
157 __u32 attributes; /* 0x34 - 0x37 */
cdddbdbc
DW
158 __u8 num_disks; /* 0x38 Number of configured disks */
159 __u8 num_raid_devs; /* 0x39 Number of configured volumes */
604b746f
JD
160 __u8 error_log_pos; /* 0x3A */
161 __u8 fill[1]; /* 0x3B */
162 __u32 cache_size; /* 0x3c - 0x40 in mb */
163 __u32 orig_family_num; /* 0x40 - 0x43 original family num */
164 __u32 pwr_cycle_count; /* 0x44 - 0x47 simulated power cycle count for array */
165 __u32 bbm_log_size; /* 0x48 - 0x4B - size of bad Block Mgmt Log in bytes */
166#define IMSM_FILLERS 35
167 __u32 filler[IMSM_FILLERS]; /* 0x4C - 0xD7 RAID_MPB_FILLERS */
cdddbdbc
DW
168 struct imsm_disk disk[1]; /* 0xD8 diskTbl[numDisks] */
169 /* here comes imsm_dev[num_raid_devs] */
604b746f 170 /* here comes BBM logs */
cdddbdbc
DW
171} __attribute__ ((packed));
172
604b746f
JD
173#define BBM_LOG_MAX_ENTRIES 254
174
175struct bbm_log_entry {
176 __u64 defective_block_start;
177#define UNREADABLE 0xFFFFFFFF
178 __u32 spare_block_offset;
179 __u16 remapped_marked_count;
180 __u16 disk_ordinal;
181} __attribute__ ((__packed__));
182
183struct bbm_log {
184 __u32 signature; /* 0xABADB10C */
185 __u32 entry_count;
186 __u32 reserved_spare_block_count; /* 0 */
187 __u32 reserved; /* 0xFFFF */
188 __u64 first_spare_lba;
189 struct bbm_log_entry mapped_block_entries[BBM_LOG_MAX_ENTRIES];
190} __attribute__ ((__packed__));
191
192
cdddbdbc
DW
193#ifndef MDASSEMBLE
194static char *map_state_str[] = { "normal", "uninitialized", "degraded", "failed" };
195#endif
196
1484e727
DW
197static __u8 migr_type(struct imsm_dev *dev)
198{
199 if (dev->vol.migr_type == MIGR_VERIFY &&
200 dev->status & DEV_VERIFY_AND_FIX)
201 return MIGR_REPAIR;
202 else
203 return dev->vol.migr_type;
204}
205
206static void set_migr_type(struct imsm_dev *dev, __u8 migr_type)
207{
208 /* for compatibility with older oroms convert MIGR_REPAIR, into
209 * MIGR_VERIFY w/ DEV_VERIFY_AND_FIX status
210 */
211 if (migr_type == MIGR_REPAIR) {
212 dev->vol.migr_type = MIGR_VERIFY;
213 dev->status |= DEV_VERIFY_AND_FIX;
214 } else {
215 dev->vol.migr_type = migr_type;
216 dev->status &= ~DEV_VERIFY_AND_FIX;
217 }
218}
219
87eb16df 220static unsigned int sector_count(__u32 bytes)
cdddbdbc 221{
87eb16df
DW
222 return ((bytes + (512-1)) & (~(512-1))) / 512;
223}
cdddbdbc 224
87eb16df
DW
225static unsigned int mpb_sectors(struct imsm_super *mpb)
226{
227 return sector_count(__le32_to_cpu(mpb->mpb_size));
cdddbdbc
DW
228}
229
ba2de7ba
DW
230struct intel_dev {
231 struct imsm_dev *dev;
232 struct intel_dev *next;
f21e18ca 233 unsigned index;
ba2de7ba
DW
234};
235
88654014
LM
236struct intel_hba {
237 enum sys_dev_type type;
238 char *path;
239 char *pci_id;
240 struct intel_hba *next;
241};
242
1a64be56
LM
243enum action {
244 DISK_REMOVE = 1,
245 DISK_ADD
246};
cdddbdbc
DW
247/* internal representation of IMSM metadata */
248struct intel_super {
249 union {
949c47a0
DW
250 void *buf; /* O_DIRECT buffer for reading/writing metadata */
251 struct imsm_super *anchor; /* immovable parameters */
cdddbdbc 252 };
949c47a0 253 size_t len; /* size of the 'buf' allocation */
4d7b1503
DW
254 void *next_buf; /* for realloc'ing buf from the manager */
255 size_t next_len;
c2c087e6 256 int updates_pending; /* count of pending updates for mdmon */
bf5a934a 257 int current_vol; /* index of raid device undergoing creation */
0dcecb2e 258 __u32 create_offset; /* common start for 'current_vol' */
148acb7b 259 __u32 random; /* random data for seeding new family numbers */
ba2de7ba 260 struct intel_dev *devlist;
cdddbdbc
DW
261 struct dl {
262 struct dl *next;
263 int index;
264 __u8 serial[MAX_RAID_SERIAL_LEN];
265 int major, minor;
266 char *devname;
b9f594fe 267 struct imsm_disk disk;
cdddbdbc 268 int fd;
0dcecb2e
DW
269 int extent_cnt;
270 struct extent *e; /* for determining freespace @ create */
efb30e7f 271 int raiddisk; /* slot to fill in autolayout */
1a64be56 272 enum action action;
cdddbdbc 273 } *disks;
1a64be56
LM
274 struct dl *disk_mgmt_list; /* list of disks to add/remove while mdmon
275 active */
47ee5a45 276 struct dl *missing; /* disks removed while we weren't looking */
43dad3d6 277 struct bbm_log *bbm_log;
88654014 278 struct intel_hba *hba; /* device path of the raid controller for this metadata */
88c32bb1 279 const struct imsm_orom *orom; /* platform firmware support */
a2b97981
DW
280 struct intel_super *next; /* (temp) list for disambiguating family_num */
281};
282
283struct intel_disk {
284 struct imsm_disk disk;
285 #define IMSM_UNKNOWN_OWNER (-1)
286 int owner;
287 struct intel_disk *next;
cdddbdbc
DW
288};
289
c2c087e6
DW
290struct extent {
291 unsigned long long start, size;
292};
293
694575e7
KW
294/* definitions of reshape process types */
295enum imsm_reshape_type {
296 CH_TAKEOVER,
b5347799 297 CH_MIGRATION,
694575e7
KW
298};
299
88758e9d
DW
300/* definition of messages passed to imsm_process_update */
301enum imsm_update_type {
302 update_activate_spare,
8273f55e 303 update_create_array,
33414a01 304 update_kill_array,
aa534678 305 update_rename_array,
1a64be56 306 update_add_remove_disk,
78b10e66 307 update_reshape_container_disks,
48c5303a 308 update_reshape_migration,
bb025c2f 309 update_takeover
88758e9d
DW
310};
311
312struct imsm_update_activate_spare {
313 enum imsm_update_type type;
d23fe947 314 struct dl *dl;
88758e9d
DW
315 int slot;
316 int array;
317 struct imsm_update_activate_spare *next;
318};
319
78b10e66
N
320struct geo_params {
321 int dev_id;
322 char *dev_name;
323 long long size;
324 int level;
325 int layout;
326 int chunksize;
327 int raid_disks;
328};
329
bb025c2f
KW
330enum takeover_direction {
331 R10_TO_R0,
332 R0_TO_R10
333};
334struct imsm_update_takeover {
335 enum imsm_update_type type;
336 int subarray;
337 enum takeover_direction direction;
338};
78b10e66
N
339
340struct imsm_update_reshape {
341 enum imsm_update_type type;
342 int old_raid_disks;
343 int new_raid_disks;
48c5303a
PC
344
345 int new_disks[1]; /* new_raid_disks - old_raid_disks makedev number */
346};
347
348struct imsm_update_reshape_migration {
349 enum imsm_update_type type;
350 int old_raid_disks;
351 int new_raid_disks;
352 /* fields for array migration changes
353 */
354 int subdev;
355 int new_level;
356 int new_layout;
4bba0439 357 int new_chunksize;
48c5303a 358
d195167d 359 int new_disks[1]; /* new_raid_disks - old_raid_disks makedev number */
78b10e66
N
360};
361
54c2c1ea
DW
362struct disk_info {
363 __u8 serial[MAX_RAID_SERIAL_LEN];
364};
365
8273f55e
DW
366struct imsm_update_create_array {
367 enum imsm_update_type type;
8273f55e 368 int dev_idx;
6a3e913e 369 struct imsm_dev dev;
8273f55e
DW
370};
371
33414a01
DW
372struct imsm_update_kill_array {
373 enum imsm_update_type type;
374 int dev_idx;
375};
376
aa534678
DW
377struct imsm_update_rename_array {
378 enum imsm_update_type type;
379 __u8 name[MAX_RAID_SERIAL_LEN];
380 int dev_idx;
381};
382
1a64be56 383struct imsm_update_add_remove_disk {
43dad3d6
DW
384 enum imsm_update_type type;
385};
386
88654014
LM
387
388static const char *_sys_dev_type[] = {
389 [SYS_DEV_UNKNOWN] = "Unknown",
390 [SYS_DEV_SAS] = "SAS",
391 [SYS_DEV_SATA] = "SATA"
392};
393
394const char *get_sys_dev_type(enum sys_dev_type type)
395{
396 if (type >= SYS_DEV_MAX)
397 type = SYS_DEV_UNKNOWN;
398
399 return _sys_dev_type[type];
400}
401
402static struct intel_hba * alloc_intel_hba(struct sys_dev *device)
403{
404 struct intel_hba *result = malloc(sizeof(*result));
405 if (result) {
406 result->type = device->type;
407 result->path = strdup(device->path);
408 result->next = NULL;
409 if (result->path && (result->pci_id = strrchr(result->path, '/')) != NULL)
410 result->pci_id++;
411 }
412 return result;
413}
414
415static struct intel_hba * find_intel_hba(struct intel_hba *hba, struct sys_dev *device)
416{
417 struct intel_hba *result=NULL;
418 for (result = hba; result; result = result->next) {
419 if (result->type == device->type && strcmp(result->path, device->path) == 0)
420 break;
421 }
422 return result;
423}
424
b4cf4cba 425static int attach_hba_to_super(struct intel_super *super, struct sys_dev *device)
88654014
LM
426{
427 struct intel_hba *hba;
428
429 /* check if disk attached to Intel HBA */
430 hba = find_intel_hba(super->hba, device);
431 if (hba != NULL)
432 return 1;
433 /* Check if HBA is already attached to super */
434 if (super->hba == NULL) {
435 super->hba = alloc_intel_hba(device);
436 return 1;
437 }
438
439 hba = super->hba;
440 /* Intel metadata allows for all disks attached to the same type HBA.
441 * Do not sypport odf HBA types mixing
442 */
443 if (device->type != hba->type)
444 return 2;
445
446 while (hba->next)
447 hba = hba->next;
448
449 hba->next = alloc_intel_hba(device);
450 return 1;
451}
452
453static struct sys_dev* find_disk_attached_hba(int fd, const char *devname)
454{
455 struct sys_dev *list, *elem, *prev;
456 char *disk_path;
457
458 if ((list = find_intel_devices()) == NULL)
459 return 0;
460
461 if (fd < 0)
462 disk_path = (char *) devname;
463 else
464 disk_path = diskfd_to_devpath(fd);
465
466 if (!disk_path) {
467 free_sys_dev(&list);
468 return 0;
469 }
470
471 for (prev = NULL, elem = list; elem; prev = elem, elem = elem->next) {
472 if (path_attached_to_hba(disk_path, elem->path)) {
473 if (prev == NULL)
474 list = list->next;
475 else
476 prev->next = elem->next;
477 elem->next = NULL;
478 if (disk_path != devname)
479 free(disk_path);
480 free_sys_dev(&list);
481 return elem;
482 }
483 }
484 if (disk_path != devname)
485 free(disk_path);
486 free_sys_dev(&list);
487
488 return NULL;
489}
490
491
d424212e
N
492static int find_intel_hba_capability(int fd, struct intel_super *super,
493 char *devname);
f2f5c343 494
cdddbdbc
DW
495static struct supertype *match_metadata_desc_imsm(char *arg)
496{
497 struct supertype *st;
498
499 if (strcmp(arg, "imsm") != 0 &&
500 strcmp(arg, "default") != 0
501 )
502 return NULL;
503
504 st = malloc(sizeof(*st));
4e9d2186
AW
505 if (!st)
506 return NULL;
ef609477 507 memset(st, 0, sizeof(*st));
d1d599ea 508 st->container_dev = NoMdDev;
cdddbdbc
DW
509 st->ss = &super_imsm;
510 st->max_devs = IMSM_MAX_DEVICES;
511 st->minor_version = 0;
512 st->sb = NULL;
513 return st;
514}
515
0e600426 516#ifndef MDASSEMBLE
cdddbdbc
DW
517static __u8 *get_imsm_version(struct imsm_super *mpb)
518{
519 return &mpb->sig[MPB_SIG_LEN];
520}
0e600426 521#endif
cdddbdbc 522
949c47a0
DW
523/* retrieve a disk directly from the anchor when the anchor is known to be
524 * up-to-date, currently only at load time
525 */
526static struct imsm_disk *__get_imsm_disk(struct imsm_super *mpb, __u8 index)
cdddbdbc 527{
949c47a0 528 if (index >= mpb->num_disks)
cdddbdbc
DW
529 return NULL;
530 return &mpb->disk[index];
531}
532
95d07a2c
LM
533/* retrieve the disk description based on a index of the disk
534 * in the sub-array
535 */
536static struct dl *get_imsm_dl_disk(struct intel_super *super, __u8 index)
949c47a0 537{
b9f594fe
DW
538 struct dl *d;
539
540 for (d = super->disks; d; d = d->next)
541 if (d->index == index)
95d07a2c
LM
542 return d;
543
544 return NULL;
545}
546/* retrieve a disk from the parsed metadata */
547static struct imsm_disk *get_imsm_disk(struct intel_super *super, __u8 index)
548{
549 struct dl *dl;
550
551 dl = get_imsm_dl_disk(super, index);
552 if (dl)
553 return &dl->disk;
554
b9f594fe 555 return NULL;
949c47a0
DW
556}
557
558/* generate a checksum directly from the anchor when the anchor is known to be
559 * up-to-date, currently only at load or write_super after coalescing
560 */
561static __u32 __gen_imsm_checksum(struct imsm_super *mpb)
cdddbdbc
DW
562{
563 __u32 end = mpb->mpb_size / sizeof(end);
564 __u32 *p = (__u32 *) mpb;
565 __u32 sum = 0;
566
97f734fd
N
567 while (end--) {
568 sum += __le32_to_cpu(*p);
569 p++;
570 }
cdddbdbc
DW
571
572 return sum - __le32_to_cpu(mpb->check_sum);
573}
574
a965f303
DW
575static size_t sizeof_imsm_map(struct imsm_map *map)
576{
577 return sizeof(struct imsm_map) + sizeof(__u32) * (map->num_members - 1);
578}
579
580struct imsm_map *get_imsm_map(struct imsm_dev *dev, int second_map)
cdddbdbc 581{
5e7b0330
AK
582 /* A device can have 2 maps if it is in the middle of a migration.
583 * If second_map is:
584 * 0 - we return the first map
585 * 1 - we return the second map if it exists, else NULL
586 * -1 - we return the second map if it exists, else the first
587 */
a965f303
DW
588 struct imsm_map *map = &dev->vol.map[0];
589
5e7b0330 590 if (second_map == 1 && !dev->vol.migr_state)
a965f303 591 return NULL;
5e7b0330
AK
592 else if (second_map == 1 ||
593 (second_map < 0 && dev->vol.migr_state)) {
a965f303
DW
594 void *ptr = map;
595
596 return ptr + sizeof_imsm_map(map);
597 } else
598 return map;
5e7b0330 599
a965f303 600}
cdddbdbc 601
3393c6af
DW
602/* return the size of the device.
603 * migr_state increases the returned size if map[0] were to be duplicated
604 */
605static size_t sizeof_imsm_dev(struct imsm_dev *dev, int migr_state)
a965f303
DW
606{
607 size_t size = sizeof(*dev) - sizeof(struct imsm_map) +
608 sizeof_imsm_map(get_imsm_map(dev, 0));
cdddbdbc
DW
609
610 /* migrating means an additional map */
a965f303
DW
611 if (dev->vol.migr_state)
612 size += sizeof_imsm_map(get_imsm_map(dev, 1));
3393c6af
DW
613 else if (migr_state)
614 size += sizeof_imsm_map(get_imsm_map(dev, 0));
cdddbdbc
DW
615
616 return size;
617}
618
54c2c1ea
DW
619#ifndef MDASSEMBLE
620/* retrieve disk serial number list from a metadata update */
621static struct disk_info *get_disk_info(struct imsm_update_create_array *update)
622{
623 void *u = update;
624 struct disk_info *inf;
625
626 inf = u + sizeof(*update) - sizeof(struct imsm_dev) +
627 sizeof_imsm_dev(&update->dev, 0);
628
629 return inf;
630}
631#endif
632
949c47a0 633static struct imsm_dev *__get_imsm_dev(struct imsm_super *mpb, __u8 index)
cdddbdbc
DW
634{
635 int offset;
636 int i;
637 void *_mpb = mpb;
638
949c47a0 639 if (index >= mpb->num_raid_devs)
cdddbdbc
DW
640 return NULL;
641
642 /* devices start after all disks */
643 offset = ((void *) &mpb->disk[mpb->num_disks]) - _mpb;
644
645 for (i = 0; i <= index; i++)
646 if (i == index)
647 return _mpb + offset;
648 else
3393c6af 649 offset += sizeof_imsm_dev(_mpb + offset, 0);
cdddbdbc
DW
650
651 return NULL;
652}
653
949c47a0
DW
654static struct imsm_dev *get_imsm_dev(struct intel_super *super, __u8 index)
655{
ba2de7ba
DW
656 struct intel_dev *dv;
657
949c47a0
DW
658 if (index >= super->anchor->num_raid_devs)
659 return NULL;
ba2de7ba
DW
660 for (dv = super->devlist; dv; dv = dv->next)
661 if (dv->index == index)
662 return dv->dev;
663 return NULL;
949c47a0
DW
664}
665
98130f40
AK
666/*
667 * for second_map:
668 * == 0 get first map
669 * == 1 get second map
670 * == -1 than get map according to the current migr_state
671 */
672static __u32 get_imsm_ord_tbl_ent(struct imsm_dev *dev,
673 int slot,
674 int second_map)
7eef0453
DW
675{
676 struct imsm_map *map;
677
5e7b0330 678 map = get_imsm_map(dev, second_map);
7eef0453 679
ff077194
DW
680 /* top byte identifies disk under rebuild */
681 return __le32_to_cpu(map->disk_ord_tbl[slot]);
682}
683
684#define ord_to_idx(ord) (((ord) << 8) >> 8)
98130f40 685static __u32 get_imsm_disk_idx(struct imsm_dev *dev, int slot, int second_map)
ff077194 686{
98130f40 687 __u32 ord = get_imsm_ord_tbl_ent(dev, slot, second_map);
ff077194
DW
688
689 return ord_to_idx(ord);
7eef0453
DW
690}
691
be73972f
DW
692static void set_imsm_ord_tbl_ent(struct imsm_map *map, int slot, __u32 ord)
693{
694 map->disk_ord_tbl[slot] = __cpu_to_le32(ord);
695}
696
f21e18ca 697static int get_imsm_disk_slot(struct imsm_map *map, unsigned idx)
620b1713
DW
698{
699 int slot;
700 __u32 ord;
701
702 for (slot = 0; slot < map->num_members; slot++) {
703 ord = __le32_to_cpu(map->disk_ord_tbl[slot]);
704 if (ord_to_idx(ord) == idx)
705 return slot;
706 }
707
708 return -1;
709}
710
cdddbdbc
DW
711static int get_imsm_raid_level(struct imsm_map *map)
712{
713 if (map->raid_level == 1) {
714 if (map->num_members == 2)
715 return 1;
716 else
717 return 10;
718 }
719
720 return map->raid_level;
721}
722
c2c087e6
DW
723static int cmp_extent(const void *av, const void *bv)
724{
725 const struct extent *a = av;
726 const struct extent *b = bv;
727 if (a->start < b->start)
728 return -1;
729 if (a->start > b->start)
730 return 1;
731 return 0;
732}
733
0dcecb2e 734static int count_memberships(struct dl *dl, struct intel_super *super)
c2c087e6 735{
c2c087e6 736 int memberships = 0;
620b1713 737 int i;
c2c087e6 738
949c47a0
DW
739 for (i = 0; i < super->anchor->num_raid_devs; i++) {
740 struct imsm_dev *dev = get_imsm_dev(super, i);
a965f303 741 struct imsm_map *map = get_imsm_map(dev, 0);
c2c087e6 742
620b1713
DW
743 if (get_imsm_disk_slot(map, dl->index) >= 0)
744 memberships++;
c2c087e6 745 }
0dcecb2e
DW
746
747 return memberships;
748}
749
750static struct extent *get_extents(struct intel_super *super, struct dl *dl)
751{
752 /* find a list of used extents on the given physical device */
753 struct extent *rv, *e;
620b1713 754 int i;
0dcecb2e
DW
755 int memberships = count_memberships(dl, super);
756 __u32 reservation = MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS;
757
c2c087e6
DW
758 rv = malloc(sizeof(struct extent) * (memberships + 1));
759 if (!rv)
760 return NULL;
761 e = rv;
762
949c47a0
DW
763 for (i = 0; i < super->anchor->num_raid_devs; i++) {
764 struct imsm_dev *dev = get_imsm_dev(super, i);
a965f303 765 struct imsm_map *map = get_imsm_map(dev, 0);
c2c087e6 766
620b1713
DW
767 if (get_imsm_disk_slot(map, dl->index) >= 0) {
768 e->start = __le32_to_cpu(map->pba_of_lba0);
769 e->size = __le32_to_cpu(map->blocks_per_member);
770 e++;
c2c087e6
DW
771 }
772 }
773 qsort(rv, memberships, sizeof(*rv), cmp_extent);
774
14e8215b
DW
775 /* determine the start of the metadata
776 * when no raid devices are defined use the default
777 * ...otherwise allow the metadata to truncate the value
778 * as is the case with older versions of imsm
779 */
780 if (memberships) {
781 struct extent *last = &rv[memberships - 1];
782 __u32 remainder;
783
784 remainder = __le32_to_cpu(dl->disk.total_blocks) -
785 (last->start + last->size);
dda5855f
DW
786 /* round down to 1k block to satisfy precision of the kernel
787 * 'size' interface
788 */
789 remainder &= ~1UL;
790 /* make sure remainder is still sane */
f21e18ca 791 if (remainder < (unsigned)ROUND_UP(super->len, 512) >> 9)
dda5855f 792 remainder = ROUND_UP(super->len, 512) >> 9;
14e8215b
DW
793 if (reservation > remainder)
794 reservation = remainder;
795 }
796 e->start = __le32_to_cpu(dl->disk.total_blocks) - reservation;
c2c087e6
DW
797 e->size = 0;
798 return rv;
799}
800
14e8215b
DW
801/* try to determine how much space is reserved for metadata from
802 * the last get_extents() entry, otherwise fallback to the
803 * default
804 */
805static __u32 imsm_reserved_sectors(struct intel_super *super, struct dl *dl)
806{
807 struct extent *e;
808 int i;
809 __u32 rv;
810
811 /* for spares just return a minimal reservation which will grow
812 * once the spare is picked up by an array
813 */
814 if (dl->index == -1)
815 return MPB_SECTOR_CNT;
816
817 e = get_extents(super, dl);
818 if (!e)
819 return MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS;
820
821 /* scroll to last entry */
822 for (i = 0; e[i].size; i++)
823 continue;
824
825 rv = __le32_to_cpu(dl->disk.total_blocks) - e[i].start;
826
827 free(e);
828
829 return rv;
830}
831
25ed7e59
DW
832static int is_spare(struct imsm_disk *disk)
833{
834 return (disk->status & SPARE_DISK) == SPARE_DISK;
835}
836
837static int is_configured(struct imsm_disk *disk)
838{
839 return (disk->status & CONFIGURED_DISK) == CONFIGURED_DISK;
840}
841
842static int is_failed(struct imsm_disk *disk)
843{
844 return (disk->status & FAILED_DISK) == FAILED_DISK;
845}
846
80e7f8c3
AC
847/* Return minimum size of a spare that can be used in this array*/
848static unsigned long long min_acceptable_spare_size_imsm(struct supertype *st)
849{
850 struct intel_super *super = st->sb;
851 struct dl *dl;
852 struct extent *e;
853 int i;
854 unsigned long long rv = 0;
855
856 if (!super)
857 return rv;
858 /* find first active disk in array */
859 dl = super->disks;
860 while (dl && (is_failed(&dl->disk) || dl->index == -1))
861 dl = dl->next;
862 if (!dl)
863 return rv;
864 /* find last lba used by subarrays */
865 e = get_extents(super, dl);
866 if (!e)
867 return rv;
868 for (i = 0; e[i].size; i++)
869 continue;
870 if (i > 0)
871 rv = e[i-1].start + e[i-1].size;
872 free(e);
873 /* add the amount of space needed for metadata */
874 rv = rv + MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS;
875 return rv * 512;
876}
877
1799c9e8 878#ifndef MDASSEMBLE
1e5c6983
DW
879static __u64 blocks_per_migr_unit(struct imsm_dev *dev);
880
44470971 881static void print_imsm_dev(struct imsm_dev *dev, char *uuid, int disk_idx)
cdddbdbc
DW
882{
883 __u64 sz;
0d80bb2f 884 int slot, i;
a965f303 885 struct imsm_map *map = get_imsm_map(dev, 0);
dd8bcb3b 886 struct imsm_map *map2 = get_imsm_map(dev, 1);
b10b37b8 887 __u32 ord;
cdddbdbc
DW
888
889 printf("\n");
1e7bc0ed 890 printf("[%.16s]:\n", dev->volume);
44470971 891 printf(" UUID : %s\n", uuid);
dd8bcb3b
AK
892 printf(" RAID Level : %d", get_imsm_raid_level(map));
893 if (map2)
894 printf(" <-- %d", get_imsm_raid_level(map2));
895 printf("\n");
896 printf(" Members : %d", map->num_members);
897 if (map2)
898 printf(" <-- %d", map2->num_members);
899 printf("\n");
0d80bb2f
DW
900 printf(" Slots : [");
901 for (i = 0; i < map->num_members; i++) {
dd8bcb3b 902 ord = get_imsm_ord_tbl_ent(dev, i, 0);
0d80bb2f
DW
903 printf("%s", ord & IMSM_ORD_REBUILD ? "_" : "U");
904 }
dd8bcb3b
AK
905 printf("]");
906 if (map2) {
907 printf(" <-- [");
908 for (i = 0; i < map2->num_members; i++) {
909 ord = get_imsm_ord_tbl_ent(dev, i, 1);
910 printf("%s", ord & IMSM_ORD_REBUILD ? "_" : "U");
911 }
912 printf("]");
913 }
914 printf("\n");
7095bccb
AK
915 printf(" Failed disk : ");
916 if (map->failed_disk_num == 0xff)
917 printf("none");
918 else
919 printf("%i", map->failed_disk_num);
920 printf("\n");
620b1713
DW
921 slot = get_imsm_disk_slot(map, disk_idx);
922 if (slot >= 0) {
98130f40 923 ord = get_imsm_ord_tbl_ent(dev, slot, -1);
b10b37b8
DW
924 printf(" This Slot : %d%s\n", slot,
925 ord & IMSM_ORD_REBUILD ? " (out-of-sync)" : "");
926 } else
cdddbdbc
DW
927 printf(" This Slot : ?\n");
928 sz = __le32_to_cpu(dev->size_high);
929 sz <<= 32;
930 sz += __le32_to_cpu(dev->size_low);
931 printf(" Array Size : %llu%s\n", (unsigned long long)sz,
932 human_size(sz * 512));
933 sz = __le32_to_cpu(map->blocks_per_member);
934 printf(" Per Dev Size : %llu%s\n", (unsigned long long)sz,
935 human_size(sz * 512));
936 printf(" Sector Offset : %u\n",
937 __le32_to_cpu(map->pba_of_lba0));
938 printf(" Num Stripes : %u\n",
939 __le32_to_cpu(map->num_data_stripes));
dd8bcb3b 940 printf(" Chunk Size : %u KiB",
cdddbdbc 941 __le16_to_cpu(map->blocks_per_strip) / 2);
dd8bcb3b
AK
942 if (map2)
943 printf(" <-- %u KiB",
944 __le16_to_cpu(map2->blocks_per_strip) / 2);
945 printf("\n");
cdddbdbc 946 printf(" Reserved : %d\n", __le32_to_cpu(dev->reserved_blocks));
8655a7b1 947 printf(" Migrate State : ");
1484e727
DW
948 if (dev->vol.migr_state) {
949 if (migr_type(dev) == MIGR_INIT)
8655a7b1 950 printf("initialize\n");
1484e727 951 else if (migr_type(dev) == MIGR_REBUILD)
8655a7b1 952 printf("rebuild\n");
1484e727 953 else if (migr_type(dev) == MIGR_VERIFY)
8655a7b1 954 printf("check\n");
1484e727 955 else if (migr_type(dev) == MIGR_GEN_MIGR)
8655a7b1 956 printf("general migration\n");
1484e727 957 else if (migr_type(dev) == MIGR_STATE_CHANGE)
8655a7b1 958 printf("state change\n");
1484e727 959 else if (migr_type(dev) == MIGR_REPAIR)
8655a7b1 960 printf("repair\n");
1484e727 961 else
8655a7b1
DW
962 printf("<unknown:%d>\n", migr_type(dev));
963 } else
964 printf("idle\n");
3393c6af
DW
965 printf(" Map State : %s", map_state_str[map->map_state]);
966 if (dev->vol.migr_state) {
967 struct imsm_map *map = get_imsm_map(dev, 1);
1e5c6983 968
b10b37b8 969 printf(" <-- %s", map_state_str[map->map_state]);
1e5c6983
DW
970 printf("\n Checkpoint : %u (%llu)",
971 __le32_to_cpu(dev->vol.curr_migr_unit),
94fcb80a 972 (unsigned long long)blocks_per_migr_unit(dev));
3393c6af
DW
973 }
974 printf("\n");
cdddbdbc 975 printf(" Dirty State : %s\n", dev->vol.dirty ? "dirty" : "clean");
cdddbdbc
DW
976}
977
14e8215b 978static void print_imsm_disk(struct imsm_super *mpb, int index, __u32 reserved)
cdddbdbc 979{
949c47a0 980 struct imsm_disk *disk = __get_imsm_disk(mpb, index);
1f24f035 981 char str[MAX_RAID_SERIAL_LEN + 1];
cdddbdbc
DW
982 __u64 sz;
983
d362da3d 984 if (index < 0 || !disk)
e9d82038
DW
985 return;
986
cdddbdbc 987 printf("\n");
1f24f035 988 snprintf(str, MAX_RAID_SERIAL_LEN + 1, "%s", disk->serial);
cdddbdbc 989 printf(" Disk%02d Serial : %s\n", index, str);
25ed7e59
DW
990 printf(" State :%s%s%s\n", is_spare(disk) ? " spare" : "",
991 is_configured(disk) ? " active" : "",
992 is_failed(disk) ? " failed" : "");
cdddbdbc 993 printf(" Id : %08x\n", __le32_to_cpu(disk->scsi_id));
14e8215b 994 sz = __le32_to_cpu(disk->total_blocks) - reserved;
cdddbdbc
DW
995 printf(" Usable Size : %llu%s\n", (unsigned long long)sz,
996 human_size(sz * 512));
997}
998
a5d85af7 999static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char *map);
44470971 1000
cdddbdbc
DW
1001static void examine_super_imsm(struct supertype *st, char *homehost)
1002{
1003 struct intel_super *super = st->sb;
949c47a0 1004 struct imsm_super *mpb = super->anchor;
cdddbdbc
DW
1005 char str[MAX_SIGNATURE_LENGTH];
1006 int i;
27fd6274
DW
1007 struct mdinfo info;
1008 char nbuf[64];
cdddbdbc 1009 __u32 sum;
14e8215b 1010 __u32 reserved = imsm_reserved_sectors(super, super->disks);
94827db3 1011 struct dl *dl;
27fd6274 1012
cdddbdbc
DW
1013 snprintf(str, MPB_SIG_LEN, "%s", mpb->sig);
1014 printf(" Magic : %s\n", str);
1015 snprintf(str, strlen(MPB_VERSION_RAID0), "%s", get_imsm_version(mpb));
1016 printf(" Version : %s\n", get_imsm_version(mpb));
148acb7b 1017 printf(" Orig Family : %08x\n", __le32_to_cpu(mpb->orig_family_num));
cdddbdbc
DW
1018 printf(" Family : %08x\n", __le32_to_cpu(mpb->family_num));
1019 printf(" Generation : %08x\n", __le32_to_cpu(mpb->generation_num));
a5d85af7 1020 getinfo_super_imsm(st, &info, NULL);
ae2bfd4e 1021 fname_from_uuid(st, &info, nbuf, ':');
27fd6274 1022 printf(" UUID : %s\n", nbuf + 5);
cdddbdbc
DW
1023 sum = __le32_to_cpu(mpb->check_sum);
1024 printf(" Checksum : %08x %s\n", sum,
949c47a0 1025 __gen_imsm_checksum(mpb) == sum ? "correct" : "incorrect");
87eb16df 1026 printf(" MPB Sectors : %d\n", mpb_sectors(mpb));
cdddbdbc
DW
1027 printf(" Disks : %d\n", mpb->num_disks);
1028 printf(" RAID Devices : %d\n", mpb->num_raid_devs);
14e8215b 1029 print_imsm_disk(mpb, super->disks->index, reserved);
604b746f
JD
1030 if (super->bbm_log) {
1031 struct bbm_log *log = super->bbm_log;
1032
1033 printf("\n");
1034 printf("Bad Block Management Log:\n");
1035 printf(" Log Size : %d\n", __le32_to_cpu(mpb->bbm_log_size));
1036 printf(" Signature : %x\n", __le32_to_cpu(log->signature));
1037 printf(" Entry Count : %d\n", __le32_to_cpu(log->entry_count));
1038 printf(" Spare Blocks : %d\n", __le32_to_cpu(log->reserved_spare_block_count));
13a3b65d
N
1039 printf(" First Spare : %llx\n",
1040 (unsigned long long) __le64_to_cpu(log->first_spare_lba));
604b746f 1041 }
44470971
DW
1042 for (i = 0; i < mpb->num_raid_devs; i++) {
1043 struct mdinfo info;
1044 struct imsm_dev *dev = __get_imsm_dev(mpb, i);
1045
1046 super->current_vol = i;
a5d85af7 1047 getinfo_super_imsm(st, &info, NULL);
ae2bfd4e 1048 fname_from_uuid(st, &info, nbuf, ':');
44470971
DW
1049 print_imsm_dev(dev, nbuf + 5, super->disks->index);
1050 }
cdddbdbc
DW
1051 for (i = 0; i < mpb->num_disks; i++) {
1052 if (i == super->disks->index)
1053 continue;
14e8215b 1054 print_imsm_disk(mpb, i, reserved);
cdddbdbc 1055 }
94827db3
N
1056 for (dl = super->disks ; dl; dl = dl->next) {
1057 struct imsm_disk *disk;
1058 char str[MAX_RAID_SERIAL_LEN + 1];
1059 __u64 sz;
1060
1061 if (dl->index >= 0)
1062 continue;
1063
1064 disk = &dl->disk;
1065 printf("\n");
1066 snprintf(str, MAX_RAID_SERIAL_LEN + 1, "%s", disk->serial);
1067 printf(" Disk Serial : %s\n", str);
1068 printf(" State :%s%s%s\n", is_spare(disk) ? " spare" : "",
1069 is_configured(disk) ? " active" : "",
1070 is_failed(disk) ? " failed" : "");
1071 printf(" Id : %08x\n", __le32_to_cpu(disk->scsi_id));
1072 sz = __le32_to_cpu(disk->total_blocks) - reserved;
1073 printf(" Usable Size : %llu%s\n", (unsigned long long)sz,
1074 human_size(sz * 512));
1075 }
cdddbdbc
DW
1076}
1077
061f2c6a 1078static void brief_examine_super_imsm(struct supertype *st, int verbose)
cdddbdbc 1079{
27fd6274 1080 /* We just write a generic IMSM ARRAY entry */
ff54de6e
N
1081 struct mdinfo info;
1082 char nbuf[64];
1e7bc0ed 1083 struct intel_super *super = st->sb;
1e7bc0ed 1084
0d5a423f
DW
1085 if (!super->anchor->num_raid_devs) {
1086 printf("ARRAY metadata=imsm\n");
1e7bc0ed 1087 return;
0d5a423f 1088 }
ff54de6e 1089
a5d85af7 1090 getinfo_super_imsm(st, &info, NULL);
4737ae25
N
1091 fname_from_uuid(st, &info, nbuf, ':');
1092 printf("ARRAY metadata=imsm UUID=%s\n", nbuf + 5);
1093}
1094
1095static void brief_examine_subarrays_imsm(struct supertype *st, int verbose)
1096{
1097 /* We just write a generic IMSM ARRAY entry */
1098 struct mdinfo info;
1099 char nbuf[64];
1100 char nbuf1[64];
1101 struct intel_super *super = st->sb;
1102 int i;
1103
1104 if (!super->anchor->num_raid_devs)
1105 return;
1106
a5d85af7 1107 getinfo_super_imsm(st, &info, NULL);
ae2bfd4e 1108 fname_from_uuid(st, &info, nbuf, ':');
1e7bc0ed
DW
1109 for (i = 0; i < super->anchor->num_raid_devs; i++) {
1110 struct imsm_dev *dev = get_imsm_dev(super, i);
1111
1112 super->current_vol = i;
a5d85af7 1113 getinfo_super_imsm(st, &info, NULL);
ae2bfd4e 1114 fname_from_uuid(st, &info, nbuf1, ':');
1124b3cf 1115 printf("ARRAY /dev/md/%.16s container=%s member=%d UUID=%s\n",
cf8de691 1116 dev->volume, nbuf + 5, i, nbuf1 + 5);
1e7bc0ed 1117 }
cdddbdbc
DW
1118}
1119
9d84c8ea
DW
1120static void export_examine_super_imsm(struct supertype *st)
1121{
1122 struct intel_super *super = st->sb;
1123 struct imsm_super *mpb = super->anchor;
1124 struct mdinfo info;
1125 char nbuf[64];
1126
a5d85af7 1127 getinfo_super_imsm(st, &info, NULL);
9d84c8ea
DW
1128 fname_from_uuid(st, &info, nbuf, ':');
1129 printf("MD_METADATA=imsm\n");
1130 printf("MD_LEVEL=container\n");
1131 printf("MD_UUID=%s\n", nbuf+5);
1132 printf("MD_DEVICES=%u\n", mpb->num_disks);
1133}
1134
cdddbdbc
DW
1135static void detail_super_imsm(struct supertype *st, char *homehost)
1136{
3ebe00a1
DW
1137 struct mdinfo info;
1138 char nbuf[64];
1139
a5d85af7 1140 getinfo_super_imsm(st, &info, NULL);
ae2bfd4e 1141 fname_from_uuid(st, &info, nbuf, ':');
3ebe00a1 1142 printf("\n UUID : %s\n", nbuf + 5);
cdddbdbc
DW
1143}
1144
1145static void brief_detail_super_imsm(struct supertype *st)
1146{
ff54de6e
N
1147 struct mdinfo info;
1148 char nbuf[64];
a5d85af7 1149 getinfo_super_imsm(st, &info, NULL);
ae2bfd4e 1150 fname_from_uuid(st, &info, nbuf, ':');
ff54de6e 1151 printf(" UUID=%s", nbuf + 5);
cdddbdbc 1152}
d665cc31
DW
1153
1154static int imsm_read_serial(int fd, char *devname, __u8 *serial);
1155static void fd2devname(int fd, char *name);
1156
120dc887 1157static int ahci_enumerate_ports(const char *hba_path, int port_count, int host_base, int verbose)
d665cc31 1158{
120dc887
LM
1159 /* dump an unsorted list of devices attached to AHCI Intel storage
1160 * controller, as well as non-connected ports
d665cc31
DW
1161 */
1162 int hba_len = strlen(hba_path) + 1;
1163 struct dirent *ent;
1164 DIR *dir;
1165 char *path = NULL;
1166 int err = 0;
1167 unsigned long port_mask = (1 << port_count) - 1;
1168
f21e18ca 1169 if (port_count > (int)sizeof(port_mask) * 8) {
d665cc31
DW
1170 if (verbose)
1171 fprintf(stderr, Name ": port_count %d out of range\n", port_count);
1172 return 2;
1173 }
1174
1175 /* scroll through /sys/dev/block looking for devices attached to
1176 * this hba
1177 */
1178 dir = opendir("/sys/dev/block");
1179 for (ent = dir ? readdir(dir) : NULL; ent; ent = readdir(dir)) {
1180 int fd;
1181 char model[64];
1182 char vendor[64];
1183 char buf[1024];
1184 int major, minor;
1185 char *device;
1186 char *c;
1187 int port;
1188 int type;
1189
1190 if (sscanf(ent->d_name, "%d:%d", &major, &minor) != 2)
1191 continue;
1192 path = devt_to_devpath(makedev(major, minor));
1193 if (!path)
1194 continue;
1195 if (!path_attached_to_hba(path, hba_path)) {
1196 free(path);
1197 path = NULL;
1198 continue;
1199 }
1200
1201 /* retrieve the scsi device type */
1202 if (asprintf(&device, "/sys/dev/block/%d:%d/device/xxxxxxx", major, minor) < 0) {
1203 if (verbose)
1204 fprintf(stderr, Name ": failed to allocate 'device'\n");
1205 err = 2;
1206 break;
1207 }
1208 sprintf(device, "/sys/dev/block/%d:%d/device/type", major, minor);
1209 if (load_sys(device, buf) != 0) {
1210 if (verbose)
1211 fprintf(stderr, Name ": failed to read device type for %s\n",
1212 path);
1213 err = 2;
1214 free(device);
1215 break;
1216 }
1217 type = strtoul(buf, NULL, 10);
1218
1219 /* if it's not a disk print the vendor and model */
1220 if (!(type == 0 || type == 7 || type == 14)) {
1221 vendor[0] = '\0';
1222 model[0] = '\0';
1223 sprintf(device, "/sys/dev/block/%d:%d/device/vendor", major, minor);
1224 if (load_sys(device, buf) == 0) {
1225 strncpy(vendor, buf, sizeof(vendor));
1226 vendor[sizeof(vendor) - 1] = '\0';
1227 c = (char *) &vendor[sizeof(vendor) - 1];
1228 while (isspace(*c) || *c == '\0')
1229 *c-- = '\0';
1230
1231 }
1232 sprintf(device, "/sys/dev/block/%d:%d/device/model", major, minor);
1233 if (load_sys(device, buf) == 0) {
1234 strncpy(model, buf, sizeof(model));
1235 model[sizeof(model) - 1] = '\0';
1236 c = (char *) &model[sizeof(model) - 1];
1237 while (isspace(*c) || *c == '\0')
1238 *c-- = '\0';
1239 }
1240
1241 if (vendor[0] && model[0])
1242 sprintf(buf, "%.64s %.64s", vendor, model);
1243 else
1244 switch (type) { /* numbers from hald/linux/device.c */
1245 case 1: sprintf(buf, "tape"); break;
1246 case 2: sprintf(buf, "printer"); break;
1247 case 3: sprintf(buf, "processor"); break;
1248 case 4:
1249 case 5: sprintf(buf, "cdrom"); break;
1250 case 6: sprintf(buf, "scanner"); break;
1251 case 8: sprintf(buf, "media_changer"); break;
1252 case 9: sprintf(buf, "comm"); break;
1253 case 12: sprintf(buf, "raid"); break;
1254 default: sprintf(buf, "unknown");
1255 }
1256 } else
1257 buf[0] = '\0';
1258 free(device);
1259
1260 /* chop device path to 'host%d' and calculate the port number */
1261 c = strchr(&path[hba_len], '/');
4e5e717d
AW
1262 if (!c) {
1263 if (verbose)
1264 fprintf(stderr, Name ": %s - invalid path name\n", path + hba_len);
1265 err = 2;
1266 break;
1267 }
d665cc31
DW
1268 *c = '\0';
1269 if (sscanf(&path[hba_len], "host%d", &port) == 1)
1270 port -= host_base;
1271 else {
1272 if (verbose) {
1273 *c = '/'; /* repair the full string */
1274 fprintf(stderr, Name ": failed to determine port number for %s\n",
1275 path);
1276 }
1277 err = 2;
1278 break;
1279 }
1280
1281 /* mark this port as used */
1282 port_mask &= ~(1 << port);
1283
1284 /* print out the device information */
1285 if (buf[0]) {
1286 printf(" Port%d : - non-disk device (%s) -\n", port, buf);
1287 continue;
1288 }
1289
1290 fd = dev_open(ent->d_name, O_RDONLY);
1291 if (fd < 0)
1292 printf(" Port%d : - disk info unavailable -\n", port);
1293 else {
1294 fd2devname(fd, buf);
1295 printf(" Port%d : %s", port, buf);
1296 if (imsm_read_serial(fd, NULL, (__u8 *) buf) == 0)
1297 printf(" (%s)\n", buf);
1298 else
1299 printf("()\n");
1300 }
1301 close(fd);
1302 free(path);
1303 path = NULL;
1304 }
1305 if (path)
1306 free(path);
1307 if (dir)
1308 closedir(dir);
1309 if (err == 0) {
1310 int i;
1311
1312 for (i = 0; i < port_count; i++)
1313 if (port_mask & (1 << i))
1314 printf(" Port%d : - no device attached -\n", i);
1315 }
1316
1317 return err;
1318}
1319
120dc887 1320
155cbb4c 1321
120dc887
LM
1322static void print_found_intel_controllers(struct sys_dev *elem)
1323{
1324 for (; elem; elem = elem->next) {
1325 fprintf(stderr, Name ": found Intel(R) ");
1326 if (elem->type == SYS_DEV_SATA)
1327 fprintf(stderr, "SATA ");
155cbb4c
LM
1328 else if (elem->type == SYS_DEV_SAS)
1329 fprintf(stderr, "SAS ");
120dc887
LM
1330 fprintf(stderr, "RAID controller");
1331 if (elem->pci_id)
1332 fprintf(stderr, " at %s", elem->pci_id);
1333 fprintf(stderr, ".\n");
1334 }
1335 fflush(stderr);
1336}
1337
120dc887
LM
1338static int ahci_get_port_count(const char *hba_path, int *port_count)
1339{
1340 struct dirent *ent;
1341 DIR *dir;
1342 int host_base = -1;
1343
1344 *port_count = 0;
1345 if ((dir = opendir(hba_path)) == NULL)
1346 return -1;
1347
1348 for (ent = readdir(dir); ent; ent = readdir(dir)) {
1349 int host;
1350
1351 if (sscanf(ent->d_name, "host%d", &host) != 1)
1352 continue;
1353 if (*port_count == 0)
1354 host_base = host;
1355 else if (host < host_base)
1356 host_base = host;
1357
1358 if (host + 1 > *port_count + host_base)
1359 *port_count = host + 1 - host_base;
1360 }
1361 closedir(dir);
1362 return host_base;
1363}
1364
a891a3c2
LM
1365static void print_imsm_capability(const struct imsm_orom *orom)
1366{
1367 printf(" Platform : Intel(R) Matrix Storage Manager\n");
1368 printf(" Version : %d.%d.%d.%d\n", orom->major_ver, orom->minor_ver,
1369 orom->hotfix_ver, orom->build);
1370 printf(" RAID Levels :%s%s%s%s%s\n",
1371 imsm_orom_has_raid0(orom) ? " raid0" : "",
1372 imsm_orom_has_raid1(orom) ? " raid1" : "",
1373 imsm_orom_has_raid1e(orom) ? " raid1e" : "",
1374 imsm_orom_has_raid10(orom) ? " raid10" : "",
1375 imsm_orom_has_raid5(orom) ? " raid5" : "");
1376 printf(" Chunk Sizes :%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
1377 imsm_orom_has_chunk(orom, 2) ? " 2k" : "",
1378 imsm_orom_has_chunk(orom, 4) ? " 4k" : "",
1379 imsm_orom_has_chunk(orom, 8) ? " 8k" : "",
1380 imsm_orom_has_chunk(orom, 16) ? " 16k" : "",
1381 imsm_orom_has_chunk(orom, 32) ? " 32k" : "",
1382 imsm_orom_has_chunk(orom, 64) ? " 64k" : "",
1383 imsm_orom_has_chunk(orom, 128) ? " 128k" : "",
1384 imsm_orom_has_chunk(orom, 256) ? " 256k" : "",
1385 imsm_orom_has_chunk(orom, 512) ? " 512k" : "",
1386 imsm_orom_has_chunk(orom, 1024*1) ? " 1M" : "",
1387 imsm_orom_has_chunk(orom, 1024*2) ? " 2M" : "",
1388 imsm_orom_has_chunk(orom, 1024*4) ? " 4M" : "",
1389 imsm_orom_has_chunk(orom, 1024*8) ? " 8M" : "",
1390 imsm_orom_has_chunk(orom, 1024*16) ? " 16M" : "",
1391 imsm_orom_has_chunk(orom, 1024*32) ? " 32M" : "",
1392 imsm_orom_has_chunk(orom, 1024*64) ? " 64M" : "");
1393 printf(" Max Disks : %d\n", orom->tds);
1394 printf(" Max Volumes : %d\n", orom->vpa);
1395 return;
1396}
1397
5615172f 1398static int detail_platform_imsm(int verbose, int enumerate_only)
d665cc31
DW
1399{
1400 /* There are two components to imsm platform support, the ahci SATA
1401 * controller and the option-rom. To find the SATA controller we
1402 * simply look in /sys/bus/pci/drivers/ahci to see if an ahci
1403 * controller with the Intel vendor id is present. This approach
1404 * allows mdadm to leverage the kernel's ahci detection logic, with the
1405 * caveat that if ahci.ko is not loaded mdadm will not be able to
1406 * detect platform raid capabilities. The option-rom resides in a
1407 * platform "Adapter ROM". We scan for its signature to retrieve the
1408 * platform capabilities. If raid support is disabled in the BIOS the
1409 * option-rom capability structure will not be available.
1410 */
1411 const struct imsm_orom *orom;
1412 struct sys_dev *list, *hba;
d665cc31
DW
1413 int host_base = 0;
1414 int port_count = 0;
120dc887 1415 int result=0;
d665cc31 1416
5615172f 1417 if (enumerate_only) {
a891a3c2 1418 if (check_env("IMSM_NO_PLATFORM"))
5615172f 1419 return 0;
a891a3c2
LM
1420 list = find_intel_devices();
1421 if (!list)
1422 return 2;
1423 for (hba = list; hba; hba = hba->next) {
1424 orom = find_imsm_capability(hba->type);
1425 if (!orom) {
1426 result = 2;
1427 break;
1428 }
1429 }
1430 free_sys_dev(&list);
1431 return result;
5615172f
DW
1432 }
1433
155cbb4c
LM
1434 list = find_intel_devices();
1435 if (!list) {
d665cc31 1436 if (verbose)
155cbb4c
LM
1437 fprintf(stderr, Name ": no active Intel(R) RAID "
1438 "controller found.\n");
d665cc31
DW
1439 free_sys_dev(&list);
1440 return 2;
1441 } else if (verbose)
155cbb4c 1442 print_found_intel_controllers(list);
d665cc31 1443
a891a3c2
LM
1444 for (hba = list; hba; hba = hba->next) {
1445 orom = find_imsm_capability(hba->type);
1446 if (!orom)
1447 fprintf(stderr, Name ": imsm capabilities not found for controller: %s (type %s)\n",
1448 hba->path, get_sys_dev_type(hba->type));
1449 else
1450 print_imsm_capability(orom);
d665cc31
DW
1451 }
1452
120dc887
LM
1453 for (hba = list; hba; hba = hba->next) {
1454 printf(" I/O Controller : %s (%s)\n",
1455 hba->path, get_sys_dev_type(hba->type));
d665cc31 1456
120dc887
LM
1457 if (hba->type == SYS_DEV_SATA) {
1458 host_base = ahci_get_port_count(hba->path, &port_count);
1459 if (ahci_enumerate_ports(hba->path, port_count, host_base, verbose)) {
1460 if (verbose)
1461 fprintf(stderr, Name ": failed to enumerate "
1462 "ports on SATA controller at %s.", hba->pci_id);
1463 result |= 2;
1464 }
1465 }
d665cc31 1466 }
155cbb4c 1467
120dc887
LM
1468 free_sys_dev(&list);
1469 return result;
d665cc31 1470}
cdddbdbc
DW
1471#endif
1472
1473static int match_home_imsm(struct supertype *st, char *homehost)
1474{
5115ca67
DW
1475 /* the imsm metadata format does not specify any host
1476 * identification information. We return -1 since we can never
1477 * confirm nor deny whether a given array is "meant" for this
148acb7b 1478 * host. We rely on compare_super and the 'family_num' fields to
5115ca67
DW
1479 * exclude member disks that do not belong, and we rely on
1480 * mdadm.conf to specify the arrays that should be assembled.
1481 * Auto-assembly may still pick up "foreign" arrays.
1482 */
cdddbdbc 1483
9362c1c8 1484 return -1;
cdddbdbc
DW
1485}
1486
1487static void uuid_from_super_imsm(struct supertype *st, int uuid[4])
1488{
51006d85
N
1489 /* The uuid returned here is used for:
1490 * uuid to put into bitmap file (Create, Grow)
1491 * uuid for backup header when saving critical section (Grow)
1492 * comparing uuids when re-adding a device into an array
1493 * In these cases the uuid required is that of the data-array,
1494 * not the device-set.
1495 * uuid to recognise same set when adding a missing device back
1496 * to an array. This is a uuid for the device-set.
1497 *
1498 * For each of these we can make do with a truncated
1499 * or hashed uuid rather than the original, as long as
1500 * everyone agrees.
1501 * In each case the uuid required is that of the data-array,
1502 * not the device-set.
43dad3d6 1503 */
51006d85
N
1504 /* imsm does not track uuid's so we synthesis one using sha1 on
1505 * - The signature (Which is constant for all imsm array, but no matter)
148acb7b 1506 * - the orig_family_num of the container
51006d85
N
1507 * - the index number of the volume
1508 * - the 'serial' number of the volume.
1509 * Hopefully these are all constant.
1510 */
1511 struct intel_super *super = st->sb;
43dad3d6 1512
51006d85
N
1513 char buf[20];
1514 struct sha1_ctx ctx;
1515 struct imsm_dev *dev = NULL;
148acb7b 1516 __u32 family_num;
51006d85 1517
148acb7b
DW
1518 /* some mdadm versions failed to set ->orig_family_num, in which
1519 * case fall back to ->family_num. orig_family_num will be
1520 * fixed up with the first metadata update.
1521 */
1522 family_num = super->anchor->orig_family_num;
1523 if (family_num == 0)
1524 family_num = super->anchor->family_num;
51006d85 1525 sha1_init_ctx(&ctx);
92bd8f8d 1526 sha1_process_bytes(super->anchor->sig, MPB_SIG_LEN, &ctx);
148acb7b 1527 sha1_process_bytes(&family_num, sizeof(__u32), &ctx);
51006d85
N
1528 if (super->current_vol >= 0)
1529 dev = get_imsm_dev(super, super->current_vol);
1530 if (dev) {
1531 __u32 vol = super->current_vol;
1532 sha1_process_bytes(&vol, sizeof(vol), &ctx);
1533 sha1_process_bytes(dev->volume, MAX_RAID_SERIAL_LEN, &ctx);
1534 }
1535 sha1_finish_ctx(&ctx, buf);
1536 memcpy(uuid, buf, 4*4);
cdddbdbc
DW
1537}
1538
0d481d37 1539#if 0
4f5bc454
DW
1540static void
1541get_imsm_numerical_version(struct imsm_super *mpb, int *m, int *p)
cdddbdbc 1542{
cdddbdbc
DW
1543 __u8 *v = get_imsm_version(mpb);
1544 __u8 *end = mpb->sig + MAX_SIGNATURE_LENGTH;
1545 char major[] = { 0, 0, 0 };
1546 char minor[] = { 0 ,0, 0 };
1547 char patch[] = { 0, 0, 0 };
1548 char *ver_parse[] = { major, minor, patch };
1549 int i, j;
1550
1551 i = j = 0;
1552 while (*v != '\0' && v < end) {
1553 if (*v != '.' && j < 2)
1554 ver_parse[i][j++] = *v;
1555 else {
1556 i++;
1557 j = 0;
1558 }
1559 v++;
1560 }
1561
4f5bc454
DW
1562 *m = strtol(minor, NULL, 0);
1563 *p = strtol(patch, NULL, 0);
1564}
0d481d37 1565#endif
4f5bc454 1566
1e5c6983
DW
1567static __u32 migr_strip_blocks_resync(struct imsm_dev *dev)
1568{
1569 /* migr_strip_size when repairing or initializing parity */
1570 struct imsm_map *map = get_imsm_map(dev, 0);
1571 __u32 chunk = __le32_to_cpu(map->blocks_per_strip);
1572
1573 switch (get_imsm_raid_level(map)) {
1574 case 5:
1575 case 10:
1576 return chunk;
1577 default:
1578 return 128*1024 >> 9;
1579 }
1580}
1581
1582static __u32 migr_strip_blocks_rebuild(struct imsm_dev *dev)
1583{
1584 /* migr_strip_size when rebuilding a degraded disk, no idea why
1585 * this is different than migr_strip_size_resync(), but it's good
1586 * to be compatible
1587 */
1588 struct imsm_map *map = get_imsm_map(dev, 1);
1589 __u32 chunk = __le32_to_cpu(map->blocks_per_strip);
1590
1591 switch (get_imsm_raid_level(map)) {
1592 case 1:
1593 case 10:
1594 if (map->num_members % map->num_domains == 0)
1595 return 128*1024 >> 9;
1596 else
1597 return chunk;
1598 case 5:
1599 return max((__u32) 64*1024 >> 9, chunk);
1600 default:
1601 return 128*1024 >> 9;
1602 }
1603}
1604
1605static __u32 num_stripes_per_unit_resync(struct imsm_dev *dev)
1606{
1607 struct imsm_map *lo = get_imsm_map(dev, 0);
1608 struct imsm_map *hi = get_imsm_map(dev, 1);
1609 __u32 lo_chunk = __le32_to_cpu(lo->blocks_per_strip);
1610 __u32 hi_chunk = __le32_to_cpu(hi->blocks_per_strip);
1611
1612 return max((__u32) 1, hi_chunk / lo_chunk);
1613}
1614
1615static __u32 num_stripes_per_unit_rebuild(struct imsm_dev *dev)
1616{
1617 struct imsm_map *lo = get_imsm_map(dev, 0);
1618 int level = get_imsm_raid_level(lo);
1619
1620 if (level == 1 || level == 10) {
1621 struct imsm_map *hi = get_imsm_map(dev, 1);
1622
1623 return hi->num_domains;
1624 } else
1625 return num_stripes_per_unit_resync(dev);
1626}
1627
98130f40 1628static __u8 imsm_num_data_members(struct imsm_dev *dev, int second_map)
1e5c6983
DW
1629{
1630 /* named 'imsm_' because raid0, raid1 and raid10
1631 * counter-intuitively have the same number of data disks
1632 */
98130f40 1633 struct imsm_map *map = get_imsm_map(dev, second_map);
1e5c6983
DW
1634
1635 switch (get_imsm_raid_level(map)) {
1636 case 0:
1637 case 1:
1638 case 10:
1639 return map->num_members;
1640 case 5:
1641 return map->num_members - 1;
1642 default:
1643 dprintf("%s: unsupported raid level\n", __func__);
1644 return 0;
1645 }
1646}
1647
1648static __u32 parity_segment_depth(struct imsm_dev *dev)
1649{
1650 struct imsm_map *map = get_imsm_map(dev, 0);
1651 __u32 chunk = __le32_to_cpu(map->blocks_per_strip);
1652
1653 switch(get_imsm_raid_level(map)) {
1654 case 1:
1655 case 10:
1656 return chunk * map->num_domains;
1657 case 5:
1658 return chunk * map->num_members;
1659 default:
1660 return chunk;
1661 }
1662}
1663
1664static __u32 map_migr_block(struct imsm_dev *dev, __u32 block)
1665{
1666 struct imsm_map *map = get_imsm_map(dev, 1);
1667 __u32 chunk = __le32_to_cpu(map->blocks_per_strip);
1668 __u32 strip = block / chunk;
1669
1670 switch (get_imsm_raid_level(map)) {
1671 case 1:
1672 case 10: {
1673 __u32 vol_strip = (strip * map->num_domains) + 1;
1674 __u32 vol_stripe = vol_strip / map->num_members;
1675
1676 return vol_stripe * chunk + block % chunk;
1677 } case 5: {
1678 __u32 stripe = strip / (map->num_members - 1);
1679
1680 return stripe * chunk + block % chunk;
1681 }
1682 default:
1683 return 0;
1684 }
1685}
1686
1687static __u64 blocks_per_migr_unit(struct imsm_dev *dev)
1688{
1689 /* calculate the conversion factor between per member 'blocks'
1690 * (md/{resync,rebuild}_start) and imsm migration units, return
1691 * 0 for the 'not migrating' and 'unsupported migration' cases
1692 */
1693 if (!dev->vol.migr_state)
1694 return 0;
1695
1696 switch (migr_type(dev)) {
6345120e 1697 case MIGR_GEN_MIGR:
1e5c6983
DW
1698 case MIGR_VERIFY:
1699 case MIGR_REPAIR:
1700 case MIGR_INIT: {
1701 struct imsm_map *map = get_imsm_map(dev, 0);
1702 __u32 stripes_per_unit;
1703 __u32 blocks_per_unit;
1704 __u32 parity_depth;
1705 __u32 migr_chunk;
1706 __u32 block_map;
1707 __u32 block_rel;
1708 __u32 segment;
1709 __u32 stripe;
1710 __u8 disks;
1711
1712 /* yes, this is really the translation of migr_units to
1713 * per-member blocks in the 'resync' case
1714 */
1715 stripes_per_unit = num_stripes_per_unit_resync(dev);
1716 migr_chunk = migr_strip_blocks_resync(dev);
98130f40 1717 disks = imsm_num_data_members(dev, 0);
1e5c6983
DW
1718 blocks_per_unit = stripes_per_unit * migr_chunk * disks;
1719 stripe = __le32_to_cpu(map->blocks_per_strip) * disks;
1720 segment = blocks_per_unit / stripe;
1721 block_rel = blocks_per_unit - segment * stripe;
1722 parity_depth = parity_segment_depth(dev);
1723 block_map = map_migr_block(dev, block_rel);
1724 return block_map + parity_depth * segment;
1725 }
1726 case MIGR_REBUILD: {
1727 __u32 stripes_per_unit;
1728 __u32 migr_chunk;
1729
1730 stripes_per_unit = num_stripes_per_unit_rebuild(dev);
1731 migr_chunk = migr_strip_blocks_rebuild(dev);
1732 return migr_chunk * stripes_per_unit;
1733 }
1e5c6983
DW
1734 case MIGR_STATE_CHANGE:
1735 default:
1736 return 0;
1737 }
1738}
1739
c2c087e6
DW
1740static int imsm_level_to_layout(int level)
1741{
1742 switch (level) {
1743 case 0:
1744 case 1:
1745 return 0;
1746 case 5:
1747 case 6:
a380c027 1748 return ALGORITHM_LEFT_ASYMMETRIC;
c2c087e6 1749 case 10:
c92a2527 1750 return 0x102;
c2c087e6 1751 }
a18a888e 1752 return UnSet;
c2c087e6
DW
1753}
1754
a5d85af7 1755static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info, char *dmap)
bf5a934a
DW
1756{
1757 struct intel_super *super = st->sb;
949c47a0 1758 struct imsm_dev *dev = get_imsm_dev(super, super->current_vol);
a965f303 1759 struct imsm_map *map = get_imsm_map(dev, 0);
81ac8b4d 1760 struct imsm_map *prev_map = get_imsm_map(dev, 1);
b335e593 1761 struct imsm_map *map_to_analyse = map;
efb30e7f 1762 struct dl *dl;
e207da2f 1763 char *devname;
139dae11 1764 unsigned int component_size_alligment;
a5d85af7 1765 int map_disks = info->array.raid_disks;
bf5a934a 1766
95eeceeb 1767 memset(info, 0, sizeof(*info));
b335e593
AK
1768 if (prev_map)
1769 map_to_analyse = prev_map;
1770
efb30e7f
DW
1771 for (dl = super->disks; dl; dl = dl->next)
1772 if (dl->raiddisk == info->disk.raid_disk)
1773 break;
bf5a934a 1774 info->container_member = super->current_vol;
cd0430a1 1775 info->array.raid_disks = map->num_members;
b335e593 1776 info->array.level = get_imsm_raid_level(map_to_analyse);
bf5a934a
DW
1777 info->array.layout = imsm_level_to_layout(info->array.level);
1778 info->array.md_minor = -1;
1779 info->array.ctime = 0;
1780 info->array.utime = 0;
b335e593
AK
1781 info->array.chunk_size =
1782 __le16_to_cpu(map_to_analyse->blocks_per_strip) << 9;
301406c9 1783 info->array.state = !dev->vol.dirty;
da9b4a62
DW
1784 info->custom_array_size = __le32_to_cpu(dev->size_high);
1785 info->custom_array_size <<= 32;
1786 info->custom_array_size |= __le32_to_cpu(dev->size_low);
3f83228a
N
1787 if (prev_map && map->map_state == prev_map->map_state) {
1788 info->reshape_active = 1;
b335e593
AK
1789 info->new_level = get_imsm_raid_level(map);
1790 info->new_layout = imsm_level_to_layout(info->new_level);
1791 info->new_chunk = __le16_to_cpu(map->blocks_per_strip) << 9;
3f83228a 1792 info->delta_disks = map->num_members - prev_map->num_members;
493f5dd6
N
1793 if (info->delta_disks) {
1794 /* this needs to be applied to every array
1795 * in the container.
1796 */
1797 info->reshape_active = 2;
1798 }
3f83228a
N
1799 /* We shape information that we give to md might have to be
1800 * modify to cope with md's requirement for reshaping arrays.
1801 * For example, when reshaping a RAID0, md requires it to be
1802 * presented as a degraded RAID4.
1803 * Also if a RAID0 is migrating to a RAID5 we need to specify
1804 * the array as already being RAID5, but the 'before' layout
1805 * is a RAID4-like layout.
1806 */
1807 switch (info->array.level) {
1808 case 0:
1809 switch(info->new_level) {
1810 case 0:
1811 /* conversion is happening as RAID4 */
1812 info->array.level = 4;
1813 info->array.raid_disks += 1;
1814 break;
1815 case 5:
1816 /* conversion is happening as RAID5 */
1817 info->array.level = 5;
1818 info->array.layout = ALGORITHM_PARITY_N;
1819 info->array.raid_disks += 1;
1820 info->delta_disks -= 1;
1821 break;
1822 default:
1823 /* FIXME error message */
1824 info->array.level = UnSet;
1825 break;
1826 }
1827 break;
1828 }
b335e593
AK
1829 } else {
1830 info->new_level = UnSet;
1831 info->new_layout = UnSet;
1832 info->new_chunk = info->array.chunk_size;
3f83228a 1833 info->delta_disks = 0;
b335e593 1834 }
301406c9
DW
1835 info->disk.major = 0;
1836 info->disk.minor = 0;
efb30e7f
DW
1837 if (dl) {
1838 info->disk.major = dl->major;
1839 info->disk.minor = dl->minor;
1840 }
bf5a934a 1841
b335e593
AK
1842 info->data_offset = __le32_to_cpu(map_to_analyse->pba_of_lba0);
1843 info->component_size =
1844 __le32_to_cpu(map_to_analyse->blocks_per_member);
139dae11
AK
1845
1846 /* check component size aligment
1847 */
1848 component_size_alligment =
1849 info->component_size % (info->array.chunk_size/512);
1850
1851 if (component_size_alligment &&
1852 (info->array.level != 1) && (info->array.level != UnSet)) {
1853 dprintf("imsm: reported component size alligned from %llu ",
1854 info->component_size);
1855 info->component_size -= component_size_alligment;
1856 dprintf("to %llu (%i).\n",
1857 info->component_size, component_size_alligment);
1858 }
1859
301406c9 1860 memset(info->uuid, 0, sizeof(info->uuid));
921d9e16 1861 info->recovery_start = MaxSector;
bf5a934a 1862
d2e6d5d6 1863 info->reshape_progress = 0;
b6796ce1 1864 info->resync_start = MaxSector;
b335e593
AK
1865 if (map_to_analyse->map_state == IMSM_T_STATE_UNINITIALIZED ||
1866 dev->vol.dirty) {
301406c9 1867 info->resync_start = 0;
b6796ce1
AK
1868 }
1869 if (dev->vol.migr_state) {
1e5c6983
DW
1870 switch (migr_type(dev)) {
1871 case MIGR_REPAIR:
1872 case MIGR_INIT: {
1873 __u64 blocks_per_unit = blocks_per_migr_unit(dev);
1874 __u64 units = __le32_to_cpu(dev->vol.curr_migr_unit);
1875
1876 info->resync_start = blocks_per_unit * units;
1877 break;
1878 }
d2e6d5d6
AK
1879 case MIGR_GEN_MIGR: {
1880 __u64 blocks_per_unit = blocks_per_migr_unit(dev);
1881 __u64 units = __le32_to_cpu(dev->vol.curr_migr_unit);
04fa9523
AK
1882 unsigned long long array_blocks;
1883 int used_disks;
d2e6d5d6
AK
1884
1885 info->reshape_progress = blocks_per_unit * units;
6289d1e0
AK
1886
1887 /* checkpoint is written per disks unit
1888 * recalculate it to reshape position
1889 */
1890 used_disks = imsm_num_data_members(dev, 0);
1891 info->reshape_progress *= used_disks;
d2e6d5d6
AK
1892 dprintf("IMSM: General Migration checkpoint : %llu "
1893 "(%llu) -> read reshape progress : %llu\n",
1894 units, blocks_per_unit, info->reshape_progress);
75156c46
AK
1895
1896 used_disks = imsm_num_data_members(dev, 1);
1897 if (used_disks > 0) {
1898 array_blocks = map->blocks_per_member *
1899 used_disks;
1900 /* round array size down to closest MB
1901 */
1902 info->custom_array_size = (array_blocks
1903 >> SECT_PER_MB_SHIFT)
1904 << SECT_PER_MB_SHIFT;
1905 }
d2e6d5d6 1906 }
1e5c6983
DW
1907 case MIGR_VERIFY:
1908 /* we could emulate the checkpointing of
1909 * 'sync_action=check' migrations, but for now
1910 * we just immediately complete them
1911 */
1912 case MIGR_REBUILD:
1913 /* this is handled by container_content_imsm() */
1e5c6983
DW
1914 case MIGR_STATE_CHANGE:
1915 /* FIXME handle other migrations */
1916 default:
1917 /* we are not dirty, so... */
1918 info->resync_start = MaxSector;
1919 }
b6796ce1 1920 }
301406c9
DW
1921
1922 strncpy(info->name, (char *) dev->volume, MAX_RAID_SERIAL_LEN);
1923 info->name[MAX_RAID_SERIAL_LEN] = 0;
bf5a934a 1924
f35f2525
N
1925 info->array.major_version = -1;
1926 info->array.minor_version = -2;
e207da2f
AW
1927 devname = devnum2devname(st->container_dev);
1928 *info->text_version = '\0';
1929 if (devname)
1930 sprintf(info->text_version, "/%s/%d", devname, info->container_member);
1931 free(devname);
a67dd8cc 1932 info->safe_mode_delay = 4000; /* 4 secs like the Matrix driver */
51006d85 1933 uuid_from_super_imsm(st, info->uuid);
a5d85af7
N
1934
1935 if (dmap) {
1936 int i, j;
1937 for (i=0; i<map_disks; i++) {
1938 dmap[i] = 0;
1939 if (i < info->array.raid_disks) {
1940 struct imsm_disk *dsk;
98130f40 1941 j = get_imsm_disk_idx(dev, i, -1);
a5d85af7
N
1942 dsk = get_imsm_disk(super, j);
1943 if (dsk && (dsk->status & CONFIGURED_DISK))
1944 dmap[i] = 1;
1945 }
1946 }
1947 }
81ac8b4d 1948}
bf5a934a 1949
97b4d0e9
DW
1950static __u8 imsm_check_degraded(struct intel_super *super, struct imsm_dev *dev, int failed);
1951static int imsm_count_failed(struct intel_super *super, struct imsm_dev *dev);
1952
1953static struct imsm_disk *get_imsm_missing(struct intel_super *super, __u8 index)
1954{
1955 struct dl *d;
1956
1957 for (d = super->missing; d; d = d->next)
1958 if (d->index == index)
1959 return &d->disk;
1960 return NULL;
1961}
1962
a5d85af7 1963static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char *map)
4f5bc454
DW
1964{
1965 struct intel_super *super = st->sb;
4f5bc454 1966 struct imsm_disk *disk;
a5d85af7 1967 int map_disks = info->array.raid_disks;
ab3cb6b3
N
1968 int max_enough = -1;
1969 int i;
1970 struct imsm_super *mpb;
4f5bc454 1971
bf5a934a 1972 if (super->current_vol >= 0) {
a5d85af7 1973 getinfo_super_imsm_volume(st, info, map);
bf5a934a
DW
1974 return;
1975 }
95eeceeb 1976 memset(info, 0, sizeof(*info));
d23fe947
DW
1977
1978 /* Set raid_disks to zero so that Assemble will always pull in valid
1979 * spares
1980 */
1981 info->array.raid_disks = 0;
cdddbdbc
DW
1982 info->array.level = LEVEL_CONTAINER;
1983 info->array.layout = 0;
1984 info->array.md_minor = -1;
c2c087e6 1985 info->array.ctime = 0; /* N/A for imsm */
cdddbdbc
DW
1986 info->array.utime = 0;
1987 info->array.chunk_size = 0;
1988
1989 info->disk.major = 0;
1990 info->disk.minor = 0;
cdddbdbc 1991 info->disk.raid_disk = -1;
c2c087e6 1992 info->reshape_active = 0;
f35f2525
N
1993 info->array.major_version = -1;
1994 info->array.minor_version = -2;
c2c087e6 1995 strcpy(info->text_version, "imsm");
a67dd8cc 1996 info->safe_mode_delay = 0;
c2c087e6
DW
1997 info->disk.number = -1;
1998 info->disk.state = 0;
c5afc314 1999 info->name[0] = 0;
921d9e16 2000 info->recovery_start = MaxSector;
c2c087e6 2001
97b4d0e9 2002 /* do we have the all the insync disks that we expect? */
ab3cb6b3 2003 mpb = super->anchor;
97b4d0e9 2004
ab3cb6b3
N
2005 for (i = 0; i < mpb->num_raid_devs; i++) {
2006 struct imsm_dev *dev = get_imsm_dev(super, i);
2007 int failed, enough, j, missing = 0;
2008 struct imsm_map *map;
2009 __u8 state;
97b4d0e9 2010
ab3cb6b3
N
2011 failed = imsm_count_failed(super, dev);
2012 state = imsm_check_degraded(super, dev, failed);
2013 map = get_imsm_map(dev, dev->vol.migr_state);
2014
2015 /* any newly missing disks?
2016 * (catches single-degraded vs double-degraded)
2017 */
2018 for (j = 0; j < map->num_members; j++) {
98130f40 2019 __u32 ord = get_imsm_ord_tbl_ent(dev, i, -1);
ab3cb6b3
N
2020 __u32 idx = ord_to_idx(ord);
2021
2022 if (!(ord & IMSM_ORD_REBUILD) &&
2023 get_imsm_missing(super, idx)) {
2024 missing = 1;
2025 break;
2026 }
97b4d0e9 2027 }
ab3cb6b3
N
2028
2029 if (state == IMSM_T_STATE_FAILED)
2030 enough = -1;
2031 else if (state == IMSM_T_STATE_DEGRADED &&
2032 (state != map->map_state || missing))
2033 enough = 0;
2034 else /* we're normal, or already degraded */
2035 enough = 1;
2036
2037 /* in the missing/failed disk case check to see
2038 * if at least one array is runnable
2039 */
2040 max_enough = max(max_enough, enough);
2041 }
2042 dprintf("%s: enough: %d\n", __func__, max_enough);
2043 info->container_enough = max_enough;
97b4d0e9 2044
4a04ec6c 2045 if (super->disks) {
14e8215b
DW
2046 __u32 reserved = imsm_reserved_sectors(super, super->disks);
2047
b9f594fe 2048 disk = &super->disks->disk;
14e8215b
DW
2049 info->data_offset = __le32_to_cpu(disk->total_blocks) - reserved;
2050 info->component_size = reserved;
25ed7e59 2051 info->disk.state = is_configured(disk) ? (1 << MD_DISK_ACTIVE) : 0;
df474657
DW
2052 /* we don't change info->disk.raid_disk here because
2053 * this state will be finalized in mdmon after we have
2054 * found the 'most fresh' version of the metadata
2055 */
25ed7e59
DW
2056 info->disk.state |= is_failed(disk) ? (1 << MD_DISK_FAULTY) : 0;
2057 info->disk.state |= is_spare(disk) ? 0 : (1 << MD_DISK_SYNC);
cdddbdbc 2058 }
a575e2a7
DW
2059
2060 /* only call uuid_from_super_imsm when this disk is part of a populated container,
2061 * ->compare_super may have updated the 'num_raid_devs' field for spares
2062 */
2063 if (info->disk.state & (1 << MD_DISK_SYNC) || super->anchor->num_raid_devs)
36ba7d48 2064 uuid_from_super_imsm(st, info->uuid);
22e263f6
AC
2065 else
2066 memcpy(info->uuid, uuid_zero, sizeof(uuid_zero));
a5d85af7
N
2067
2068 /* I don't know how to compute 'map' on imsm, so use safe default */
2069 if (map) {
2070 int i;
2071 for (i = 0; i < map_disks; i++)
2072 map[i] = 1;
2073 }
2074
cdddbdbc
DW
2075}
2076
5c4cd5da
AC
2077/* allocates memory and fills disk in mdinfo structure
2078 * for each disk in array */
2079struct mdinfo *getinfo_super_disks_imsm(struct supertype *st)
2080{
2081 struct mdinfo *mddev = NULL;
2082 struct intel_super *super = st->sb;
2083 struct imsm_disk *disk;
2084 int count = 0;
2085 struct dl *dl;
2086 if (!super || !super->disks)
2087 return NULL;
2088 dl = super->disks;
2089 mddev = malloc(sizeof(*mddev));
2090 if (!mddev) {
2091 fprintf(stderr, Name ": Failed to allocate memory.\n");
2092 return NULL;
2093 }
2094 memset(mddev, 0, sizeof(*mddev));
2095 while (dl) {
2096 struct mdinfo *tmp;
2097 disk = &dl->disk;
2098 tmp = malloc(sizeof(*tmp));
2099 if (!tmp) {
2100 fprintf(stderr, Name ": Failed to allocate memory.\n");
2101 if (mddev)
2102 sysfs_free(mddev);
2103 return NULL;
2104 }
2105 memset(tmp, 0, sizeof(*tmp));
2106 if (mddev->devs)
2107 tmp->next = mddev->devs;
2108 mddev->devs = tmp;
2109 tmp->disk.number = count++;
2110 tmp->disk.major = dl->major;
2111 tmp->disk.minor = dl->minor;
2112 tmp->disk.state = is_configured(disk) ?
2113 (1 << MD_DISK_ACTIVE) : 0;
2114 tmp->disk.state |= is_failed(disk) ? (1 << MD_DISK_FAULTY) : 0;
2115 tmp->disk.state |= is_spare(disk) ? 0 : (1 << MD_DISK_SYNC);
2116 tmp->disk.raid_disk = -1;
2117 dl = dl->next;
2118 }
2119 return mddev;
2120}
2121
cdddbdbc
DW
2122static int update_super_imsm(struct supertype *st, struct mdinfo *info,
2123 char *update, char *devname, int verbose,
2124 int uuid_set, char *homehost)
2125{
f352c545
DW
2126 /* For 'assemble' and 'force' we need to return non-zero if any
2127 * change was made. For others, the return value is ignored.
2128 * Update options are:
2129 * force-one : This device looks a bit old but needs to be included,
2130 * update age info appropriately.
2131 * assemble: clear any 'faulty' flag to allow this device to
2132 * be assembled.
2133 * force-array: Array is degraded but being forced, mark it clean
2134 * if that will be needed to assemble it.
2135 *
2136 * newdev: not used ????
2137 * grow: Array has gained a new device - this is currently for
2138 * linear only
2139 * resync: mark as dirty so a resync will happen.
2140 * name: update the name - preserving the homehost
6e46bf34 2141 * uuid: Change the uuid of the array to match watch is given
f352c545
DW
2142 *
2143 * Following are not relevant for this imsm:
2144 * sparc2.2 : update from old dodgey metadata
2145 * super-minor: change the preferred_minor number
2146 * summaries: update redundant counters.
f352c545
DW
2147 * homehost: update the recorded homehost
2148 * _reshape_progress: record new reshape_progress position.
2149 */
6e46bf34
DW
2150 int rv = 1;
2151 struct intel_super *super = st->sb;
2152 struct imsm_super *mpb;
f352c545 2153
6e46bf34
DW
2154 /* we can only update container info */
2155 if (!super || super->current_vol >= 0 || !super->anchor)
2156 return 1;
2157
2158 mpb = super->anchor;
2159
2160 if (strcmp(update, "uuid") == 0 && uuid_set && !info->update_private)
1e2b2765 2161 rv = -1;
6e46bf34
DW
2162 else if (strcmp(update, "uuid") == 0 && uuid_set && info->update_private) {
2163 mpb->orig_family_num = *((__u32 *) info->update_private);
2164 rv = 0;
2165 } else if (strcmp(update, "uuid") == 0) {
2166 __u32 *new_family = malloc(sizeof(*new_family));
2167
2168 /* update orig_family_number with the incoming random
2169 * data, report the new effective uuid, and store the
2170 * new orig_family_num for future updates.
2171 */
2172 if (new_family) {
2173 memcpy(&mpb->orig_family_num, info->uuid, sizeof(__u32));
2174 uuid_from_super_imsm(st, info->uuid);
2175 *new_family = mpb->orig_family_num;
2176 info->update_private = new_family;
2177 rv = 0;
2178 }
2179 } else if (strcmp(update, "assemble") == 0)
2180 rv = 0;
2181 else
1e2b2765 2182 rv = -1;
f352c545 2183
6e46bf34
DW
2184 /* successful update? recompute checksum */
2185 if (rv == 0)
2186 mpb->check_sum = __le32_to_cpu(__gen_imsm_checksum(mpb));
f352c545
DW
2187
2188 return rv;
cdddbdbc
DW
2189}
2190
c2c087e6 2191static size_t disks_to_mpb_size(int disks)
cdddbdbc 2192{
c2c087e6 2193 size_t size;
cdddbdbc 2194
c2c087e6
DW
2195 size = sizeof(struct imsm_super);
2196 size += (disks - 1) * sizeof(struct imsm_disk);
2197 size += 2 * sizeof(struct imsm_dev);
2198 /* up to 2 maps per raid device (-2 for imsm_maps in imsm_dev */
2199 size += (4 - 2) * sizeof(struct imsm_map);
2200 /* 4 possible disk_ord_tbl's */
2201 size += 4 * (disks - 1) * sizeof(__u32);
2202
2203 return size;
2204}
2205
2206static __u64 avail_size_imsm(struct supertype *st, __u64 devsize)
2207{
2208 if (devsize < (MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS))
2209 return 0;
2210
2211 return devsize - (MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS);
cdddbdbc
DW
2212}
2213
ba2de7ba
DW
2214static void free_devlist(struct intel_super *super)
2215{
2216 struct intel_dev *dv;
2217
2218 while (super->devlist) {
2219 dv = super->devlist->next;
2220 free(super->devlist->dev);
2221 free(super->devlist);
2222 super->devlist = dv;
2223 }
2224}
2225
2226static void imsm_copy_dev(struct imsm_dev *dest, struct imsm_dev *src)
2227{
2228 memcpy(dest, src, sizeof_imsm_dev(src, 0));
2229}
2230
cdddbdbc
DW
2231static int compare_super_imsm(struct supertype *st, struct supertype *tst)
2232{
2233 /*
2234 * return:
2235 * 0 same, or first was empty, and second was copied
2236 * 1 second had wrong number
2237 * 2 wrong uuid
2238 * 3 wrong other info
2239 */
2240 struct intel_super *first = st->sb;
2241 struct intel_super *sec = tst->sb;
2242
2243 if (!first) {
2244 st->sb = tst->sb;
2245 tst->sb = NULL;
2246 return 0;
2247 }
8603ea6f
LM
2248 /* in platform dependent environment test if the disks
2249 * use the same Intel hba
2250 */
2251 if (!check_env("IMSM_NO_PLATFORM")) {
ea2bc72b
LM
2252 if (!first->hba || !sec->hba ||
2253 (first->hba->type != sec->hba->type)) {
8603ea6f
LM
2254 fprintf(stderr,
2255 "HBAs of devices does not match %s != %s\n",
ea2bc72b
LM
2256 first->hba ? get_sys_dev_type(first->hba->type) : NULL,
2257 sec->hba ? get_sys_dev_type(sec->hba->type) : NULL);
8603ea6f
LM
2258 return 3;
2259 }
2260 }
cdddbdbc 2261
d23fe947
DW
2262 /* if an anchor does not have num_raid_devs set then it is a free
2263 * floating spare
2264 */
2265 if (first->anchor->num_raid_devs > 0 &&
2266 sec->anchor->num_raid_devs > 0) {
a2b97981
DW
2267 /* Determine if these disks might ever have been
2268 * related. Further disambiguation can only take place
2269 * in load_super_imsm_all
2270 */
2271 __u32 first_family = first->anchor->orig_family_num;
2272 __u32 sec_family = sec->anchor->orig_family_num;
2273
f796af5d
DW
2274 if (memcmp(first->anchor->sig, sec->anchor->sig,
2275 MAX_SIGNATURE_LENGTH) != 0)
2276 return 3;
2277
a2b97981
DW
2278 if (first_family == 0)
2279 first_family = first->anchor->family_num;
2280 if (sec_family == 0)
2281 sec_family = sec->anchor->family_num;
2282
2283 if (first_family != sec_family)
d23fe947 2284 return 3;
f796af5d 2285
d23fe947 2286 }
cdddbdbc 2287
f796af5d 2288
3e372e5a
DW
2289 /* if 'first' is a spare promote it to a populated mpb with sec's
2290 * family number
2291 */
2292 if (first->anchor->num_raid_devs == 0 &&
2293 sec->anchor->num_raid_devs > 0) {
78d30f94 2294 int i;
ba2de7ba
DW
2295 struct intel_dev *dv;
2296 struct imsm_dev *dev;
78d30f94
DW
2297
2298 /* we need to copy raid device info from sec if an allocation
2299 * fails here we don't associate the spare
2300 */
2301 for (i = 0; i < sec->anchor->num_raid_devs; i++) {
ba2de7ba
DW
2302 dv = malloc(sizeof(*dv));
2303 if (!dv)
2304 break;
2305 dev = malloc(sizeof_imsm_dev(get_imsm_dev(sec, i), 1));
2306 if (!dev) {
2307 free(dv);
2308 break;
78d30f94 2309 }
ba2de7ba
DW
2310 dv->dev = dev;
2311 dv->index = i;
2312 dv->next = first->devlist;
2313 first->devlist = dv;
78d30f94 2314 }
709743c5 2315 if (i < sec->anchor->num_raid_devs) {
ba2de7ba
DW
2316 /* allocation failure */
2317 free_devlist(first);
2318 fprintf(stderr, "imsm: failed to associate spare\n");
2319 return 3;
78d30f94 2320 }
3e372e5a 2321 first->anchor->num_raid_devs = sec->anchor->num_raid_devs;
148acb7b 2322 first->anchor->orig_family_num = sec->anchor->orig_family_num;
3e372e5a 2323 first->anchor->family_num = sec->anchor->family_num;
ac6449be 2324 memcpy(first->anchor->sig, sec->anchor->sig, MAX_SIGNATURE_LENGTH);
709743c5
DW
2325 for (i = 0; i < sec->anchor->num_raid_devs; i++)
2326 imsm_copy_dev(get_imsm_dev(first, i), get_imsm_dev(sec, i));
3e372e5a
DW
2327 }
2328
cdddbdbc
DW
2329 return 0;
2330}
2331
0030e8d6
DW
2332static void fd2devname(int fd, char *name)
2333{
2334 struct stat st;
2335 char path[256];
33a6535d 2336 char dname[PATH_MAX];
0030e8d6
DW
2337 char *nm;
2338 int rv;
2339
2340 name[0] = '\0';
2341 if (fstat(fd, &st) != 0)
2342 return;
2343 sprintf(path, "/sys/dev/block/%d:%d",
2344 major(st.st_rdev), minor(st.st_rdev));
2345
2346 rv = readlink(path, dname, sizeof(dname));
2347 if (rv <= 0)
2348 return;
2349
2350 dname[rv] = '\0';
2351 nm = strrchr(dname, '/');
2352 nm++;
2353 snprintf(name, MAX_RAID_SERIAL_LEN, "/dev/%s", nm);
2354}
2355
cdddbdbc
DW
2356extern int scsi_get_serial(int fd, void *buf, size_t buf_len);
2357
2358static int imsm_read_serial(int fd, char *devname,
2359 __u8 serial[MAX_RAID_SERIAL_LEN])
2360{
2361 unsigned char scsi_serial[255];
cdddbdbc
DW
2362 int rv;
2363 int rsp_len;
1f24f035 2364 int len;
316e2bf4
DW
2365 char *dest;
2366 char *src;
2367 char *rsp_buf;
2368 int i;
cdddbdbc
DW
2369
2370 memset(scsi_serial, 0, sizeof(scsi_serial));
cdddbdbc 2371
f9ba0ff1
DW
2372 rv = scsi_get_serial(fd, scsi_serial, sizeof(scsi_serial));
2373
40ebbb9c 2374 if (rv && check_env("IMSM_DEVNAME_AS_SERIAL")) {
f9ba0ff1
DW
2375 memset(serial, 0, MAX_RAID_SERIAL_LEN);
2376 fd2devname(fd, (char *) serial);
0030e8d6
DW
2377 return 0;
2378 }
2379
cdddbdbc
DW
2380 if (rv != 0) {
2381 if (devname)
2382 fprintf(stderr,
2383 Name ": Failed to retrieve serial for %s\n",
2384 devname);
2385 return rv;
2386 }
2387
2388 rsp_len = scsi_serial[3];
03cd4cc8
DW
2389 if (!rsp_len) {
2390 if (devname)
2391 fprintf(stderr,
2392 Name ": Failed to retrieve serial for %s\n",
2393 devname);
2394 return 2;
2395 }
1f24f035 2396 rsp_buf = (char *) &scsi_serial[4];
5c3db629 2397
316e2bf4
DW
2398 /* trim all whitespace and non-printable characters and convert
2399 * ':' to ';'
2400 */
2401 for (i = 0, dest = rsp_buf; i < rsp_len; i++) {
2402 src = &rsp_buf[i];
2403 if (*src > 0x20) {
2404 /* ':' is reserved for use in placeholder serial
2405 * numbers for missing disks
2406 */
2407 if (*src == ':')
2408 *dest++ = ';';
2409 else
2410 *dest++ = *src;
2411 }
2412 }
2413 len = dest - rsp_buf;
2414 dest = rsp_buf;
2415
2416 /* truncate leading characters */
2417 if (len > MAX_RAID_SERIAL_LEN) {
2418 dest += len - MAX_RAID_SERIAL_LEN;
1f24f035 2419 len = MAX_RAID_SERIAL_LEN;
316e2bf4 2420 }
5c3db629 2421
5c3db629 2422 memset(serial, 0, MAX_RAID_SERIAL_LEN);
316e2bf4 2423 memcpy(serial, dest, len);
cdddbdbc
DW
2424
2425 return 0;
2426}
2427
1f24f035
DW
2428static int serialcmp(__u8 *s1, __u8 *s2)
2429{
2430 return strncmp((char *) s1, (char *) s2, MAX_RAID_SERIAL_LEN);
2431}
2432
2433static void serialcpy(__u8 *dest, __u8 *src)
2434{
2435 strncpy((char *) dest, (char *) src, MAX_RAID_SERIAL_LEN);
2436}
2437
1799c9e8 2438#ifndef MDASSEMBLE
54c2c1ea
DW
2439static struct dl *serial_to_dl(__u8 *serial, struct intel_super *super)
2440{
2441 struct dl *dl;
2442
2443 for (dl = super->disks; dl; dl = dl->next)
2444 if (serialcmp(dl->serial, serial) == 0)
2445 break;
2446
2447 return dl;
2448}
1799c9e8 2449#endif
54c2c1ea 2450
a2b97981
DW
2451static struct imsm_disk *
2452__serial_to_disk(__u8 *serial, struct imsm_super *mpb, int *idx)
2453{
2454 int i;
2455
2456 for (i = 0; i < mpb->num_disks; i++) {
2457 struct imsm_disk *disk = __get_imsm_disk(mpb, i);
2458
2459 if (serialcmp(disk->serial, serial) == 0) {
2460 if (idx)
2461 *idx = i;
2462 return disk;
2463 }
2464 }
2465
2466 return NULL;
2467}
2468
cdddbdbc
DW
2469static int
2470load_imsm_disk(int fd, struct intel_super *super, char *devname, int keep_fd)
2471{
a2b97981 2472 struct imsm_disk *disk;
cdddbdbc
DW
2473 struct dl *dl;
2474 struct stat stb;
cdddbdbc 2475 int rv;
a2b97981 2476 char name[40];
d23fe947
DW
2477 __u8 serial[MAX_RAID_SERIAL_LEN];
2478
2479 rv = imsm_read_serial(fd, devname, serial);
2480
2481 if (rv != 0)
2482 return 2;
2483
a2b97981 2484 dl = calloc(1, sizeof(*dl));
b9f594fe 2485 if (!dl) {
cdddbdbc
DW
2486 if (devname)
2487 fprintf(stderr,
2488 Name ": failed to allocate disk buffer for %s\n",
2489 devname);
2490 return 2;
2491 }
cdddbdbc 2492
a2b97981
DW
2493 fstat(fd, &stb);
2494 dl->major = major(stb.st_rdev);
2495 dl->minor = minor(stb.st_rdev);
2496 dl->next = super->disks;
2497 dl->fd = keep_fd ? fd : -1;
2498 assert(super->disks == NULL);
2499 super->disks = dl;
2500 serialcpy(dl->serial, serial);
2501 dl->index = -2;
2502 dl->e = NULL;
2503 fd2devname(fd, name);
2504 if (devname)
2505 dl->devname = strdup(devname);
2506 else
2507 dl->devname = strdup(name);
cdddbdbc 2508
d23fe947 2509 /* look up this disk's index in the current anchor */
a2b97981
DW
2510 disk = __serial_to_disk(dl->serial, super->anchor, &dl->index);
2511 if (disk) {
2512 dl->disk = *disk;
2513 /* only set index on disks that are a member of a
2514 * populated contianer, i.e. one with raid_devs
2515 */
2516 if (is_failed(&dl->disk))
3f6efecc 2517 dl->index = -2;
a2b97981
DW
2518 else if (is_spare(&dl->disk))
2519 dl->index = -1;
3f6efecc
DW
2520 }
2521
949c47a0
DW
2522 return 0;
2523}
2524
0e600426 2525#ifndef MDASSEMBLE
0c046afd
DW
2526/* When migrating map0 contains the 'destination' state while map1
2527 * contains the current state. When not migrating map0 contains the
2528 * current state. This routine assumes that map[0].map_state is set to
2529 * the current array state before being called.
2530 *
2531 * Migration is indicated by one of the following states
2532 * 1/ Idle (migr_state=0 map0state=normal||unitialized||degraded||failed)
e3bba0e0 2533 * 2/ Initialize (migr_state=1 migr_type=MIGR_INIT map0state=normal
0c046afd 2534 * map1state=unitialized)
1484e727 2535 * 3/ Repair (Resync) (migr_state=1 migr_type=MIGR_REPAIR map0state=normal
0c046afd 2536 * map1state=normal)
e3bba0e0 2537 * 4/ Rebuild (migr_state=1 migr_type=MIGR_REBUILD map0state=normal
0c046afd
DW
2538 * map1state=degraded)
2539 */
0556e1a2 2540static void migrate(struct imsm_dev *dev, __u8 to_state, int migr_type)
3393c6af 2541{
0c046afd 2542 struct imsm_map *dest;
3393c6af
DW
2543 struct imsm_map *src = get_imsm_map(dev, 0);
2544
0c046afd 2545 dev->vol.migr_state = 1;
1484e727 2546 set_migr_type(dev, migr_type);
f8f603f1 2547 dev->vol.curr_migr_unit = 0;
0c046afd
DW
2548 dest = get_imsm_map(dev, 1);
2549
0556e1a2 2550 /* duplicate and then set the target end state in map[0] */
3393c6af 2551 memcpy(dest, src, sizeof_imsm_map(src));
28bce06f
AK
2552 if ((migr_type == MIGR_REBUILD) ||
2553 (migr_type == MIGR_GEN_MIGR)) {
0556e1a2
DW
2554 __u32 ord;
2555 int i;
2556
2557 for (i = 0; i < src->num_members; i++) {
2558 ord = __le32_to_cpu(src->disk_ord_tbl[i]);
2559 set_imsm_ord_tbl_ent(src, i, ord_to_idx(ord));
2560 }
2561 }
2562
0c046afd 2563 src->map_state = to_state;
949c47a0 2564}
f8f603f1
DW
2565
2566static void end_migration(struct imsm_dev *dev, __u8 map_state)
2567{
2568 struct imsm_map *map = get_imsm_map(dev, 0);
0556e1a2 2569 struct imsm_map *prev = get_imsm_map(dev, dev->vol.migr_state);
28bce06f 2570 int i, j;
0556e1a2
DW
2571
2572 /* merge any IMSM_ORD_REBUILD bits that were not successfully
2573 * completed in the last migration.
2574 *
28bce06f 2575 * FIXME add support for raid-level-migration
0556e1a2
DW
2576 */
2577 for (i = 0; i < prev->num_members; i++)
28bce06f
AK
2578 for (j = 0; j < map->num_members; j++)
2579 /* during online capacity expansion
2580 * disks position can be changed if takeover is used
2581 */
2582 if (ord_to_idx(map->disk_ord_tbl[j]) ==
2583 ord_to_idx(prev->disk_ord_tbl[i])) {
2584 map->disk_ord_tbl[j] |= prev->disk_ord_tbl[i];
2585 break;
2586 }
f8f603f1
DW
2587
2588 dev->vol.migr_state = 0;
28bce06f 2589 dev->vol.migr_type = 0;
f8f603f1
DW
2590 dev->vol.curr_migr_unit = 0;
2591 map->map_state = map_state;
2592}
0e600426 2593#endif
949c47a0
DW
2594
2595static int parse_raid_devices(struct intel_super *super)
2596{
2597 int i;
2598 struct imsm_dev *dev_new;
4d7b1503 2599 size_t len, len_migr;
401d313b 2600 size_t max_len = 0;
4d7b1503
DW
2601 size_t space_needed = 0;
2602 struct imsm_super *mpb = super->anchor;
949c47a0
DW
2603
2604 for (i = 0; i < super->anchor->num_raid_devs; i++) {
2605 struct imsm_dev *dev_iter = __get_imsm_dev(super->anchor, i);
ba2de7ba 2606 struct intel_dev *dv;
949c47a0 2607
4d7b1503
DW
2608 len = sizeof_imsm_dev(dev_iter, 0);
2609 len_migr = sizeof_imsm_dev(dev_iter, 1);
2610 if (len_migr > len)
2611 space_needed += len_migr - len;
2612
ba2de7ba
DW
2613 dv = malloc(sizeof(*dv));
2614 if (!dv)
2615 return 1;
401d313b
AK
2616 if (max_len < len_migr)
2617 max_len = len_migr;
2618 if (max_len > len_migr)
2619 space_needed += max_len - len_migr;
2620 dev_new = malloc(max_len);
ba2de7ba
DW
2621 if (!dev_new) {
2622 free(dv);
949c47a0 2623 return 1;
ba2de7ba 2624 }
949c47a0 2625 imsm_copy_dev(dev_new, dev_iter);
ba2de7ba
DW
2626 dv->dev = dev_new;
2627 dv->index = i;
2628 dv->next = super->devlist;
2629 super->devlist = dv;
949c47a0 2630 }
cdddbdbc 2631
4d7b1503
DW
2632 /* ensure that super->buf is large enough when all raid devices
2633 * are migrating
2634 */
2635 if (__le32_to_cpu(mpb->mpb_size) + space_needed > super->len) {
2636 void *buf;
2637
2638 len = ROUND_UP(__le32_to_cpu(mpb->mpb_size) + space_needed, 512);
2639 if (posix_memalign(&buf, 512, len) != 0)
2640 return 1;
2641
1f45a8ad
DW
2642 memcpy(buf, super->buf, super->len);
2643 memset(buf + super->len, 0, len - super->len);
4d7b1503
DW
2644 free(super->buf);
2645 super->buf = buf;
2646 super->len = len;
2647 }
2648
cdddbdbc
DW
2649 return 0;
2650}
2651
604b746f
JD
2652/* retrieve a pointer to the bbm log which starts after all raid devices */
2653struct bbm_log *__get_imsm_bbm_log(struct imsm_super *mpb)
2654{
2655 void *ptr = NULL;
2656
2657 if (__le32_to_cpu(mpb->bbm_log_size)) {
2658 ptr = mpb;
2659 ptr += mpb->mpb_size - __le32_to_cpu(mpb->bbm_log_size);
2660 }
2661
2662 return ptr;
2663}
2664
d23fe947 2665static void __free_imsm(struct intel_super *super, int free_disks);
9ca2c81c 2666
cdddbdbc 2667/* load_imsm_mpb - read matrix metadata
f2f5c343 2668 * allocates super->mpb to be freed by free_imsm
cdddbdbc
DW
2669 */
2670static int load_imsm_mpb(int fd, struct intel_super *super, char *devname)
2671{
2672 unsigned long long dsize;
cdddbdbc
DW
2673 unsigned long long sectors;
2674 struct stat;
6416d527 2675 struct imsm_super *anchor;
cdddbdbc
DW
2676 __u32 check_sum;
2677
cdddbdbc 2678 get_dev_size(fd, NULL, &dsize);
64436f06
N
2679 if (dsize < 1024) {
2680 if (devname)
2681 fprintf(stderr,
2682 Name ": %s: device to small for imsm\n",
2683 devname);
2684 return 1;
2685 }
cdddbdbc
DW
2686
2687 if (lseek64(fd, dsize - (512 * 2), SEEK_SET) < 0) {
2688 if (devname)
2689 fprintf(stderr,
2690 Name ": Cannot seek to anchor block on %s: %s\n",
2691 devname, strerror(errno));
2692 return 1;
2693 }
2694
949c47a0 2695 if (posix_memalign((void**)&anchor, 512, 512) != 0) {
ad97895e
DW
2696 if (devname)
2697 fprintf(stderr,
2698 Name ": Failed to allocate imsm anchor buffer"
2699 " on %s\n", devname);
2700 return 1;
2701 }
949c47a0 2702 if (read(fd, anchor, 512) != 512) {
cdddbdbc
DW
2703 if (devname)
2704 fprintf(stderr,
2705 Name ": Cannot read anchor block on %s: %s\n",
2706 devname, strerror(errno));
6416d527 2707 free(anchor);
cdddbdbc
DW
2708 return 1;
2709 }
2710
6416d527 2711 if (strncmp((char *) anchor->sig, MPB_SIGNATURE, MPB_SIG_LEN) != 0) {
cdddbdbc
DW
2712 if (devname)
2713 fprintf(stderr,
2714 Name ": no IMSM anchor on %s\n", devname);
6416d527 2715 free(anchor);
cdddbdbc
DW
2716 return 2;
2717 }
2718
d23fe947 2719 __free_imsm(super, 0);
f2f5c343
LM
2720 /* reload capability and hba */
2721
2722 /* capability and hba must be updated with new super allocation */
d424212e 2723 find_intel_hba_capability(fd, super, devname);
949c47a0
DW
2724 super->len = ROUND_UP(anchor->mpb_size, 512);
2725 if (posix_memalign(&super->buf, 512, super->len) != 0) {
cdddbdbc
DW
2726 if (devname)
2727 fprintf(stderr,
2728 Name ": unable to allocate %zu byte mpb buffer\n",
949c47a0 2729 super->len);
6416d527 2730 free(anchor);
cdddbdbc
DW
2731 return 2;
2732 }
949c47a0 2733 memcpy(super->buf, anchor, 512);
cdddbdbc 2734
6416d527
NB
2735 sectors = mpb_sectors(anchor) - 1;
2736 free(anchor);
949c47a0 2737 if (!sectors) {
ecf45690
DW
2738 check_sum = __gen_imsm_checksum(super->anchor);
2739 if (check_sum != __le32_to_cpu(super->anchor->check_sum)) {
2740 if (devname)
2741 fprintf(stderr,
2742 Name ": IMSM checksum %x != %x on %s\n",
2743 check_sum,
2744 __le32_to_cpu(super->anchor->check_sum),
2745 devname);
2746 return 2;
2747 }
2748
a2b97981 2749 return 0;
949c47a0 2750 }
cdddbdbc
DW
2751
2752 /* read the extended mpb */
2753 if (lseek64(fd, dsize - (512 * (2 + sectors)), SEEK_SET) < 0) {
2754 if (devname)
2755 fprintf(stderr,
2756 Name ": Cannot seek to extended mpb on %s: %s\n",
2757 devname, strerror(errno));
2758 return 1;
2759 }
2760
f21e18ca 2761 if ((unsigned)read(fd, super->buf + 512, super->len - 512) != super->len - 512) {
cdddbdbc
DW
2762 if (devname)
2763 fprintf(stderr,
2764 Name ": Cannot read extended mpb on %s: %s\n",
2765 devname, strerror(errno));
2766 return 2;
2767 }
2768
949c47a0
DW
2769 check_sum = __gen_imsm_checksum(super->anchor);
2770 if (check_sum != __le32_to_cpu(super->anchor->check_sum)) {
cdddbdbc
DW
2771 if (devname)
2772 fprintf(stderr,
2773 Name ": IMSM checksum %x != %x on %s\n",
949c47a0 2774 check_sum, __le32_to_cpu(super->anchor->check_sum),
cdddbdbc 2775 devname);
db575f3b 2776 return 3;
cdddbdbc
DW
2777 }
2778
604b746f
JD
2779 /* FIXME the BBM log is disk specific so we cannot use this global
2780 * buffer for all disks. Ok for now since we only look at the global
2781 * bbm_log_size parameter to gate assembly
2782 */
2783 super->bbm_log = __get_imsm_bbm_log(super->anchor);
2784
a2b97981
DW
2785 return 0;
2786}
2787
2788static int
2789load_and_parse_mpb(int fd, struct intel_super *super, char *devname, int keep_fd)
2790{
2791 int err;
2792
2793 err = load_imsm_mpb(fd, super, devname);
2794 if (err)
2795 return err;
2796 err = load_imsm_disk(fd, super, devname, keep_fd);
2797 if (err)
2798 return err;
2799 err = parse_raid_devices(super);
4d7b1503 2800
a2b97981 2801 return err;
cdddbdbc
DW
2802}
2803
ae6aad82
DW
2804static void __free_imsm_disk(struct dl *d)
2805{
2806 if (d->fd >= 0)
2807 close(d->fd);
2808 if (d->devname)
2809 free(d->devname);
0dcecb2e
DW
2810 if (d->e)
2811 free(d->e);
ae6aad82
DW
2812 free(d);
2813
2814}
1a64be56 2815
cdddbdbc
DW
2816static void free_imsm_disks(struct intel_super *super)
2817{
47ee5a45 2818 struct dl *d;
cdddbdbc 2819
47ee5a45
DW
2820 while (super->disks) {
2821 d = super->disks;
cdddbdbc 2822 super->disks = d->next;
ae6aad82 2823 __free_imsm_disk(d);
cdddbdbc 2824 }
cb82edca
AK
2825 while (super->disk_mgmt_list) {
2826 d = super->disk_mgmt_list;
2827 super->disk_mgmt_list = d->next;
2828 __free_imsm_disk(d);
2829 }
47ee5a45
DW
2830 while (super->missing) {
2831 d = super->missing;
2832 super->missing = d->next;
2833 __free_imsm_disk(d);
2834 }
2835
cdddbdbc
DW
2836}
2837
9ca2c81c 2838/* free all the pieces hanging off of a super pointer */
d23fe947 2839static void __free_imsm(struct intel_super *super, int free_disks)
cdddbdbc 2840{
88654014
LM
2841 struct intel_hba *elem, *next;
2842
9ca2c81c 2843 if (super->buf) {
949c47a0 2844 free(super->buf);
9ca2c81c
DW
2845 super->buf = NULL;
2846 }
f2f5c343
LM
2847 /* unlink capability description */
2848 super->orom = NULL;
d23fe947
DW
2849 if (free_disks)
2850 free_imsm_disks(super);
ba2de7ba 2851 free_devlist(super);
88654014
LM
2852 elem = super->hba;
2853 while (elem) {
2854 if (elem->path)
2855 free((void *)elem->path);
2856 next = elem->next;
2857 free(elem);
2858 elem = next;
88c32bb1 2859 }
88654014 2860 super->hba = NULL;
cdddbdbc
DW
2861}
2862
9ca2c81c
DW
2863static void free_imsm(struct intel_super *super)
2864{
d23fe947 2865 __free_imsm(super, 1);
9ca2c81c
DW
2866 free(super);
2867}
cdddbdbc
DW
2868
2869static void free_super_imsm(struct supertype *st)
2870{
2871 struct intel_super *super = st->sb;
2872
2873 if (!super)
2874 return;
2875
2876 free_imsm(super);
2877 st->sb = NULL;
2878}
2879
49133e57 2880static struct intel_super *alloc_super(void)
c2c087e6
DW
2881{
2882 struct intel_super *super = malloc(sizeof(*super));
2883
2884 if (super) {
2885 memset(super, 0, sizeof(*super));
bf5a934a 2886 super->current_vol = -1;
0dcecb2e 2887 super->create_offset = ~((__u32 ) 0);
c2c087e6 2888 }
c2c087e6
DW
2889 return super;
2890}
2891
f0f5a016
LM
2892/*
2893 * find and allocate hba and OROM/EFI based on valid fd of RAID component device
2894 */
d424212e 2895static int find_intel_hba_capability(int fd, struct intel_super *super, char *devname)
f0f5a016
LM
2896{
2897 struct sys_dev *hba_name;
2898 int rv = 0;
2899
2900 if ((fd < 0) || check_env("IMSM_NO_PLATFORM")) {
f2f5c343 2901 super->orom = NULL;
f0f5a016
LM
2902 super->hba = NULL;
2903 return 0;
2904 }
2905 hba_name = find_disk_attached_hba(fd, NULL);
2906 if (!hba_name) {
d424212e 2907 if (devname)
f0f5a016
LM
2908 fprintf(stderr,
2909 Name ": %s is not attached to Intel(R) RAID controller.\n",
d424212e 2910 devname);
f0f5a016
LM
2911 return 1;
2912 }
2913 rv = attach_hba_to_super(super, hba_name);
2914 if (rv == 2) {
d424212e
N
2915 if (devname) {
2916 struct intel_hba *hba = super->hba;
f0f5a016 2917
f0f5a016
LM
2918 fprintf(stderr, Name ": %s is attached to Intel(R) %s RAID "
2919 "controller (%s),\n"
2920 " but the container is assigned to Intel(R) "
2921 "%s RAID controller (",
d424212e 2922 devname,
f0f5a016
LM
2923 hba_name->path,
2924 hba_name->pci_id ? : "Err!",
2925 get_sys_dev_type(hba_name->type));
2926
f0f5a016
LM
2927 while (hba) {
2928 fprintf(stderr, "%s", hba->pci_id ? : "Err!");
2929 if (hba->next)
2930 fprintf(stderr, ", ");
2931 hba = hba->next;
2932 }
2933
2934 fprintf(stderr, ").\n"
2935 " Mixing devices attached to different controllers "
2936 "is not allowed.\n");
2937 }
2938 free_sys_dev(&hba_name);
2939 return 2;
2940 }
f2f5c343 2941 super->orom = find_imsm_capability(hba_name->type);
f0f5a016 2942 free_sys_dev(&hba_name);
f2f5c343
LM
2943 if (!super->orom)
2944 return 3;
f0f5a016
LM
2945 return 0;
2946}
2947
cdddbdbc 2948#ifndef MDASSEMBLE
47ee5a45
DW
2949/* find_missing - helper routine for load_super_imsm_all that identifies
2950 * disks that have disappeared from the system. This routine relies on
2951 * the mpb being uptodate, which it is at load time.
2952 */
2953static int find_missing(struct intel_super *super)
2954{
2955 int i;
2956 struct imsm_super *mpb = super->anchor;
2957 struct dl *dl;
2958 struct imsm_disk *disk;
47ee5a45
DW
2959
2960 for (i = 0; i < mpb->num_disks; i++) {
2961 disk = __get_imsm_disk(mpb, i);
54c2c1ea 2962 dl = serial_to_dl(disk->serial, super);
47ee5a45
DW
2963 if (dl)
2964 continue;
47ee5a45
DW
2965
2966 dl = malloc(sizeof(*dl));
2967 if (!dl)
2968 return 1;
2969 dl->major = 0;
2970 dl->minor = 0;
2971 dl->fd = -1;
2972 dl->devname = strdup("missing");
2973 dl->index = i;
2974 serialcpy(dl->serial, disk->serial);
2975 dl->disk = *disk;
689c9bf3 2976 dl->e = NULL;
47ee5a45
DW
2977 dl->next = super->missing;
2978 super->missing = dl;
2979 }
2980
2981 return 0;
2982}
2983
a2b97981
DW
2984static struct intel_disk *disk_list_get(__u8 *serial, struct intel_disk *disk_list)
2985{
2986 struct intel_disk *idisk = disk_list;
2987
2988 while (idisk) {
2989 if (serialcmp(idisk->disk.serial, serial) == 0)
2990 break;
2991 idisk = idisk->next;
2992 }
2993
2994 return idisk;
2995}
2996
2997static int __prep_thunderdome(struct intel_super **table, int tbl_size,
2998 struct intel_super *super,
2999 struct intel_disk **disk_list)
3000{
3001 struct imsm_disk *d = &super->disks->disk;
3002 struct imsm_super *mpb = super->anchor;
3003 int i, j;
3004
3005 for (i = 0; i < tbl_size; i++) {
3006 struct imsm_super *tbl_mpb = table[i]->anchor;
3007 struct imsm_disk *tbl_d = &table[i]->disks->disk;
3008
3009 if (tbl_mpb->family_num == mpb->family_num) {
3010 if (tbl_mpb->check_sum == mpb->check_sum) {
3011 dprintf("%s: mpb from %d:%d matches %d:%d\n",
3012 __func__, super->disks->major,
3013 super->disks->minor,
3014 table[i]->disks->major,
3015 table[i]->disks->minor);
3016 break;
3017 }
3018
3019 if (((is_configured(d) && !is_configured(tbl_d)) ||
3020 is_configured(d) == is_configured(tbl_d)) &&
3021 tbl_mpb->generation_num < mpb->generation_num) {
3022 /* current version of the mpb is a
3023 * better candidate than the one in
3024 * super_table, but copy over "cross
3025 * generational" status
3026 */
3027 struct intel_disk *idisk;
3028
3029 dprintf("%s: mpb from %d:%d replaces %d:%d\n",
3030 __func__, super->disks->major,
3031 super->disks->minor,
3032 table[i]->disks->major,
3033 table[i]->disks->minor);
3034
3035 idisk = disk_list_get(tbl_d->serial, *disk_list);
3036 if (idisk && is_failed(&idisk->disk))
3037 tbl_d->status |= FAILED_DISK;
3038 break;
3039 } else {
3040 struct intel_disk *idisk;
3041 struct imsm_disk *disk;
3042
3043 /* tbl_mpb is more up to date, but copy
3044 * over cross generational status before
3045 * returning
3046 */
3047 disk = __serial_to_disk(d->serial, mpb, NULL);
3048 if (disk && is_failed(disk))
3049 d->status |= FAILED_DISK;
3050
3051 idisk = disk_list_get(d->serial, *disk_list);
3052 if (idisk) {
3053 idisk->owner = i;
3054 if (disk && is_configured(disk))
3055 idisk->disk.status |= CONFIGURED_DISK;
3056 }
3057
3058 dprintf("%s: mpb from %d:%d prefer %d:%d\n",
3059 __func__, super->disks->major,
3060 super->disks->minor,
3061 table[i]->disks->major,
3062 table[i]->disks->minor);
3063
3064 return tbl_size;
3065 }
3066 }
3067 }
3068
3069 if (i >= tbl_size)
3070 table[tbl_size++] = super;
3071 else
3072 table[i] = super;
3073
3074 /* update/extend the merged list of imsm_disk records */
3075 for (j = 0; j < mpb->num_disks; j++) {
3076 struct imsm_disk *disk = __get_imsm_disk(mpb, j);
3077 struct intel_disk *idisk;
3078
3079 idisk = disk_list_get(disk->serial, *disk_list);
3080 if (idisk) {
3081 idisk->disk.status |= disk->status;
3082 if (is_configured(&idisk->disk) ||
3083 is_failed(&idisk->disk))
3084 idisk->disk.status &= ~(SPARE_DISK);
3085 } else {
3086 idisk = calloc(1, sizeof(*idisk));
3087 if (!idisk)
3088 return -1;
3089 idisk->owner = IMSM_UNKNOWN_OWNER;
3090 idisk->disk = *disk;
3091 idisk->next = *disk_list;
3092 *disk_list = idisk;
3093 }
3094
3095 if (serialcmp(idisk->disk.serial, d->serial) == 0)
3096 idisk->owner = i;
3097 }
3098
3099 return tbl_size;
3100}
3101
3102static struct intel_super *
3103validate_members(struct intel_super *super, struct intel_disk *disk_list,
3104 const int owner)
3105{
3106 struct imsm_super *mpb = super->anchor;
3107 int ok_count = 0;
3108 int i;
3109
3110 for (i = 0; i < mpb->num_disks; i++) {
3111 struct imsm_disk *disk = __get_imsm_disk(mpb, i);
3112 struct intel_disk *idisk;
3113
3114 idisk = disk_list_get(disk->serial, disk_list);
3115 if (idisk) {
3116 if (idisk->owner == owner ||
3117 idisk->owner == IMSM_UNKNOWN_OWNER)
3118 ok_count++;
3119 else
3120 dprintf("%s: '%.16s' owner %d != %d\n",
3121 __func__, disk->serial, idisk->owner,
3122 owner);
3123 } else {
3124 dprintf("%s: unknown disk %x [%d]: %.16s\n",
3125 __func__, __le32_to_cpu(mpb->family_num), i,
3126 disk->serial);
3127 break;
3128 }
3129 }
3130
3131 if (ok_count == mpb->num_disks)
3132 return super;
3133 return NULL;
3134}
3135
3136static void show_conflicts(__u32 family_num, struct intel_super *super_list)
3137{
3138 struct intel_super *s;
3139
3140 for (s = super_list; s; s = s->next) {
3141 if (family_num != s->anchor->family_num)
3142 continue;
3143 fprintf(stderr, "Conflict, offlining family %#x on '%s'\n",
3144 __le32_to_cpu(family_num), s->disks->devname);
3145 }
3146}
3147
3148static struct intel_super *
3149imsm_thunderdome(struct intel_super **super_list, int len)
3150{
3151 struct intel_super *super_table[len];
3152 struct intel_disk *disk_list = NULL;
3153 struct intel_super *champion, *spare;
3154 struct intel_super *s, **del;
3155 int tbl_size = 0;
3156 int conflict;
3157 int i;
3158
3159 memset(super_table, 0, sizeof(super_table));
3160 for (s = *super_list; s; s = s->next)
3161 tbl_size = __prep_thunderdome(super_table, tbl_size, s, &disk_list);
3162
3163 for (i = 0; i < tbl_size; i++) {
3164 struct imsm_disk *d;
3165 struct intel_disk *idisk;
3166 struct imsm_super *mpb = super_table[i]->anchor;
3167
3168 s = super_table[i];
3169 d = &s->disks->disk;
3170
3171 /* 'd' must appear in merged disk list for its
3172 * configuration to be valid
3173 */
3174 idisk = disk_list_get(d->serial, disk_list);
3175 if (idisk && idisk->owner == i)
3176 s = validate_members(s, disk_list, i);
3177 else
3178 s = NULL;
3179
3180 if (!s)
3181 dprintf("%s: marking family: %#x from %d:%d offline\n",
3182 __func__, mpb->family_num,
3183 super_table[i]->disks->major,
3184 super_table[i]->disks->minor);
3185 super_table[i] = s;
3186 }
3187
3188 /* This is where the mdadm implementation differs from the Windows
3189 * driver which has no strict concept of a container. We can only
3190 * assemble one family from a container, so when returning a prodigal
3191 * array member to this system the code will not be able to disambiguate
3192 * the container contents that should be assembled ("foreign" versus
3193 * "local"). It requires user intervention to set the orig_family_num
3194 * to a new value to establish a new container. The Windows driver in
3195 * this situation fixes up the volume name in place and manages the
3196 * foreign array as an independent entity.
3197 */
3198 s = NULL;
3199 spare = NULL;
3200 conflict = 0;
3201 for (i = 0; i < tbl_size; i++) {
3202 struct intel_super *tbl_ent = super_table[i];
3203 int is_spare = 0;
3204
3205 if (!tbl_ent)
3206 continue;
3207
3208 if (tbl_ent->anchor->num_raid_devs == 0) {
3209 spare = tbl_ent;
3210 is_spare = 1;
3211 }
3212
3213 if (s && !is_spare) {
3214 show_conflicts(tbl_ent->anchor->family_num, *super_list);
3215 conflict++;
3216 } else if (!s && !is_spare)
3217 s = tbl_ent;
3218 }
3219
3220 if (!s)
3221 s = spare;
3222 if (!s) {
3223 champion = NULL;
3224 goto out;
3225 }
3226 champion = s;
3227
3228 if (conflict)
3229 fprintf(stderr, "Chose family %#x on '%s', "
3230 "assemble conflicts to new container with '--update=uuid'\n",
3231 __le32_to_cpu(s->anchor->family_num), s->disks->devname);
3232
3233 /* collect all dl's onto 'champion', and update them to
3234 * champion's version of the status
3235 */
3236 for (s = *super_list; s; s = s->next) {
3237 struct imsm_super *mpb = champion->anchor;
3238 struct dl *dl = s->disks;
3239
3240 if (s == champion)
3241 continue;
3242
3243 for (i = 0; i < mpb->num_disks; i++) {
3244 struct imsm_disk *disk;
3245
3246 disk = __serial_to_disk(dl->serial, mpb, &dl->index);
3247 if (disk) {
3248 dl->disk = *disk;
3249 /* only set index on disks that are a member of
3250 * a populated contianer, i.e. one with
3251 * raid_devs
3252 */
3253 if (is_failed(&dl->disk))
3254 dl->index = -2;
3255 else if (is_spare(&dl->disk))
3256 dl->index = -1;
3257 break;
3258 }
3259 }
3260
3261 if (i >= mpb->num_disks) {
3262 struct intel_disk *idisk;
3263
3264 idisk = disk_list_get(dl->serial, disk_list);
ecf408e9 3265 if (idisk && is_spare(&idisk->disk) &&
a2b97981
DW
3266 !is_failed(&idisk->disk) && !is_configured(&idisk->disk))
3267 dl->index = -1;
3268 else {
3269 dl->index = -2;
3270 continue;
3271 }
3272 }
3273
3274 dl->next = champion->disks;
3275 champion->disks = dl;
3276 s->disks = NULL;
3277 }
3278
3279 /* delete 'champion' from super_list */
3280 for (del = super_list; *del; ) {
3281 if (*del == champion) {
3282 *del = (*del)->next;
3283 break;
3284 } else
3285 del = &(*del)->next;
3286 }
3287 champion->next = NULL;
3288
3289 out:
3290 while (disk_list) {
3291 struct intel_disk *idisk = disk_list;
3292
3293 disk_list = disk_list->next;
3294 free(idisk);
3295 }
3296
3297 return champion;
3298}
3299
cdddbdbc 3300static int load_super_imsm_all(struct supertype *st, int fd, void **sbp,
e1902a7b 3301 char *devname)
cdddbdbc
DW
3302{
3303 struct mdinfo *sra;
a2b97981
DW
3304 struct intel_super *super_list = NULL;
3305 struct intel_super *super = NULL;
db575f3b 3306 int devnum = fd2devnum(fd);
a2b97981 3307 struct mdinfo *sd;
db575f3b 3308 int retry;
a2b97981
DW
3309 int err = 0;
3310 int i;
dab4a513
DW
3311
3312 /* check if 'fd' an opened container */
b526e52d 3313 sra = sysfs_read(fd, 0, GET_LEVEL|GET_VERSION|GET_DEVS|GET_STATE);
cdddbdbc
DW
3314 if (!sra)
3315 return 1;
3316
3317 if (sra->array.major_version != -1 ||
3318 sra->array.minor_version != -2 ||
1602d52c
AW
3319 strcmp(sra->text_version, "imsm") != 0) {
3320 err = 1;
3321 goto error;
3322 }
a2b97981
DW
3323 /* load all mpbs */
3324 for (sd = sra->devs, i = 0; sd; sd = sd->next, i++) {
49133e57 3325 struct intel_super *s = alloc_super();
7a6ecd55 3326 char nm[32];
a2b97981 3327 int dfd;
f2f5c343 3328 int rv;
a2b97981
DW
3329
3330 err = 1;
3331 if (!s)
3332 goto error;
3333 s->next = super_list;
3334 super_list = s;
cdddbdbc 3335
a2b97981 3336 err = 2;
cdddbdbc 3337 sprintf(nm, "%d:%d", sd->disk.major, sd->disk.minor);
e1902a7b 3338 dfd = dev_open(nm, O_RDWR);
a2b97981
DW
3339 if (dfd < 0)
3340 goto error;
3341
d424212e 3342 rv = find_intel_hba_capability(dfd, s, devname);
f2f5c343
LM
3343 /* no orom/efi or non-intel hba of the disk */
3344 if (rv != 0)
3345 goto error;
3346
e1902a7b 3347 err = load_and_parse_mpb(dfd, s, NULL, 1);
db575f3b
DW
3348
3349 /* retry the load if we might have raced against mdmon */
a2b97981 3350 if (err == 3 && mdmon_running(devnum))
db575f3b
DW
3351 for (retry = 0; retry < 3; retry++) {
3352 usleep(3000);
e1902a7b 3353 err = load_and_parse_mpb(dfd, s, NULL, 1);
a2b97981 3354 if (err != 3)
db575f3b
DW
3355 break;
3356 }
a2b97981
DW
3357 if (err)
3358 goto error;
cdddbdbc
DW
3359 }
3360
a2b97981
DW
3361 /* all mpbs enter, maybe one leaves */
3362 super = imsm_thunderdome(&super_list, i);
3363 if (!super) {
3364 err = 1;
3365 goto error;
cdddbdbc
DW
3366 }
3367
47ee5a45
DW
3368 if (find_missing(super) != 0) {
3369 free_imsm(super);
a2b97981
DW
3370 err = 2;
3371 goto error;
47ee5a45 3372 }
a2b97981
DW
3373 err = 0;
3374
3375 error:
3376 while (super_list) {
3377 struct intel_super *s = super_list;
3378
3379 super_list = super_list->next;
3380 free_imsm(s);
3381 }
1602d52c 3382 sysfs_free(sra);
a2b97981
DW
3383
3384 if (err)
3385 return err;
f7e7067b 3386
cdddbdbc 3387 *sbp = super;
db575f3b 3388 st->container_dev = devnum;
a2b97981 3389 if (err == 0 && st->ss == NULL) {
bf5a934a 3390 st->ss = &super_imsm;
cdddbdbc
DW
3391 st->minor_version = 0;
3392 st->max_devs = IMSM_MAX_DEVICES;
3393 }
cdddbdbc
DW
3394 return 0;
3395}
2b959fbf
N
3396
3397static int load_container_imsm(struct supertype *st, int fd, char *devname)
3398{
3399 return load_super_imsm_all(st, fd, &st->sb, devname);
3400}
cdddbdbc
DW
3401#endif
3402
3403static int load_super_imsm(struct supertype *st, int fd, char *devname)
3404{
3405 struct intel_super *super;
3406 int rv;
3407
691c6ee1
N
3408 if (test_partition(fd))
3409 /* IMSM not allowed on partitions */
3410 return 1;
3411
37424f13
DW
3412 free_super_imsm(st);
3413
49133e57 3414 super = alloc_super();
cdddbdbc
DW
3415 if (!super) {
3416 fprintf(stderr,
3417 Name ": malloc of %zu failed.\n",
3418 sizeof(*super));
3419 return 1;
3420 }
ea2bc72b
LM
3421 /* Load hba and capabilities if they exist.
3422 * But do not preclude loading metadata in case capabilities or hba are
3423 * non-compliant and ignore_hw_compat is set.
3424 */
d424212e 3425 rv = find_intel_hba_capability(fd, super, devname);
f2f5c343 3426 /* no orom/efi or non-intel hba of the disk */
ea2bc72b 3427 if ((rv != 0) && (st->ignore_hw_compat == 0)) {
f2f5c343
LM
3428 if (devname)
3429 fprintf(stderr,
3430 Name ": No OROM/EFI properties for %s\n", devname);
3431 free_imsm(super);
3432 return 2;
3433 }
a2b97981 3434 rv = load_and_parse_mpb(fd, super, devname, 0);
cdddbdbc
DW
3435
3436 if (rv) {
3437 if (devname)
3438 fprintf(stderr,
3439 Name ": Failed to load all information "
3440 "sections on %s\n", devname);
3441 free_imsm(super);
3442 return rv;
3443 }
3444
3445 st->sb = super;
3446 if (st->ss == NULL) {
3447 st->ss = &super_imsm;
3448 st->minor_version = 0;
3449 st->max_devs = IMSM_MAX_DEVICES;
3450 }
cdddbdbc
DW
3451 return 0;
3452}
3453
ef6ffade
DW
3454static __u16 info_to_blocks_per_strip(mdu_array_info_t *info)
3455{
3456 if (info->level == 1)
3457 return 128;
3458 return info->chunk_size >> 9;
3459}
3460
ff596308 3461static __u32 info_to_num_data_stripes(mdu_array_info_t *info, int num_domains)
ef6ffade
DW
3462{
3463 __u32 num_stripes;
3464
3465 num_stripes = (info->size * 2) / info_to_blocks_per_strip(info);
ff596308 3466 num_stripes /= num_domains;
ef6ffade
DW
3467
3468 return num_stripes;
3469}
3470
fcfd9599
DW
3471static __u32 info_to_blocks_per_member(mdu_array_info_t *info)
3472{
4025c288
DW
3473 if (info->level == 1)
3474 return info->size * 2;
3475 else
3476 return (info->size * 2) & ~(info_to_blocks_per_strip(info) - 1);
fcfd9599
DW
3477}
3478
4d1313e9
DW
3479static void imsm_update_version_info(struct intel_super *super)
3480{
3481 /* update the version and attributes */
3482 struct imsm_super *mpb = super->anchor;
3483 char *version;
3484 struct imsm_dev *dev;
3485 struct imsm_map *map;
3486 int i;
3487
3488 for (i = 0; i < mpb->num_raid_devs; i++) {
3489 dev = get_imsm_dev(super, i);
3490 map = get_imsm_map(dev, 0);
3491 if (__le32_to_cpu(dev->size_high) > 0)
3492 mpb->attributes |= MPB_ATTRIB_2TB;
3493
3494 /* FIXME detect when an array spans a port multiplier */
3495 #if 0
3496 mpb->attributes |= MPB_ATTRIB_PM;
3497 #endif
3498
3499 if (mpb->num_raid_devs > 1 ||
3500 mpb->attributes != MPB_ATTRIB_CHECKSUM_VERIFY) {
3501 version = MPB_VERSION_ATTRIBS;
3502 switch (get_imsm_raid_level(map)) {
3503 case 0: mpb->attributes |= MPB_ATTRIB_RAID0; break;
3504 case 1: mpb->attributes |= MPB_ATTRIB_RAID1; break;
3505 case 10: mpb->attributes |= MPB_ATTRIB_RAID10; break;
3506 case 5: mpb->attributes |= MPB_ATTRIB_RAID5; break;
3507 }
3508 } else {
3509 if (map->num_members >= 5)
3510 version = MPB_VERSION_5OR6_DISK_ARRAY;
3511 else if (dev->status == DEV_CLONE_N_GO)
3512 version = MPB_VERSION_CNG;
3513 else if (get_imsm_raid_level(map) == 5)
3514 version = MPB_VERSION_RAID5;
3515 else if (map->num_members >= 3)
3516 version = MPB_VERSION_3OR4_DISK_ARRAY;
3517 else if (get_imsm_raid_level(map) == 1)
3518 version = MPB_VERSION_RAID1;
3519 else
3520 version = MPB_VERSION_RAID0;
3521 }
3522 strcpy(((char *) mpb->sig) + strlen(MPB_SIGNATURE), version);
3523 }
3524}
3525
aa534678
DW
3526static int check_name(struct intel_super *super, char *name, int quiet)
3527{
3528 struct imsm_super *mpb = super->anchor;
3529 char *reason = NULL;
3530 int i;
3531
3532 if (strlen(name) > MAX_RAID_SERIAL_LEN)
3533 reason = "must be 16 characters or less";
3534
3535 for (i = 0; i < mpb->num_raid_devs; i++) {
3536 struct imsm_dev *dev = get_imsm_dev(super, i);
3537
3538 if (strncmp((char *) dev->volume, name, MAX_RAID_SERIAL_LEN) == 0) {
3539 reason = "already exists";
3540 break;
3541 }
3542 }
3543
3544 if (reason && !quiet)
3545 fprintf(stderr, Name ": imsm volume name %s\n", reason);
3546
3547 return !reason;
3548}
3549
8b353278
DW
3550static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
3551 unsigned long long size, char *name,
3552 char *homehost, int *uuid)
cdddbdbc 3553{
c2c087e6
DW
3554 /* We are creating a volume inside a pre-existing container.
3555 * so st->sb is already set.
3556 */
3557 struct intel_super *super = st->sb;
949c47a0 3558 struct imsm_super *mpb = super->anchor;
ba2de7ba 3559 struct intel_dev *dv;
c2c087e6
DW
3560 struct imsm_dev *dev;
3561 struct imsm_vol *vol;
3562 struct imsm_map *map;
3563 int idx = mpb->num_raid_devs;
3564 int i;
3565 unsigned long long array_blocks;
2c092cad 3566 size_t size_old, size_new;
ff596308 3567 __u32 num_data_stripes;
cdddbdbc 3568
88c32bb1 3569 if (super->orom && mpb->num_raid_devs >= super->orom->vpa) {
c2c087e6 3570 fprintf(stderr, Name": This imsm-container already has the "
88c32bb1 3571 "maximum of %d volumes\n", super->orom->vpa);
c2c087e6
DW
3572 return 0;
3573 }
3574
2c092cad
DW
3575 /* ensure the mpb is large enough for the new data */
3576 size_old = __le32_to_cpu(mpb->mpb_size);
3577 size_new = disks_to_mpb_size(info->nr_disks);
3578 if (size_new > size_old) {
3579 void *mpb_new;
3580 size_t size_round = ROUND_UP(size_new, 512);
3581
3582 if (posix_memalign(&mpb_new, 512, size_round) != 0) {
3583 fprintf(stderr, Name": could not allocate new mpb\n");
3584 return 0;
3585 }
3586 memcpy(mpb_new, mpb, size_old);
3587 free(mpb);
3588 mpb = mpb_new;
949c47a0 3589 super->anchor = mpb_new;
2c092cad
DW
3590 mpb->mpb_size = __cpu_to_le32(size_new);
3591 memset(mpb_new + size_old, 0, size_round - size_old);
3592 }
bf5a934a 3593 super->current_vol = idx;
d23fe947
DW
3594 /* when creating the first raid device in this container set num_disks
3595 * to zero, i.e. delete this spare and add raid member devices in
3596 * add_to_super_imsm_volume()
3597 */
3598 if (super->current_vol == 0)
3599 mpb->num_disks = 0;
5a038140 3600
aa534678
DW
3601 if (!check_name(super, name, 0))
3602 return 0;
ba2de7ba
DW
3603 dv = malloc(sizeof(*dv));
3604 if (!dv) {
3605 fprintf(stderr, Name ": failed to allocate device list entry\n");
3606 return 0;
3607 }
1a2487c2 3608 dev = calloc(1, sizeof(*dev) + sizeof(__u32) * (info->raid_disks - 1));
949c47a0 3609 if (!dev) {
ba2de7ba 3610 free(dv);
949c47a0
DW
3611 fprintf(stderr, Name": could not allocate raid device\n");
3612 return 0;
3613 }
1a2487c2 3614
c2c087e6 3615 strncpy((char *) dev->volume, name, MAX_RAID_SERIAL_LEN);
03bcbc65
DW
3616 if (info->level == 1)
3617 array_blocks = info_to_blocks_per_member(info);
3618 else
3619 array_blocks = calc_array_size(info->level, info->raid_disks,
3620 info->layout, info->chunk_size,
3621 info->size*2);
979d38be
DW
3622 /* round array size down to closest MB */
3623 array_blocks = (array_blocks >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT;
3624
c2c087e6
DW
3625 dev->size_low = __cpu_to_le32((__u32) array_blocks);
3626 dev->size_high = __cpu_to_le32((__u32) (array_blocks >> 32));
1a2487c2 3627 dev->status = (DEV_READ_COALESCING | DEV_WRITE_COALESCING);
c2c087e6
DW
3628 vol = &dev->vol;
3629 vol->migr_state = 0;
1484e727 3630 set_migr_type(dev, MIGR_INIT);
c2c087e6 3631 vol->dirty = 0;
f8f603f1 3632 vol->curr_migr_unit = 0;
a965f303 3633 map = get_imsm_map(dev, 0);
0dcecb2e 3634 map->pba_of_lba0 = __cpu_to_le32(super->create_offset);
fcfd9599 3635 map->blocks_per_member = __cpu_to_le32(info_to_blocks_per_member(info));
ef6ffade 3636 map->blocks_per_strip = __cpu_to_le16(info_to_blocks_per_strip(info));
0556e1a2 3637 map->failed_disk_num = ~0;
c2c087e6
DW
3638 map->map_state = info->level ? IMSM_T_STATE_UNINITIALIZED :
3639 IMSM_T_STATE_NORMAL;
252d23c0 3640 map->ddf = 1;
ef6ffade
DW
3641
3642 if (info->level == 1 && info->raid_disks > 2) {
38950822
AW
3643 free(dev);
3644 free(dv);
ef6ffade
DW
3645 fprintf(stderr, Name": imsm does not support more than 2 disks"
3646 "in a raid1 volume\n");
3647 return 0;
3648 }
81062a36
DW
3649
3650 map->raid_level = info->level;
4d1313e9 3651 if (info->level == 10) {
c2c087e6 3652 map->raid_level = 1;
4d1313e9 3653 map->num_domains = info->raid_disks / 2;
81062a36
DW
3654 } else if (info->level == 1)
3655 map->num_domains = info->raid_disks;
3656 else
ff596308 3657 map->num_domains = 1;
81062a36 3658
ff596308
DW
3659 num_data_stripes = info_to_num_data_stripes(info, map->num_domains);
3660 map->num_data_stripes = __cpu_to_le32(num_data_stripes);
ef6ffade 3661
c2c087e6
DW
3662 map->num_members = info->raid_disks;
3663 for (i = 0; i < map->num_members; i++) {
3664 /* initialized in add_to_super */
4eb26970 3665 set_imsm_ord_tbl_ent(map, i, IMSM_ORD_REBUILD);
c2c087e6 3666 }
949c47a0 3667 mpb->num_raid_devs++;
ba2de7ba
DW
3668
3669 dv->dev = dev;
3670 dv->index = super->current_vol;
3671 dv->next = super->devlist;
3672 super->devlist = dv;
c2c087e6 3673
4d1313e9
DW
3674 imsm_update_version_info(super);
3675
c2c087e6 3676 return 1;
cdddbdbc
DW
3677}
3678
bf5a934a
DW
3679static int init_super_imsm(struct supertype *st, mdu_array_info_t *info,
3680 unsigned long long size, char *name,
3681 char *homehost, int *uuid)
3682{
3683 /* This is primarily called by Create when creating a new array.
3684 * We will then get add_to_super called for each component, and then
3685 * write_init_super called to write it out to each device.
3686 * For IMSM, Create can create on fresh devices or on a pre-existing
3687 * array.
3688 * To create on a pre-existing array a different method will be called.
3689 * This one is just for fresh drives.
3690 */
3691 struct intel_super *super;
3692 struct imsm_super *mpb;
3693 size_t mpb_size;
4d1313e9 3694 char *version;
bf5a934a 3695
bf5a934a 3696 if (st->sb)
e683ca88
DW
3697 return init_super_imsm_volume(st, info, size, name, homehost, uuid);
3698
3699 if (info)
3700 mpb_size = disks_to_mpb_size(info->nr_disks);
3701 else
3702 mpb_size = 512;
bf5a934a 3703
49133e57 3704 super = alloc_super();
e683ca88 3705 if (super && posix_memalign(&super->buf, 512, mpb_size) != 0) {
bf5a934a 3706 free(super);
e683ca88
DW
3707 super = NULL;
3708 }
3709 if (!super) {
3710 fprintf(stderr, Name
3711 ": %s could not allocate superblock\n", __func__);
bf5a934a
DW
3712 return 0;
3713 }
e683ca88 3714 memset(super->buf, 0, mpb_size);
ef649044 3715 mpb = super->buf;
e683ca88
DW
3716 mpb->mpb_size = __cpu_to_le32(mpb_size);
3717 st->sb = super;
3718
3719 if (info == NULL) {
3720 /* zeroing superblock */
3721 return 0;
3722 }
bf5a934a 3723
4d1313e9
DW
3724 mpb->attributes = MPB_ATTRIB_CHECKSUM_VERIFY;
3725
3726 version = (char *) mpb->sig;
3727 strcpy(version, MPB_SIGNATURE);
3728 version += strlen(MPB_SIGNATURE);
3729 strcpy(version, MPB_VERSION_RAID0);
bf5a934a 3730
bf5a934a
DW
3731 return 1;
3732}
3733
0e600426 3734#ifndef MDASSEMBLE
f20c3968 3735static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
bf5a934a
DW
3736 int fd, char *devname)
3737{
3738 struct intel_super *super = st->sb;
d23fe947 3739 struct imsm_super *mpb = super->anchor;
bf5a934a
DW
3740 struct dl *dl;
3741 struct imsm_dev *dev;
3742 struct imsm_map *map;
4eb26970 3743 int slot;
bf5a934a 3744
949c47a0 3745 dev = get_imsm_dev(super, super->current_vol);
a965f303 3746 map = get_imsm_map(dev, 0);
bf5a934a 3747
208933a7
N
3748 if (! (dk->state & (1<<MD_DISK_SYNC))) {
3749 fprintf(stderr, Name ": %s: Cannot add spare devices to IMSM volume\n",
3750 devname);
3751 return 1;
3752 }
3753
efb30e7f
DW
3754 if (fd == -1) {
3755 /* we're doing autolayout so grab the pre-marked (in
3756 * validate_geometry) raid_disk
3757 */
3758 for (dl = super->disks; dl; dl = dl->next)
3759 if (dl->raiddisk == dk->raid_disk)
3760 break;
3761 } else {
3762 for (dl = super->disks; dl ; dl = dl->next)
3763 if (dl->major == dk->major &&
3764 dl->minor == dk->minor)
3765 break;
3766 }
d23fe947 3767
208933a7
N
3768 if (!dl) {
3769 fprintf(stderr, Name ": %s is not a member of the same container\n", devname);
f20c3968 3770 return 1;
208933a7 3771 }
bf5a934a 3772
d23fe947
DW
3773 /* add a pristine spare to the metadata */
3774 if (dl->index < 0) {
3775 dl->index = super->anchor->num_disks;
3776 super->anchor->num_disks++;
3777 }
4eb26970
DW
3778 /* Check the device has not already been added */
3779 slot = get_imsm_disk_slot(map, dl->index);
3780 if (slot >= 0 &&
98130f40 3781 (get_imsm_ord_tbl_ent(dev, slot, -1) & IMSM_ORD_REBUILD) == 0) {
4eb26970
DW
3782 fprintf(stderr, Name ": %s has been included in this array twice\n",
3783 devname);
3784 return 1;
3785 }
be73972f 3786 set_imsm_ord_tbl_ent(map, dk->number, dl->index);
ee5aad5a 3787 dl->disk.status = CONFIGURED_DISK;
d23fe947
DW
3788
3789 /* if we are creating the first raid device update the family number */
3790 if (super->current_vol == 0) {
3791 __u32 sum;
3792 struct imsm_dev *_dev = __get_imsm_dev(mpb, 0);
3793 struct imsm_disk *_disk = __get_imsm_disk(mpb, dl->index);
3794
791b666a
AW
3795 if (!_dev || !_disk) {
3796 fprintf(stderr, Name ": BUG mpb setup error\n");
3797 return 1;
3798 }
d23fe947
DW
3799 *_dev = *dev;
3800 *_disk = dl->disk;
148acb7b
DW
3801 sum = random32();
3802 sum += __gen_imsm_checksum(mpb);
d23fe947 3803 mpb->family_num = __cpu_to_le32(sum);
148acb7b 3804 mpb->orig_family_num = mpb->family_num;
d23fe947 3805 }
f20c3968
DW
3806
3807 return 0;
bf5a934a
DW
3808}
3809
88654014 3810
f20c3968 3811static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
88654014 3812 int fd, char *devname)
cdddbdbc 3813{
c2c087e6 3814 struct intel_super *super = st->sb;
c2c087e6
DW
3815 struct dl *dd;
3816 unsigned long long size;
f2f27e63 3817 __u32 id;
c2c087e6
DW
3818 int rv;
3819 struct stat stb;
3820
88654014
LM
3821 /* If we are on an RAID enabled platform check that the disk is
3822 * attached to the raid controller.
3823 * We do not need to test disks attachment for container based additions,
3824 * they shall be already tested when container was created/assembled.
88c32bb1 3825 */
d424212e 3826 rv = find_intel_hba_capability(fd, super, devname);
f2f5c343 3827 /* no orom/efi or non-intel hba of the disk */
f0f5a016
LM
3828 if (rv != 0) {
3829 dprintf("capability: %p fd: %d ret: %d\n",
3830 super->orom, fd, rv);
3831 return 1;
88c32bb1
DW
3832 }
3833
f20c3968
DW
3834 if (super->current_vol >= 0)
3835 return add_to_super_imsm_volume(st, dk, fd, devname);
bf5a934a 3836
c2c087e6
DW
3837 fstat(fd, &stb);
3838 dd = malloc(sizeof(*dd));
b9f594fe 3839 if (!dd) {
c2c087e6
DW
3840 fprintf(stderr,
3841 Name ": malloc failed %s:%d.\n", __func__, __LINE__);
f20c3968 3842 return 1;
c2c087e6
DW
3843 }
3844 memset(dd, 0, sizeof(*dd));
3845 dd->major = major(stb.st_rdev);
3846 dd->minor = minor(stb.st_rdev);
b9f594fe 3847 dd->index = -1;
c2c087e6 3848 dd->devname = devname ? strdup(devname) : NULL;
c2c087e6 3849 dd->fd = fd;
689c9bf3 3850 dd->e = NULL;
1a64be56 3851 dd->action = DISK_ADD;
c2c087e6 3852 rv = imsm_read_serial(fd, devname, dd->serial);
32ba9157 3853 if (rv) {
c2c087e6 3854 fprintf(stderr,
0030e8d6 3855 Name ": failed to retrieve scsi serial, aborting\n");
949c47a0 3856 free(dd);
0030e8d6 3857 abort();
c2c087e6
DW
3858 }
3859
c2c087e6
DW
3860 get_dev_size(fd, NULL, &size);
3861 size /= 512;
1f24f035 3862 serialcpy(dd->disk.serial, dd->serial);
b9f594fe 3863 dd->disk.total_blocks = __cpu_to_le32(size);
ee5aad5a 3864 dd->disk.status = SPARE_DISK;
c2c087e6 3865 if (sysfs_disk_to_scsi_id(fd, &id) == 0)
b9f594fe 3866 dd->disk.scsi_id = __cpu_to_le32(id);
c2c087e6 3867 else
b9f594fe 3868 dd->disk.scsi_id = __cpu_to_le32(0);
43dad3d6
DW
3869
3870 if (st->update_tail) {
1a64be56
LM
3871 dd->next = super->disk_mgmt_list;
3872 super->disk_mgmt_list = dd;
43dad3d6
DW
3873 } else {
3874 dd->next = super->disks;
3875 super->disks = dd;
ceaf0ee1 3876 super->updates_pending++;
43dad3d6 3877 }
f20c3968
DW
3878
3879 return 0;
cdddbdbc
DW
3880}
3881
1a64be56
LM
3882
3883static int remove_from_super_imsm(struct supertype *st, mdu_disk_info_t *dk)
3884{
3885 struct intel_super *super = st->sb;
3886 struct dl *dd;
3887
3888 /* remove from super works only in mdmon - for communication
3889 * manager - monitor. Check if communication memory buffer
3890 * is prepared.
3891 */
3892 if (!st->update_tail) {
3893 fprintf(stderr,
3894 Name ": %s shall be used in mdmon context only"
3895 "(line %d).\n", __func__, __LINE__);
3896 return 1;
3897 }
3898 dd = malloc(sizeof(*dd));
3899 if (!dd) {
3900 fprintf(stderr,
3901 Name ": malloc failed %s:%d.\n", __func__, __LINE__);
3902 return 1;
3903 }
3904 memset(dd, 0, sizeof(*dd));
3905 dd->major = dk->major;
3906 dd->minor = dk->minor;
3907 dd->index = -1;
3908 dd->fd = -1;
3909 dd->disk.status = SPARE_DISK;
3910 dd->action = DISK_REMOVE;
3911
3912 dd->next = super->disk_mgmt_list;
3913 super->disk_mgmt_list = dd;
3914
3915
3916 return 0;
3917}
3918
f796af5d
DW
3919static int store_imsm_mpb(int fd, struct imsm_super *mpb);
3920
3921static union {
3922 char buf[512];
3923 struct imsm_super anchor;
3924} spare_record __attribute__ ((aligned(512)));
c2c087e6 3925
d23fe947
DW
3926/* spare records have their own family number and do not have any defined raid
3927 * devices
3928 */
3929static int write_super_imsm_spares(struct intel_super *super, int doclose)
3930{
d23fe947 3931 struct imsm_super *mpb = super->anchor;
f796af5d 3932 struct imsm_super *spare = &spare_record.anchor;
d23fe947
DW
3933 __u32 sum;
3934 struct dl *d;
3935
f796af5d
DW
3936 spare->mpb_size = __cpu_to_le32(sizeof(struct imsm_super)),
3937 spare->generation_num = __cpu_to_le32(1UL),
3938 spare->attributes = MPB_ATTRIB_CHECKSUM_VERIFY;
3939 spare->num_disks = 1,
3940 spare->num_raid_devs = 0,
3941 spare->cache_size = mpb->cache_size,
3942 spare->pwr_cycle_count = __cpu_to_le32(1),
3943
3944 snprintf((char *) spare->sig, MAX_SIGNATURE_LENGTH,
3945 MPB_SIGNATURE MPB_VERSION_RAID0);
d23fe947
DW
3946
3947 for (d = super->disks; d; d = d->next) {
8796fdc4 3948 if (d->index != -1)
d23fe947
DW
3949 continue;
3950
f796af5d
DW
3951 spare->disk[0] = d->disk;
3952 sum = __gen_imsm_checksum(spare);
3953 spare->family_num = __cpu_to_le32(sum);
3954 spare->orig_family_num = 0;
3955 sum = __gen_imsm_checksum(spare);
3956 spare->check_sum = __cpu_to_le32(sum);
d23fe947 3957
f796af5d 3958 if (store_imsm_mpb(d->fd, spare)) {
d23fe947
DW
3959 fprintf(stderr, "%s: failed for device %d:%d %s\n",
3960 __func__, d->major, d->minor, strerror(errno));
e74255d9 3961 return 1;
d23fe947
DW
3962 }
3963 if (doclose) {
3964 close(d->fd);
3965 d->fd = -1;
3966 }
3967 }
3968
e74255d9 3969 return 0;
d23fe947
DW
3970}
3971
36988a3d 3972static int write_super_imsm(struct supertype *st, int doclose)
cdddbdbc 3973{
36988a3d 3974 struct intel_super *super = st->sb;
949c47a0 3975 struct imsm_super *mpb = super->anchor;
c2c087e6
DW
3976 struct dl *d;
3977 __u32 generation;
3978 __u32 sum;
d23fe947 3979 int spares = 0;
949c47a0 3980 int i;
a48ac0a8 3981 __u32 mpb_size = sizeof(struct imsm_super) - sizeof(struct imsm_disk);
36988a3d 3982 int num_disks = 0;
cdddbdbc 3983
c2c087e6
DW
3984 /* 'generation' is incremented everytime the metadata is written */
3985 generation = __le32_to_cpu(mpb->generation_num);
3986 generation++;
3987 mpb->generation_num = __cpu_to_le32(generation);
3988
148acb7b
DW
3989 /* fix up cases where previous mdadm releases failed to set
3990 * orig_family_num
3991 */
3992 if (mpb->orig_family_num == 0)
3993 mpb->orig_family_num = mpb->family_num;
3994
d23fe947 3995 for (d = super->disks; d; d = d->next) {
8796fdc4 3996 if (d->index == -1)
d23fe947 3997 spares++;
36988a3d 3998 else {
d23fe947 3999 mpb->disk[d->index] = d->disk;
36988a3d
AK
4000 num_disks++;
4001 }
d23fe947 4002 }
36988a3d 4003 for (d = super->missing; d; d = d->next) {
47ee5a45 4004 mpb->disk[d->index] = d->disk;
36988a3d
AK
4005 num_disks++;
4006 }
4007 mpb->num_disks = num_disks;
4008 mpb_size += sizeof(struct imsm_disk) * mpb->num_disks;
b9f594fe 4009
949c47a0
DW
4010 for (i = 0; i < mpb->num_raid_devs; i++) {
4011 struct imsm_dev *dev = __get_imsm_dev(mpb, i);
36988a3d
AK
4012 struct imsm_dev *dev2 = get_imsm_dev(super, i);
4013 if (dev && dev2) {
4014 imsm_copy_dev(dev, dev2);
4015 mpb_size += sizeof_imsm_dev(dev, 0);
4016 }
949c47a0 4017 }
a48ac0a8
DW
4018 mpb_size += __le32_to_cpu(mpb->bbm_log_size);
4019 mpb->mpb_size = __cpu_to_le32(mpb_size);
949c47a0 4020
c2c087e6 4021 /* recalculate checksum */
949c47a0 4022 sum = __gen_imsm_checksum(mpb);
c2c087e6
DW
4023 mpb->check_sum = __cpu_to_le32(sum);
4024
d23fe947 4025 /* write the mpb for disks that compose raid devices */
c2c087e6 4026 for (d = super->disks; d ; d = d->next) {
d23fe947
DW
4027 if (d->index < 0)
4028 continue;
f796af5d 4029 if (store_imsm_mpb(d->fd, mpb))
c2c087e6
DW
4030 fprintf(stderr, "%s: failed for device %d:%d %s\n",
4031 __func__, d->major, d->minor, strerror(errno));
c2c087e6
DW
4032 if (doclose) {
4033 close(d->fd);
4034 d->fd = -1;
4035 }
4036 }
4037
d23fe947
DW
4038 if (spares)
4039 return write_super_imsm_spares(super, doclose);
4040
e74255d9 4041 return 0;
c2c087e6
DW
4042}
4043
0e600426 4044
9b1fb677 4045static int create_array(struct supertype *st, int dev_idx)
43dad3d6
DW
4046{
4047 size_t len;
4048 struct imsm_update_create_array *u;
4049 struct intel_super *super = st->sb;
9b1fb677 4050 struct imsm_dev *dev = get_imsm_dev(super, dev_idx);
54c2c1ea
DW
4051 struct imsm_map *map = get_imsm_map(dev, 0);
4052 struct disk_info *inf;
4053 struct imsm_disk *disk;
4054 int i;
43dad3d6 4055
54c2c1ea
DW
4056 len = sizeof(*u) - sizeof(*dev) + sizeof_imsm_dev(dev, 0) +
4057 sizeof(*inf) * map->num_members;
43dad3d6
DW
4058 u = malloc(len);
4059 if (!u) {
4060 fprintf(stderr, "%s: failed to allocate update buffer\n",
4061 __func__);
4062 return 1;
4063 }
4064
4065 u->type = update_create_array;
9b1fb677 4066 u->dev_idx = dev_idx;
43dad3d6 4067 imsm_copy_dev(&u->dev, dev);
54c2c1ea
DW
4068 inf = get_disk_info(u);
4069 for (i = 0; i < map->num_members; i++) {
98130f40 4070 int idx = get_imsm_disk_idx(dev, i, -1);
9b1fb677 4071
54c2c1ea
DW
4072 disk = get_imsm_disk(super, idx);
4073 serialcpy(inf[i].serial, disk->serial);
4074 }
43dad3d6
DW
4075 append_metadata_update(st, u, len);
4076
4077 return 0;
4078}
4079
1a64be56 4080static int mgmt_disk(struct supertype *st)
43dad3d6
DW
4081{
4082 struct intel_super *super = st->sb;
4083 size_t len;
1a64be56 4084 struct imsm_update_add_remove_disk *u;
43dad3d6 4085
1a64be56 4086 if (!super->disk_mgmt_list)
43dad3d6
DW
4087 return 0;
4088
4089 len = sizeof(*u);
4090 u = malloc(len);
4091 if (!u) {
4092 fprintf(stderr, "%s: failed to allocate update buffer\n",
4093 __func__);
4094 return 1;
4095 }
4096
1a64be56 4097 u->type = update_add_remove_disk;
43dad3d6
DW
4098 append_metadata_update(st, u, len);
4099
4100 return 0;
4101}
4102
c2c087e6
DW
4103static int write_init_super_imsm(struct supertype *st)
4104{
9b1fb677
DW
4105 struct intel_super *super = st->sb;
4106 int current_vol = super->current_vol;
4107
4108 /* we are done with current_vol reset it to point st at the container */
4109 super->current_vol = -1;
4110
8273f55e 4111 if (st->update_tail) {
43dad3d6
DW
4112 /* queue the recently created array / added disk
4113 * as a metadata update */
43dad3d6 4114 int rv;
8273f55e 4115
43dad3d6 4116 /* determine if we are creating a volume or adding a disk */
9b1fb677 4117 if (current_vol < 0) {
1a64be56
LM
4118 /* in the mgmt (add/remove) disk case we are running
4119 * in mdmon context, so don't close fd's
43dad3d6 4120 */
1a64be56 4121 return mgmt_disk(st);
43dad3d6 4122 } else
9b1fb677 4123 rv = create_array(st, current_vol);
8273f55e 4124
43dad3d6 4125 return rv;
d682f344
N
4126 } else {
4127 struct dl *d;
4128 for (d = super->disks; d; d = d->next)
4129 Kill(d->devname, NULL, 0, 1, 1);
36988a3d 4130 return write_super_imsm(st, 1);
d682f344 4131 }
cdddbdbc 4132}
0e600426 4133#endif
cdddbdbc 4134
e683ca88 4135static int store_super_imsm(struct supertype *st, int fd)
cdddbdbc 4136{
e683ca88
DW
4137 struct intel_super *super = st->sb;
4138 struct imsm_super *mpb = super ? super->anchor : NULL;
551c80c1 4139
e683ca88 4140 if (!mpb)
ad97895e
DW
4141 return 1;
4142
1799c9e8 4143#ifndef MDASSEMBLE
e683ca88 4144 return store_imsm_mpb(fd, mpb);
1799c9e8
N
4145#else
4146 return 1;
4147#endif
cdddbdbc
DW
4148}
4149
0e600426
N
4150static int imsm_bbm_log_size(struct imsm_super *mpb)
4151{
4152 return __le32_to_cpu(mpb->bbm_log_size);
4153}
4154
4155#ifndef MDASSEMBLE
cdddbdbc
DW
4156static int validate_geometry_imsm_container(struct supertype *st, int level,
4157 int layout, int raiddisks, int chunk,
c2c087e6 4158 unsigned long long size, char *dev,
2c514b71
NB
4159 unsigned long long *freesize,
4160 int verbose)
cdddbdbc 4161{
c2c087e6
DW
4162 int fd;
4163 unsigned long long ldsize;
f2f5c343
LM
4164 struct intel_super *super=NULL;
4165 int rv = 0;
cdddbdbc 4166
c2c087e6
DW
4167 if (level != LEVEL_CONTAINER)
4168 return 0;
4169 if (!dev)
4170 return 1;
4171
4172 fd = open(dev, O_RDONLY|O_EXCL, 0);
4173 if (fd < 0) {
2c514b71
NB
4174 if (verbose)
4175 fprintf(stderr, Name ": imsm: Cannot open %s: %s\n",
4176 dev, strerror(errno));
c2c087e6
DW
4177 return 0;
4178 }
4179 if (!get_dev_size(fd, dev, &ldsize)) {
4180 close(fd);
4181 return 0;
4182 }
f2f5c343
LM
4183
4184 /* capabilities retrieve could be possible
4185 * note that there is no fd for the disks in array.
4186 */
4187 super = alloc_super();
4188 if (!super) {
4189 fprintf(stderr,
4190 Name ": malloc of %zu failed.\n",
4191 sizeof(*super));
4192 close(fd);
4193 return 0;
4194 }
4195
d424212e 4196 rv = find_intel_hba_capability(fd, super, verbose ? dev : NULL);
f2f5c343
LM
4197 if (rv != 0) {
4198#if DEBUG
4199 char str[256];
4200 fd2devname(fd, str);
4201 dprintf("validate_geometry_imsm_container: fd: %d %s orom: %p rv: %d raiddisk: %d\n",
4202 fd, str, super->orom, rv, raiddisks);
4203#endif
4204 /* no orom/efi or non-intel hba of the disk */
4205 close(fd);
4206 free_imsm(super);
4207 return 0;
4208 }
c2c087e6 4209 close(fd);
f2f5c343
LM
4210 if (super->orom && raiddisks > super->orom->tds) {
4211 if (verbose)
4212 fprintf(stderr, Name ": %d exceeds maximum number of"
4213 " platform supported disks: %d\n",
4214 raiddisks, super->orom->tds);
4215
4216 free_imsm(super);
4217 return 0;
4218 }
c2c087e6
DW
4219
4220 *freesize = avail_size_imsm(st, ldsize >> 9);
f2f5c343 4221 free_imsm(super);
c2c087e6
DW
4222
4223 return 1;
cdddbdbc
DW
4224}
4225
0dcecb2e
DW
4226static unsigned long long find_size(struct extent *e, int *idx, int num_extents)
4227{
4228 const unsigned long long base_start = e[*idx].start;
4229 unsigned long long end = base_start + e[*idx].size;
4230 int i;
4231
4232 if (base_start == end)
4233 return 0;
4234
4235 *idx = *idx + 1;
4236 for (i = *idx; i < num_extents; i++) {
4237 /* extend overlapping extents */
4238 if (e[i].start >= base_start &&
4239 e[i].start <= end) {
4240 if (e[i].size == 0)
4241 return 0;
4242 if (e[i].start + e[i].size > end)
4243 end = e[i].start + e[i].size;
4244 } else if (e[i].start > end) {
4245 *idx = i;
4246 break;
4247 }
4248 }
4249
4250 return end - base_start;
4251}
4252
4253static unsigned long long merge_extents(struct intel_super *super, int sum_extents)
4254{
4255 /* build a composite disk with all known extents and generate a new
4256 * 'maxsize' given the "all disks in an array must share a common start
4257 * offset" constraint
4258 */
4259 struct extent *e = calloc(sum_extents, sizeof(*e));
4260 struct dl *dl;
4261 int i, j;
4262 int start_extent;
4263 unsigned long long pos;
b9d77223 4264 unsigned long long start = 0;
0dcecb2e
DW
4265 unsigned long long maxsize;
4266 unsigned long reserve;
4267
4268 if (!e)
a7dd165b 4269 return 0;
0dcecb2e
DW
4270
4271 /* coalesce and sort all extents. also, check to see if we need to
4272 * reserve space between member arrays
4273 */
4274 j = 0;
4275 for (dl = super->disks; dl; dl = dl->next) {
4276 if (!dl->e)
4277 continue;
4278 for (i = 0; i < dl->extent_cnt; i++)
4279 e[j++] = dl->e[i];
4280 }
4281 qsort(e, sum_extents, sizeof(*e), cmp_extent);
4282
4283 /* merge extents */
4284 i = 0;
4285 j = 0;
4286 while (i < sum_extents) {
4287 e[j].start = e[i].start;
4288 e[j].size = find_size(e, &i, sum_extents);
4289 j++;
4290 if (e[j-1].size == 0)
4291 break;
4292 }
4293
4294 pos = 0;
4295 maxsize = 0;
4296 start_extent = 0;
4297 i = 0;
4298 do {
4299 unsigned long long esize;
4300
4301 esize = e[i].start - pos;
4302 if (esize >= maxsize) {
4303 maxsize = esize;
4304 start = pos;
4305 start_extent = i;
4306 }
4307 pos = e[i].start + e[i].size;
4308 i++;
4309 } while (e[i-1].size);
4310 free(e);
4311
a7dd165b
DW
4312 if (maxsize == 0)
4313 return 0;
4314
4315 /* FIXME assumes volume at offset 0 is the first volume in a
4316 * container
4317 */
0dcecb2e
DW
4318 if (start_extent > 0)
4319 reserve = IMSM_RESERVED_SECTORS; /* gap between raid regions */
4320 else
4321 reserve = 0;
4322
4323 if (maxsize < reserve)
a7dd165b 4324 return 0;
0dcecb2e
DW
4325
4326 super->create_offset = ~((__u32) 0);
4327 if (start + reserve > super->create_offset)
a7dd165b 4328 return 0; /* start overflows create_offset */
0dcecb2e
DW
4329 super->create_offset = start + reserve;
4330
4331 return maxsize - reserve;
4332}
4333
88c32bb1
DW
4334static int is_raid_level_supported(const struct imsm_orom *orom, int level, int raiddisks)
4335{
4336 if (level < 0 || level == 6 || level == 4)
4337 return 0;
4338
4339 /* if we have an orom prevent invalid raid levels */
4340 if (orom)
4341 switch (level) {
4342 case 0: return imsm_orom_has_raid0(orom);
4343 case 1:
4344 if (raiddisks > 2)
4345 return imsm_orom_has_raid1e(orom);
1c556e92
DW
4346 return imsm_orom_has_raid1(orom) && raiddisks == 2;
4347 case 10: return imsm_orom_has_raid10(orom) && raiddisks == 4;
4348 case 5: return imsm_orom_has_raid5(orom) && raiddisks > 2;
88c32bb1
DW
4349 }
4350 else
4351 return 1; /* not on an Intel RAID platform so anything goes */
4352
4353 return 0;
4354}
4355
73408129 4356
35f81cbb 4357#define pr_vrb(fmt, arg...) (void) (verbose && fprintf(stderr, Name fmt, ##arg))
73408129
LM
4358/*
4359 * validate volume parameters with OROM/EFI capabilities
4360 */
6592ce37
DW
4361static int
4362validate_geometry_imsm_orom(struct intel_super *super, int level, int layout,
c21e737b 4363 int raiddisks, int *chunk, int verbose)
6592ce37 4364{
73408129
LM
4365#if DEBUG
4366 verbose = 1;
4367#endif
4368 /* validate container capabilities */
4369 if (super->orom && raiddisks > super->orom->tds) {
4370 if (verbose)
4371 fprintf(stderr, Name ": %d exceeds maximum number of"
4372 " platform supported disks: %d\n",
4373 raiddisks, super->orom->tds);
4374 return 0;
4375 }
4376
4377 /* capabilities of OROM tested - copied from validate_geometry_imsm_volume */
4378 if (super->orom && (!is_raid_level_supported(super->orom, level,
4379 raiddisks))) {
6592ce37
DW
4380 pr_vrb(": platform does not support raid%d with %d disk%s\n",
4381 level, raiddisks, raiddisks > 1 ? "s" : "");
4382 return 0;
4383 }
c21e737b
CA
4384 if (super->orom && level != 1) {
4385 if (chunk && (*chunk == 0 || *chunk == UnSet))
4386 *chunk = imsm_orom_default_chunk(super->orom);
4387 else if (chunk && !imsm_orom_has_chunk(super->orom, *chunk)) {
4388 pr_vrb(": platform does not support a chunk size of: "
4389 "%d\n", *chunk);
4390 return 0;
4391 }
6592ce37
DW
4392 }
4393 if (layout != imsm_level_to_layout(level)) {
4394 if (level == 5)
4395 pr_vrb(": imsm raid 5 only supports the left-asymmetric layout\n");
4396 else if (level == 10)
4397 pr_vrb(": imsm raid 10 only supports the n2 layout\n");
4398 else
4399 pr_vrb(": imsm unknown layout %#x for this raid level %d\n",
4400 layout, level);
4401 return 0;
4402 }
6592ce37
DW
4403 return 1;
4404}
4405
c2c087e6
DW
4406/* validate_geometry_imsm_volume - lifted from validate_geometry_ddf_bvd
4407 * FIX ME add ahci details
4408 */
8b353278 4409static int validate_geometry_imsm_volume(struct supertype *st, int level,
c21e737b 4410 int layout, int raiddisks, int *chunk,
c2c087e6 4411 unsigned long long size, char *dev,
2c514b71
NB
4412 unsigned long long *freesize,
4413 int verbose)
cdddbdbc 4414{
c2c087e6
DW
4415 struct stat stb;
4416 struct intel_super *super = st->sb;
a20d2ba5 4417 struct imsm_super *mpb = super->anchor;
c2c087e6
DW
4418 struct dl *dl;
4419 unsigned long long pos = 0;
4420 unsigned long long maxsize;
4421 struct extent *e;
4422 int i;
cdddbdbc 4423
88c32bb1
DW
4424 /* We must have the container info already read in. */
4425 if (!super)
c2c087e6
DW
4426 return 0;
4427
d54559f0
LM
4428 if (!validate_geometry_imsm_orom(super, level, layout, raiddisks, chunk, verbose)) {
4429 fprintf(stderr, Name ": RAID gemetry validation failed. "
4430 "Cannot proceed with the action(s).\n");
c2c087e6 4431 return 0;
d54559f0 4432 }
c2c087e6
DW
4433 if (!dev) {
4434 /* General test: make sure there is space for
2da8544a
DW
4435 * 'raiddisks' device extents of size 'size' at a given
4436 * offset
c2c087e6 4437 */
e46273eb 4438 unsigned long long minsize = size;
b7528a20 4439 unsigned long long start_offset = MaxSector;
c2c087e6
DW
4440 int dcnt = 0;
4441 if (minsize == 0)
4442 minsize = MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS;
4443 for (dl = super->disks; dl ; dl = dl->next) {
4444 int found = 0;
4445
bf5a934a 4446 pos = 0;
c2c087e6
DW
4447 i = 0;
4448 e = get_extents(super, dl);
4449 if (!e) continue;
4450 do {
4451 unsigned long long esize;
4452 esize = e[i].start - pos;
4453 if (esize >= minsize)
4454 found = 1;
b7528a20 4455 if (found && start_offset == MaxSector) {
2da8544a
DW
4456 start_offset = pos;
4457 break;
4458 } else if (found && pos != start_offset) {
4459 found = 0;
4460 break;
4461 }
c2c087e6
DW
4462 pos = e[i].start + e[i].size;
4463 i++;
4464 } while (e[i-1].size);
4465 if (found)
4466 dcnt++;
4467 free(e);
4468 }
4469 if (dcnt < raiddisks) {
2c514b71
NB
4470 if (verbose)
4471 fprintf(stderr, Name ": imsm: Not enough "
4472 "devices with space for this array "
4473 "(%d < %d)\n",
4474 dcnt, raiddisks);
c2c087e6
DW
4475 return 0;
4476 }
4477 return 1;
4478 }
0dcecb2e 4479
c2c087e6
DW
4480 /* This device must be a member of the set */
4481 if (stat(dev, &stb) < 0)
4482 return 0;
4483 if ((S_IFMT & stb.st_mode) != S_IFBLK)
4484 return 0;
4485 for (dl = super->disks ; dl ; dl = dl->next) {
f21e18ca
N
4486 if (dl->major == (int)major(stb.st_rdev) &&
4487 dl->minor == (int)minor(stb.st_rdev))
c2c087e6
DW
4488 break;
4489 }
4490 if (!dl) {
2c514b71
NB
4491 if (verbose)
4492 fprintf(stderr, Name ": %s is not in the "
4493 "same imsm set\n", dev);
c2c087e6 4494 return 0;
a20d2ba5
DW
4495 } else if (super->orom && dl->index < 0 && mpb->num_raid_devs) {
4496 /* If a volume is present then the current creation attempt
4497 * cannot incorporate new spares because the orom may not
4498 * understand this configuration (all member disks must be
4499 * members of each array in the container).
4500 */
4501 fprintf(stderr, Name ": %s is a spare and a volume"
4502 " is already defined for this container\n", dev);
4503 fprintf(stderr, Name ": The option-rom requires all member"
4504 " disks to be a member of all volumes\n");
4505 return 0;
c2c087e6 4506 }
0dcecb2e
DW
4507
4508 /* retrieve the largest free space block */
c2c087e6
DW
4509 e = get_extents(super, dl);
4510 maxsize = 0;
4511 i = 0;
0dcecb2e
DW
4512 if (e) {
4513 do {
4514 unsigned long long esize;
4515
4516 esize = e[i].start - pos;
4517 if (esize >= maxsize)
4518 maxsize = esize;
4519 pos = e[i].start + e[i].size;
4520 i++;
4521 } while (e[i-1].size);
4522 dl->e = e;
4523 dl->extent_cnt = i;
4524 } else {
4525 if (verbose)
4526 fprintf(stderr, Name ": unable to determine free space for: %s\n",
4527 dev);
4528 return 0;
4529 }
4530 if (maxsize < size) {
4531 if (verbose)
4532 fprintf(stderr, Name ": %s not enough space (%llu < %llu)\n",
4533 dev, maxsize, size);
4534 return 0;
4535 }
4536
4537 /* count total number of extents for merge */
4538 i = 0;
4539 for (dl = super->disks; dl; dl = dl->next)
4540 if (dl->e)
4541 i += dl->extent_cnt;
4542
4543 maxsize = merge_extents(super, i);
a7dd165b 4544 if (maxsize < size || maxsize == 0) {
0dcecb2e
DW
4545 if (verbose)
4546 fprintf(stderr, Name ": not enough space after merge (%llu < %llu)\n",
4547 maxsize, size);
4548 return 0;
0dcecb2e
DW
4549 }
4550
c2c087e6
DW
4551 *freesize = maxsize;
4552
4553 return 1;
cdddbdbc
DW
4554}
4555
efb30e7f
DW
4556static int reserve_space(struct supertype *st, int raiddisks,
4557 unsigned long long size, int chunk,
4558 unsigned long long *freesize)
4559{
4560 struct intel_super *super = st->sb;
4561 struct imsm_super *mpb = super->anchor;
4562 struct dl *dl;
4563 int i;
4564 int extent_cnt;
4565 struct extent *e;
4566 unsigned long long maxsize;
4567 unsigned long long minsize;
4568 int cnt;
4569 int used;
4570
4571 /* find the largest common start free region of the possible disks */
4572 used = 0;
4573 extent_cnt = 0;
4574 cnt = 0;
4575 for (dl = super->disks; dl; dl = dl->next) {
4576 dl->raiddisk = -1;
4577
4578 if (dl->index >= 0)
4579 used++;
4580
4581 /* don't activate new spares if we are orom constrained
4582 * and there is already a volume active in the container
4583 */
4584 if (super->orom && dl->index < 0 && mpb->num_raid_devs)
4585 continue;
4586
4587 e = get_extents(super, dl);
4588 if (!e)
4589 continue;
4590 for (i = 1; e[i-1].size; i++)
4591 ;
4592 dl->e = e;
4593 dl->extent_cnt = i;
4594 extent_cnt += i;
4595 cnt++;
4596 }
4597
4598 maxsize = merge_extents(super, extent_cnt);
4599 minsize = size;
4600 if (size == 0)
612e59d8
CA
4601 /* chunk is in K */
4602 minsize = chunk * 2;
efb30e7f
DW
4603
4604 if (cnt < raiddisks ||
4605 (super->orom && used && used != raiddisks) ||
a7dd165b
DW
4606 maxsize < minsize ||
4607 maxsize == 0) {
efb30e7f
DW
4608 fprintf(stderr, Name ": not enough devices with space to create array.\n");
4609 return 0; /* No enough free spaces large enough */
4610 }
4611
4612 if (size == 0) {
4613 size = maxsize;
4614 if (chunk) {
612e59d8
CA
4615 size /= 2 * chunk;
4616 size *= 2 * chunk;
efb30e7f
DW
4617 }
4618 }
4619
4620 cnt = 0;
4621 for (dl = super->disks; dl; dl = dl->next)
4622 if (dl->e)
4623 dl->raiddisk = cnt++;
4624
4625 *freesize = size;
4626
4627 return 1;
4628}
4629
bf5a934a 4630static int validate_geometry_imsm(struct supertype *st, int level, int layout,
c21e737b 4631 int raiddisks, int *chunk, unsigned long long size,
bf5a934a
DW
4632 char *dev, unsigned long long *freesize,
4633 int verbose)
4634{
4635 int fd, cfd;
4636 struct mdinfo *sra;
20cbe8d2 4637 int is_member = 0;
bf5a934a 4638
d54559f0
LM
4639 /* load capability
4640 * if given unused devices create a container
bf5a934a
DW
4641 * if given given devices in a container create a member volume
4642 */
4643 if (level == LEVEL_CONTAINER) {
4644 /* Must be a fresh device to add to a container */
4645 return validate_geometry_imsm_container(st, level, layout,
c21e737b
CA
4646 raiddisks,
4647 chunk?*chunk:0, size,
bf5a934a
DW
4648 dev, freesize,
4649 verbose);
4650 }
4651
8592f29d
N
4652 if (!dev) {
4653 if (st->sb && freesize) {
efb30e7f
DW
4654 /* we are being asked to automatically layout a
4655 * new volume based on the current contents of
4656 * the container. If the the parameters can be
4657 * satisfied reserve_space will record the disks,
4658 * start offset, and size of the volume to be
4659 * created. add_to_super and getinfo_super
4660 * detect when autolayout is in progress.
4661 */
6592ce37
DW
4662 if (!validate_geometry_imsm_orom(st->sb, level, layout,
4663 raiddisks, chunk,
4664 verbose))
4665 return 0;
c21e737b
CA
4666 return reserve_space(st, raiddisks, size,
4667 chunk?*chunk:0, freesize);
8592f29d
N
4668 }
4669 return 1;
4670 }
bf5a934a
DW
4671 if (st->sb) {
4672 /* creating in a given container */
4673 return validate_geometry_imsm_volume(st, level, layout,
4674 raiddisks, chunk, size,
4675 dev, freesize, verbose);
4676 }
4677
bf5a934a
DW
4678 /* This device needs to be a device in an 'imsm' container */
4679 fd = open(dev, O_RDONLY|O_EXCL, 0);
4680 if (fd >= 0) {
4681 if (verbose)
4682 fprintf(stderr,
4683 Name ": Cannot create this array on device %s\n",
4684 dev);
4685 close(fd);
4686 return 0;
4687 }
4688 if (errno != EBUSY || (fd = open(dev, O_RDONLY, 0)) < 0) {
4689 if (verbose)
4690 fprintf(stderr, Name ": Cannot open %s: %s\n",
4691 dev, strerror(errno));
4692 return 0;
4693 }
4694 /* Well, it is in use by someone, maybe an 'imsm' container. */
4695 cfd = open_container(fd);
20cbe8d2 4696 close(fd);
bf5a934a 4697 if (cfd < 0) {
bf5a934a
DW
4698 if (verbose)
4699 fprintf(stderr, Name ": Cannot use %s: It is busy\n",
4700 dev);
4701 return 0;
4702 }
4703 sra = sysfs_read(cfd, 0, GET_VERSION);
bf5a934a 4704 if (sra && sra->array.major_version == -1 &&
20cbe8d2
AW
4705 strcmp(sra->text_version, "imsm") == 0)
4706 is_member = 1;
4707 sysfs_free(sra);
4708 if (is_member) {
bf5a934a
DW
4709 /* This is a member of a imsm container. Load the container
4710 * and try to create a volume
4711 */
4712 struct intel_super *super;
4713
e1902a7b 4714 if (load_super_imsm_all(st, cfd, (void **) &super, NULL) == 0) {
bf5a934a
DW
4715 st->sb = super;
4716 st->container_dev = fd2devnum(cfd);
4717 close(cfd);
4718 return validate_geometry_imsm_volume(st, level, layout,
4719 raiddisks, chunk,
4720 size, dev,
4721 freesize, verbose);
4722 }
20cbe8d2 4723 }
bf5a934a 4724
20cbe8d2
AW
4725 if (verbose)
4726 fprintf(stderr, Name ": failed container membership check\n");
4727
4728 close(cfd);
4729 return 0;
bf5a934a 4730}
0bd16cf2 4731
30f58b22 4732static void default_geometry_imsm(struct supertype *st, int *level, int *layout, int *chunk)
0bd16cf2
DJ
4733{
4734 struct intel_super *super = st->sb;
4735
30f58b22
DW
4736 if (level && *level == UnSet)
4737 *level = LEVEL_CONTAINER;
4738
4739 if (level && layout && *layout == UnSet)
4740 *layout = imsm_level_to_layout(*level);
0bd16cf2 4741
1d54f286
N
4742 if (chunk && (*chunk == UnSet || *chunk == 0) &&
4743 super && super->orom)
30f58b22 4744 *chunk = imsm_orom_default_chunk(super->orom);
0bd16cf2
DJ
4745}
4746
33414a01
DW
4747static void handle_missing(struct intel_super *super, struct imsm_dev *dev);
4748
4749static int kill_subarray_imsm(struct supertype *st)
4750{
4751 /* remove the subarray currently referenced by ->current_vol */
4752 __u8 i;
4753 struct intel_dev **dp;
4754 struct intel_super *super = st->sb;
4755 __u8 current_vol = super->current_vol;
4756 struct imsm_super *mpb = super->anchor;
4757
4758 if (super->current_vol < 0)
4759 return 2;
4760 super->current_vol = -1; /* invalidate subarray cursor */
4761
4762 /* block deletions that would change the uuid of active subarrays
4763 *
4764 * FIXME when immutable ids are available, but note that we'll
4765 * also need to fixup the invalidated/active subarray indexes in
4766 * mdstat
4767 */
4768 for (i = 0; i < mpb->num_raid_devs; i++) {
4769 char subarray[4];
4770
4771 if (i < current_vol)
4772 continue;
4773 sprintf(subarray, "%u", i);
4774 if (is_subarray_active(subarray, st->devname)) {
4775 fprintf(stderr,
4776 Name ": deleting subarray-%d would change the UUID of active subarray-%d, aborting\n",
4777 current_vol, i);
4778
4779 return 2;
4780 }
4781 }
4782
4783 if (st->update_tail) {
4784 struct imsm_update_kill_array *u = malloc(sizeof(*u));
4785
4786 if (!u)
4787 return 2;
4788 u->type = update_kill_array;
4789 u->dev_idx = current_vol;
4790 append_metadata_update(st, u, sizeof(*u));
4791
4792 return 0;
4793 }
4794
4795 for (dp = &super->devlist; *dp;)
4796 if ((*dp)->index == current_vol) {
4797 *dp = (*dp)->next;
4798 } else {
4799 handle_missing(super, (*dp)->dev);
4800 if ((*dp)->index > current_vol)
4801 (*dp)->index--;
4802 dp = &(*dp)->next;
4803 }
4804
4805 /* no more raid devices, all active components are now spares,
4806 * but of course failed are still failed
4807 */
4808 if (--mpb->num_raid_devs == 0) {
4809 struct dl *d;
4810
4811 for (d = super->disks; d; d = d->next)
4812 if (d->index > -2) {
4813 d->index = -1;
4814 d->disk.status = SPARE_DISK;
4815 }
4816 }
4817
4818 super->updates_pending++;
4819
4820 return 0;
4821}
aa534678 4822
a951a4f7 4823static int update_subarray_imsm(struct supertype *st, char *subarray,
fa56eddb 4824 char *update, struct mddev_ident *ident)
aa534678
DW
4825{
4826 /* update the subarray currently referenced by ->current_vol */
4827 struct intel_super *super = st->sb;
4828 struct imsm_super *mpb = super->anchor;
4829
aa534678
DW
4830 if (strcmp(update, "name") == 0) {
4831 char *name = ident->name;
a951a4f7
N
4832 char *ep;
4833 int vol;
aa534678 4834
a951a4f7 4835 if (is_subarray_active(subarray, st->devname)) {
aa534678
DW
4836 fprintf(stderr,
4837 Name ": Unable to update name of active subarray\n");
4838 return 2;
4839 }
4840
4841 if (!check_name(super, name, 0))
4842 return 2;
4843
a951a4f7
N
4844 vol = strtoul(subarray, &ep, 10);
4845 if (*ep != '\0' || vol >= super->anchor->num_raid_devs)
4846 return 2;
4847
aa534678
DW
4848 if (st->update_tail) {
4849 struct imsm_update_rename_array *u = malloc(sizeof(*u));
4850
4851 if (!u)
4852 return 2;
4853 u->type = update_rename_array;
a951a4f7 4854 u->dev_idx = vol;
aa534678
DW
4855 snprintf((char *) u->name, MAX_RAID_SERIAL_LEN, "%s", name);
4856 append_metadata_update(st, u, sizeof(*u));
4857 } else {
4858 struct imsm_dev *dev;
4859 int i;
4860
a951a4f7 4861 dev = get_imsm_dev(super, vol);
aa534678
DW
4862 snprintf((char *) dev->volume, MAX_RAID_SERIAL_LEN, "%s", name);
4863 for (i = 0; i < mpb->num_raid_devs; i++) {
4864 dev = get_imsm_dev(super, i);
4865 handle_missing(super, dev);
4866 }
4867 super->updates_pending++;
4868 }
4869 } else
4870 return 2;
4871
4872 return 0;
4873}
bf5a934a 4874
28bce06f
AK
4875static int is_gen_migration(struct imsm_dev *dev)
4876{
4877 if (!dev->vol.migr_state)
4878 return 0;
4879
4880 if (migr_type(dev) == MIGR_GEN_MIGR)
4881 return 1;
4882
4883 return 0;
4884}
71204a50 4885#endif /* MDASSEMBLE */
28bce06f 4886
1e5c6983
DW
4887static int is_rebuilding(struct imsm_dev *dev)
4888{
4889 struct imsm_map *migr_map;
4890
4891 if (!dev->vol.migr_state)
4892 return 0;
4893
4894 if (migr_type(dev) != MIGR_REBUILD)
4895 return 0;
4896
4897 migr_map = get_imsm_map(dev, 1);
4898
4899 if (migr_map->map_state == IMSM_T_STATE_DEGRADED)
4900 return 1;
4901 else
4902 return 0;
4903}
4904
4905static void update_recovery_start(struct imsm_dev *dev, struct mdinfo *array)
4906{
4907 struct mdinfo *rebuild = NULL;
4908 struct mdinfo *d;
4909 __u32 units;
4910
4911 if (!is_rebuilding(dev))
4912 return;
4913
4914 /* Find the rebuild target, but punt on the dual rebuild case */
4915 for (d = array->devs; d; d = d->next)
4916 if (d->recovery_start == 0) {
4917 if (rebuild)
4918 return;
4919 rebuild = d;
4920 }
4921
4363fd80
DW
4922 if (!rebuild) {
4923 /* (?) none of the disks are marked with
4924 * IMSM_ORD_REBUILD, so assume they are missing and the
4925 * disk_ord_tbl was not correctly updated
4926 */
4927 dprintf("%s: failed to locate out-of-sync disk\n", __func__);
4928 return;
4929 }
4930
1e5c6983
DW
4931 units = __le32_to_cpu(dev->vol.curr_migr_unit);
4932 rebuild->recovery_start = units * blocks_per_migr_unit(dev);
4933}
4934
4935
00bbdbda 4936static struct mdinfo *container_content_imsm(struct supertype *st, char *subarray)
cdddbdbc 4937{
4f5bc454
DW
4938 /* Given a container loaded by load_super_imsm_all,
4939 * extract information about all the arrays into
4940 * an mdinfo tree.
00bbdbda 4941 * If 'subarray' is given, just extract info about that array.
4f5bc454
DW
4942 *
4943 * For each imsm_dev create an mdinfo, fill it in,
4944 * then look for matching devices in super->disks
4945 * and create appropriate device mdinfo.
4946 */
4947 struct intel_super *super = st->sb;
949c47a0 4948 struct imsm_super *mpb = super->anchor;
4f5bc454 4949 struct mdinfo *rest = NULL;
00bbdbda 4950 unsigned int i;
a06d022d 4951 int bbm_errors = 0;
abef11a3
AK
4952 struct dl *d;
4953 int spare_disks = 0;
cdddbdbc 4954
a06d022d
KW
4955 /* check for bad blocks */
4956 if (imsm_bbm_log_size(super->anchor))
4957 bbm_errors = 1;
604b746f 4958
abef11a3
AK
4959 /* count spare devices, not used in maps
4960 */
4961 for (d = super->disks; d; d = d->next)
4962 if (d->index == -1)
4963 spare_disks++;
4964
4f5bc454 4965 for (i = 0; i < mpb->num_raid_devs; i++) {
00bbdbda
N
4966 struct imsm_dev *dev;
4967 struct imsm_map *map;
86e3692b 4968 struct imsm_map *map2;
4f5bc454 4969 struct mdinfo *this;
2db86302 4970 int slot, chunk;
00bbdbda
N
4971 char *ep;
4972
4973 if (subarray &&
4974 (i != strtoul(subarray, &ep, 10) || *ep != '\0'))
4975 continue;
4976
4977 dev = get_imsm_dev(super, i);
4978 map = get_imsm_map(dev, 0);
86e3692b 4979 map2 = get_imsm_map(dev, 1);
4f5bc454 4980
1ce0101c
DW
4981 /* do not publish arrays that are in the middle of an
4982 * unsupported migration
4983 */
4984 if (dev->vol.migr_state &&
28bce06f 4985 (migr_type(dev) == MIGR_STATE_CHANGE)) {
1ce0101c
DW
4986 fprintf(stderr, Name ": cannot assemble volume '%.16s':"
4987 " unsupported migration in progress\n",
4988 dev->volume);
4989 continue;
4990 }
2db86302
LM
4991 /* do not publish arrays that are not support by controller's
4992 * OROM/EFI
4993 */
1ce0101c 4994
2db86302 4995 chunk = __le16_to_cpu(map->blocks_per_strip) >> 1;
7b0bbd0f 4996#ifndef MDASSEMBLE
2db86302
LM
4997 if (!validate_geometry_imsm_orom(super,
4998 get_imsm_raid_level(map), /* RAID level */
4999 imsm_level_to_layout(get_imsm_raid_level(map)),
5000 map->num_members, /* raid disks */
5001 &chunk,
5002 1 /* verbose */)) {
5003 fprintf(stderr, Name ": RAID gemetry validation failed. "
5004 "Cannot proceed with the action(s).\n");
5005 continue;
5006 }
7b0bbd0f 5007#endif /* MDASSEMBLE */
4f5bc454 5008 this = malloc(sizeof(*this));
0fbd635c 5009 if (!this) {
cf1be220 5010 fprintf(stderr, Name ": failed to allocate %zu bytes\n",
0fbd635c
AW
5011 sizeof(*this));
5012 break;
5013 }
4f5bc454
DW
5014 memset(this, 0, sizeof(*this));
5015 this->next = rest;
4f5bc454 5016
301406c9 5017 super->current_vol = i;
a5d85af7 5018 getinfo_super_imsm_volume(st, this, NULL);
4f5bc454 5019 for (slot = 0 ; slot < map->num_members; slot++) {
1e5c6983 5020 unsigned long long recovery_start;
4f5bc454
DW
5021 struct mdinfo *info_d;
5022 struct dl *d;
5023 int idx;
9a1608e5 5024 int skip;
7eef0453 5025 __u32 ord;
4f5bc454 5026
9a1608e5 5027 skip = 0;
98130f40 5028 idx = get_imsm_disk_idx(dev, slot, 0);
196b0d44 5029 ord = get_imsm_ord_tbl_ent(dev, slot, -1);
4f5bc454
DW
5030 for (d = super->disks; d ; d = d->next)
5031 if (d->index == idx)
0fbd635c 5032 break;
4f5bc454 5033
1e5c6983 5034 recovery_start = MaxSector;
4f5bc454 5035 if (d == NULL)
9a1608e5 5036 skip = 1;
25ed7e59 5037 if (d && is_failed(&d->disk))
9a1608e5 5038 skip = 1;
7eef0453 5039 if (ord & IMSM_ORD_REBUILD)
1e5c6983 5040 recovery_start = 0;
9a1608e5
DW
5041
5042 /*
5043 * if we skip some disks the array will be assmebled degraded;
1e5c6983
DW
5044 * reset resync start to avoid a dirty-degraded
5045 * situation when performing the intial sync
9a1608e5
DW
5046 *
5047 * FIXME handle dirty degraded
5048 */
1e5c6983 5049 if ((skip || recovery_start == 0) && !dev->vol.dirty)
b7528a20 5050 this->resync_start = MaxSector;
9a1608e5
DW
5051 if (skip)
5052 continue;
4f5bc454 5053
1e5c6983 5054 info_d = calloc(1, sizeof(*info_d));
9a1608e5
DW
5055 if (!info_d) {
5056 fprintf(stderr, Name ": failed to allocate disk"
1ce0101c 5057 " for volume %.16s\n", dev->volume);
1e5c6983
DW
5058 info_d = this->devs;
5059 while (info_d) {
5060 struct mdinfo *d = info_d->next;
5061
5062 free(info_d);
5063 info_d = d;
5064 }
9a1608e5
DW
5065 free(this);
5066 this = rest;
5067 break;
5068 }
4f5bc454
DW
5069 info_d->next = this->devs;
5070 this->devs = info_d;
5071
4f5bc454
DW
5072 info_d->disk.number = d->index;
5073 info_d->disk.major = d->major;
5074 info_d->disk.minor = d->minor;
5075 info_d->disk.raid_disk = slot;
1e5c6983 5076 info_d->recovery_start = recovery_start;
86e3692b
AK
5077 if (map2) {
5078 if (slot < map2->num_members)
5079 info_d->disk.state = (1 << MD_DISK_ACTIVE);
04c3c514
AK
5080 else
5081 this->array.spare_disks++;
86e3692b
AK
5082 } else {
5083 if (slot < map->num_members)
5084 info_d->disk.state = (1 << MD_DISK_ACTIVE);
04c3c514
AK
5085 else
5086 this->array.spare_disks++;
86e3692b 5087 }
1e5c6983
DW
5088 if (info_d->recovery_start == MaxSector)
5089 this->array.working_disks++;
4f5bc454
DW
5090
5091 info_d->events = __le32_to_cpu(mpb->generation_num);
5092 info_d->data_offset = __le32_to_cpu(map->pba_of_lba0);
5093 info_d->component_size = __le32_to_cpu(map->blocks_per_member);
4f5bc454 5094 }
1e5c6983
DW
5095 /* now that the disk list is up-to-date fixup recovery_start */
5096 update_recovery_start(dev, this);
abef11a3 5097 this->array.spare_disks += spare_disks;
9a1608e5 5098 rest = this;
4f5bc454
DW
5099 }
5100
a06d022d
KW
5101 /* if array has bad blocks, set suitable bit in array status */
5102 if (bbm_errors)
5103 rest->array.state |= (1<<MD_SB_BBM_ERRORS);
5104
4f5bc454 5105 return rest;
cdddbdbc
DW
5106}
5107
845dea95 5108
fb49eef2 5109static __u8 imsm_check_degraded(struct intel_super *super, struct imsm_dev *dev, int failed)
c2a1e7da 5110{
a965f303 5111 struct imsm_map *map = get_imsm_map(dev, 0);
c2a1e7da
DW
5112
5113 if (!failed)
3393c6af
DW
5114 return map->map_state == IMSM_T_STATE_UNINITIALIZED ?
5115 IMSM_T_STATE_UNINITIALIZED : IMSM_T_STATE_NORMAL;
c2a1e7da
DW
5116
5117 switch (get_imsm_raid_level(map)) {
5118 case 0:
5119 return IMSM_T_STATE_FAILED;
5120 break;
5121 case 1:
5122 if (failed < map->num_members)
5123 return IMSM_T_STATE_DEGRADED;
5124 else
5125 return IMSM_T_STATE_FAILED;
5126 break;
5127 case 10:
5128 {
5129 /**
c92a2527
DW
5130 * check to see if any mirrors have failed, otherwise we
5131 * are degraded. Even numbered slots are mirrored on
5132 * slot+1
c2a1e7da 5133 */
c2a1e7da 5134 int i;
d9b420a5
N
5135 /* gcc -Os complains that this is unused */
5136 int insync = insync;
c2a1e7da
DW
5137
5138 for (i = 0; i < map->num_members; i++) {
98130f40 5139 __u32 ord = get_imsm_ord_tbl_ent(dev, i, -1);
c92a2527
DW
5140 int idx = ord_to_idx(ord);
5141 struct imsm_disk *disk;
c2a1e7da 5142
c92a2527
DW
5143 /* reset the potential in-sync count on even-numbered
5144 * slots. num_copies is always 2 for imsm raid10
5145 */
5146 if ((i & 1) == 0)
5147 insync = 2;
c2a1e7da 5148
c92a2527 5149 disk = get_imsm_disk(super, idx);
25ed7e59 5150 if (!disk || is_failed(disk) || ord & IMSM_ORD_REBUILD)
c92a2527 5151 insync--;
c2a1e7da 5152
c92a2527
DW
5153 /* no in-sync disks left in this mirror the
5154 * array has failed
5155 */
5156 if (insync == 0)
5157 return IMSM_T_STATE_FAILED;
c2a1e7da
DW
5158 }
5159
5160 return IMSM_T_STATE_DEGRADED;
5161 }
5162 case 5:
5163 if (failed < 2)
5164 return IMSM_T_STATE_DEGRADED;
5165 else
5166 return IMSM_T_STATE_FAILED;
5167 break;
5168 default:
5169 break;
5170 }
5171
5172 return map->map_state;
5173}
5174
ff077194 5175static int imsm_count_failed(struct intel_super *super, struct imsm_dev *dev)
c2a1e7da
DW
5176{
5177 int i;
5178 int failed = 0;
5179 struct imsm_disk *disk;
ff077194 5180 struct imsm_map *map = get_imsm_map(dev, 0);
0556e1a2
DW
5181 struct imsm_map *prev = get_imsm_map(dev, dev->vol.migr_state);
5182 __u32 ord;
5183 int idx;
c2a1e7da 5184
0556e1a2
DW
5185 /* at the beginning of migration we set IMSM_ORD_REBUILD on
5186 * disks that are being rebuilt. New failures are recorded to
5187 * map[0]. So we look through all the disks we started with and
5188 * see if any failures are still present, or if any new ones
5189 * have arrived
5190 *
5191 * FIXME add support for online capacity expansion and
5192 * raid-level-migration
5193 */
5194 for (i = 0; i < prev->num_members; i++) {
5195 ord = __le32_to_cpu(prev->disk_ord_tbl[i]);
5196 ord |= __le32_to_cpu(map->disk_ord_tbl[i]);
5197 idx = ord_to_idx(ord);
c2a1e7da 5198
949c47a0 5199 disk = get_imsm_disk(super, idx);
25ed7e59 5200 if (!disk || is_failed(disk) || ord & IMSM_ORD_REBUILD)
fcb84475 5201 failed++;
c2a1e7da
DW
5202 }
5203
5204 return failed;
845dea95
NB
5205}
5206
97b4d0e9
DW
5207#ifndef MDASSEMBLE
5208static int imsm_open_new(struct supertype *c, struct active_array *a,
5209 char *inst)
5210{
5211 struct intel_super *super = c->sb;
5212 struct imsm_super *mpb = super->anchor;
5213
5214 if (atoi(inst) >= mpb->num_raid_devs) {
5215 fprintf(stderr, "%s: subarry index %d, out of range\n",
5216 __func__, atoi(inst));
5217 return -ENODEV;
5218 }
5219
5220 dprintf("imsm: open_new %s\n", inst);
5221 a->info.container_member = atoi(inst);
5222 return 0;
5223}
5224
0c046afd
DW
5225static int is_resyncing(struct imsm_dev *dev)
5226{
5227 struct imsm_map *migr_map;
5228
5229 if (!dev->vol.migr_state)
5230 return 0;
5231
1484e727
DW
5232 if (migr_type(dev) == MIGR_INIT ||
5233 migr_type(dev) == MIGR_REPAIR)
0c046afd
DW
5234 return 1;
5235
4c9bc37b
AK
5236 if (migr_type(dev) == MIGR_GEN_MIGR)
5237 return 0;
5238
0c046afd
DW
5239 migr_map = get_imsm_map(dev, 1);
5240
4c9bc37b
AK
5241 if ((migr_map->map_state == IMSM_T_STATE_NORMAL) &&
5242 (dev->vol.migr_type != MIGR_GEN_MIGR))
0c046afd
DW
5243 return 1;
5244 else
5245 return 0;
5246}
5247
0556e1a2
DW
5248/* return true if we recorded new information */
5249static int mark_failure(struct imsm_dev *dev, struct imsm_disk *disk, int idx)
47ee5a45 5250{
0556e1a2
DW
5251 __u32 ord;
5252 int slot;
5253 struct imsm_map *map;
5254
5255 /* new failures are always set in map[0] */
5256 map = get_imsm_map(dev, 0);
5257
5258 slot = get_imsm_disk_slot(map, idx);
5259 if (slot < 0)
5260 return 0;
5261
5262 ord = __le32_to_cpu(map->disk_ord_tbl[slot]);
25ed7e59 5263 if (is_failed(disk) && (ord & IMSM_ORD_REBUILD))
0556e1a2
DW
5264 return 0;
5265
f2f27e63 5266 disk->status |= FAILED_DISK;
0556e1a2 5267 set_imsm_ord_tbl_ent(map, slot, idx | IMSM_ORD_REBUILD);
f21e18ca 5268 if (map->failed_disk_num == 0xff)
0556e1a2
DW
5269 map->failed_disk_num = slot;
5270 return 1;
5271}
5272
5273static void mark_missing(struct imsm_dev *dev, struct imsm_disk *disk, int idx)
5274{
5275 mark_failure(dev, disk, idx);
5276
5277 if (disk->scsi_id == __cpu_to_le32(~(__u32)0))
5278 return;
5279
47ee5a45
DW
5280 disk->scsi_id = __cpu_to_le32(~(__u32)0);
5281 memmove(&disk->serial[0], &disk->serial[1], MAX_RAID_SERIAL_LEN - 1);
5282}
5283
33414a01
DW
5284static void handle_missing(struct intel_super *super, struct imsm_dev *dev)
5285{
5286 __u8 map_state;
5287 struct dl *dl;
5288 int failed;
5289
5290 if (!super->missing)
5291 return;
5292 failed = imsm_count_failed(super, dev);
5293 map_state = imsm_check_degraded(super, dev, failed);
5294
5295 dprintf("imsm: mark missing\n");
5296 end_migration(dev, map_state);
5297 for (dl = super->missing; dl; dl = dl->next)
5298 mark_missing(dev, &dl->disk, dl->index);
5299 super->updates_pending++;
5300}
5301
70bdf0dc
AK
5302static unsigned long long imsm_set_array_size(struct imsm_dev *dev)
5303{
5304 int used_disks = imsm_num_data_members(dev, 0);
5305 unsigned long long array_blocks;
5306 struct imsm_map *map;
5307
5308 if (used_disks == 0) {
5309 /* when problems occures
5310 * return current array_blocks value
5311 */
5312 array_blocks = __le32_to_cpu(dev->size_high);
5313 array_blocks = array_blocks << 32;
5314 array_blocks += __le32_to_cpu(dev->size_low);
5315
5316 return array_blocks;
5317 }
5318
5319 /* set array size in metadata
5320 */
5321 map = get_imsm_map(dev, 0);
5322 array_blocks = map->blocks_per_member * used_disks;
5323
5324 /* round array size down to closest MB
5325 */
5326 array_blocks = (array_blocks >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT;
5327 dev->size_low = __cpu_to_le32((__u32)array_blocks);
5328 dev->size_high = __cpu_to_le32((__u32)(array_blocks >> 32));
5329
5330 return array_blocks;
5331}
5332
28bce06f
AK
5333static void imsm_set_disk(struct active_array *a, int n, int state);
5334
0e2d1a4e
AK
5335static void imsm_progress_container_reshape(struct intel_super *super)
5336{
5337 /* if no device has a migr_state, but some device has a
5338 * different number of members than the previous device, start
5339 * changing the number of devices in this device to match
5340 * previous.
5341 */
5342 struct imsm_super *mpb = super->anchor;
5343 int prev_disks = -1;
5344 int i;
1dfaa380 5345 int copy_map_size;
0e2d1a4e
AK
5346
5347 for (i = 0; i < mpb->num_raid_devs; i++) {
5348 struct imsm_dev *dev = get_imsm_dev(super, i);
5349 struct imsm_map *map = get_imsm_map(dev, 0);
5350 struct imsm_map *map2;
5351 int prev_num_members;
0e2d1a4e
AK
5352
5353 if (dev->vol.migr_state)
5354 return;
5355
5356 if (prev_disks == -1)
5357 prev_disks = map->num_members;
5358 if (prev_disks == map->num_members)
5359 continue;
5360
5361 /* OK, this array needs to enter reshape mode.
5362 * i.e it needs a migr_state
5363 */
5364
1dfaa380 5365 copy_map_size = sizeof_imsm_map(map);
0e2d1a4e
AK
5366 prev_num_members = map->num_members;
5367 map->num_members = prev_disks;
5368 dev->vol.migr_state = 1;
5369 dev->vol.curr_migr_unit = 0;
5370 dev->vol.migr_type = MIGR_GEN_MIGR;
5371 for (i = prev_num_members;
5372 i < map->num_members; i++)
5373 set_imsm_ord_tbl_ent(map, i, i);
5374 map2 = get_imsm_map(dev, 1);
5375 /* Copy the current map */
1dfaa380 5376 memcpy(map2, map, copy_map_size);
0e2d1a4e
AK
5377 map2->num_members = prev_num_members;
5378
70bdf0dc 5379 imsm_set_array_size(dev);
0e2d1a4e
AK
5380 super->updates_pending++;
5381 }
5382}
5383
aad6f216 5384/* Handle dirty -> clean transititions, resync and reshape. Degraded and rebuild
0c046afd
DW
5385 * states are handled in imsm_set_disk() with one exception, when a
5386 * resync is stopped due to a new failure this routine will set the
5387 * 'degraded' state for the array.
5388 */
01f157d7 5389static int imsm_set_array_state(struct active_array *a, int consistent)
a862209d
DW
5390{
5391 int inst = a->info.container_member;
5392 struct intel_super *super = a->container->sb;
949c47a0 5393 struct imsm_dev *dev = get_imsm_dev(super, inst);
a965f303 5394 struct imsm_map *map = get_imsm_map(dev, 0);
0c046afd
DW
5395 int failed = imsm_count_failed(super, dev);
5396 __u8 map_state = imsm_check_degraded(super, dev, failed);
1e5c6983 5397 __u32 blocks_per_unit;
a862209d 5398
1af97990
AK
5399 if (dev->vol.migr_state &&
5400 dev->vol.migr_type == MIGR_GEN_MIGR) {
5401 /* array state change is blocked due to reshape action
aad6f216
N
5402 * We might need to
5403 * - abort the reshape (if last_checkpoint is 0 and action!= reshape)
5404 * - finish the reshape (if last_checkpoint is big and action != reshape)
5405 * - update curr_migr_unit
1af97990 5406 */
aad6f216
N
5407 if (a->curr_action == reshape) {
5408 /* still reshaping, maybe update curr_migr_unit */
633b5610 5409 goto mark_checkpoint;
aad6f216
N
5410 } else {
5411 if (a->last_checkpoint == 0 && a->prev_action == reshape) {
5412 /* for some reason we aborted the reshape.
5413 * Better clean up
5414 */
5415 struct imsm_map *map2 = get_imsm_map(dev, 1);
5416 dev->vol.migr_state = 0;
5417 dev->vol.migr_type = 0;
5418 dev->vol.curr_migr_unit = 0;
5419 memcpy(map, map2, sizeof_imsm_map(map2));
5420 super->updates_pending++;
5421 }
5422 if (a->last_checkpoint >= a->info.component_size) {
5423 unsigned long long array_blocks;
5424 int used_disks;
e154ced3 5425 struct mdinfo *mdi;
aad6f216 5426
9653001d 5427 used_disks = imsm_num_data_members(dev, 0);
d55adef9
AK
5428 if (used_disks > 0) {
5429 array_blocks =
5430 map->blocks_per_member *
5431 used_disks;
5432 /* round array size down to closest MB
5433 */
5434 array_blocks = (array_blocks
5435 >> SECT_PER_MB_SHIFT)
5436 << SECT_PER_MB_SHIFT;
d55adef9
AK
5437 a->info.custom_array_size = array_blocks;
5438 /* encourage manager to update array
5439 * size
5440 */
e154ced3 5441
d55adef9 5442 a->check_reshape = 1;
633b5610 5443 }
e154ced3
AK
5444 /* finalize online capacity expansion/reshape */
5445 for (mdi = a->info.devs; mdi; mdi = mdi->next)
5446 imsm_set_disk(a,
5447 mdi->disk.raid_disk,
5448 mdi->curr_state);
5449
0e2d1a4e 5450 imsm_progress_container_reshape(super);
e154ced3 5451 }
aad6f216 5452 }
1af97990
AK
5453 }
5454
47ee5a45 5455 /* before we activate this array handle any missing disks */
33414a01
DW
5456 if (consistent == 2)
5457 handle_missing(super, dev);
1e5c6983 5458
0c046afd 5459 if (consistent == 2 &&
b7941fd6 5460 (!is_resync_complete(&a->info) ||
0c046afd
DW
5461 map_state != IMSM_T_STATE_NORMAL ||
5462 dev->vol.migr_state))
01f157d7 5463 consistent = 0;
272906ef 5464
b7941fd6 5465 if (is_resync_complete(&a->info)) {
0c046afd 5466 /* complete intialization / resync,
0556e1a2
DW
5467 * recovery and interrupted recovery is completed in
5468 * ->set_disk
0c046afd
DW
5469 */
5470 if (is_resyncing(dev)) {
5471 dprintf("imsm: mark resync done\n");
f8f603f1 5472 end_migration(dev, map_state);
115c3803 5473 super->updates_pending++;
484240d8 5474 a->last_checkpoint = 0;
115c3803 5475 }
0c046afd
DW
5476 } else if (!is_resyncing(dev) && !failed) {
5477 /* mark the start of the init process if nothing is failed */
b7941fd6 5478 dprintf("imsm: mark resync start\n");
1484e727 5479 if (map->map_state == IMSM_T_STATE_UNINITIALIZED)
e3bba0e0 5480 migrate(dev, IMSM_T_STATE_NORMAL, MIGR_INIT);
1484e727
DW
5481 else
5482 migrate(dev, IMSM_T_STATE_NORMAL, MIGR_REPAIR);
3393c6af 5483 super->updates_pending++;
115c3803 5484 }
a862209d 5485
633b5610 5486mark_checkpoint:
1e5c6983
DW
5487 /* check if we can update curr_migr_unit from resync_start, recovery_start */
5488 blocks_per_unit = blocks_per_migr_unit(dev);
4f0a7acc 5489 if (blocks_per_unit) {
1e5c6983
DW
5490 __u32 units32;
5491 __u64 units;
5492
4f0a7acc 5493 units = a->last_checkpoint / blocks_per_unit;
1e5c6983
DW
5494 units32 = units;
5495
5496 /* check that we did not overflow 32-bits, and that
5497 * curr_migr_unit needs updating
5498 */
5499 if (units32 == units &&
bfd80a56 5500 units32 != 0 &&
1e5c6983
DW
5501 __le32_to_cpu(dev->vol.curr_migr_unit) != units32) {
5502 dprintf("imsm: mark checkpoint (%u)\n", units32);
5503 dev->vol.curr_migr_unit = __cpu_to_le32(units32);
5504 super->updates_pending++;
5505 }
5506 }
f8f603f1 5507
3393c6af 5508 /* mark dirty / clean */
0c046afd 5509 if (dev->vol.dirty != !consistent) {
b7941fd6 5510 dprintf("imsm: mark '%s'\n", consistent ? "clean" : "dirty");
0c046afd
DW
5511 if (consistent)
5512 dev->vol.dirty = 0;
5513 else
5514 dev->vol.dirty = 1;
a862209d
DW
5515 super->updates_pending++;
5516 }
28bce06f 5517
01f157d7 5518 return consistent;
a862209d
DW
5519}
5520
8d45d196 5521static void imsm_set_disk(struct active_array *a, int n, int state)
845dea95 5522{
8d45d196
DW
5523 int inst = a->info.container_member;
5524 struct intel_super *super = a->container->sb;
949c47a0 5525 struct imsm_dev *dev = get_imsm_dev(super, inst);
a965f303 5526 struct imsm_map *map = get_imsm_map(dev, 0);
8d45d196 5527 struct imsm_disk *disk;
0c046afd 5528 int failed;
b10b37b8 5529 __u32 ord;
0c046afd 5530 __u8 map_state;
8d45d196
DW
5531
5532 if (n > map->num_members)
5533 fprintf(stderr, "imsm: set_disk %d out of range 0..%d\n",
5534 n, map->num_members - 1);
5535
5536 if (n < 0)
5537 return;
5538
4e6e574a 5539 dprintf("imsm: set_disk %d:%x\n", n, state);
8d45d196 5540
98130f40 5541 ord = get_imsm_ord_tbl_ent(dev, n, -1);
b10b37b8 5542 disk = get_imsm_disk(super, ord_to_idx(ord));
8d45d196 5543
5802a811 5544 /* check for new failures */
0556e1a2
DW
5545 if (state & DS_FAULTY) {
5546 if (mark_failure(dev, disk, ord_to_idx(ord)))
5547 super->updates_pending++;
8d45d196 5548 }
47ee5a45 5549
19859edc 5550 /* check if in_sync */
0556e1a2 5551 if (state & DS_INSYNC && ord & IMSM_ORD_REBUILD && is_rebuilding(dev)) {
b10b37b8
DW
5552 struct imsm_map *migr_map = get_imsm_map(dev, 1);
5553
5554 set_imsm_ord_tbl_ent(migr_map, n, ord_to_idx(ord));
19859edc
DW
5555 super->updates_pending++;
5556 }
8d45d196 5557
0c046afd
DW
5558 failed = imsm_count_failed(super, dev);
5559 map_state = imsm_check_degraded(super, dev, failed);
5802a811 5560
0c046afd
DW
5561 /* check if recovery complete, newly degraded, or failed */
5562 if (map_state == IMSM_T_STATE_NORMAL && is_rebuilding(dev)) {
f8f603f1 5563 end_migration(dev, map_state);
0556e1a2
DW
5564 map = get_imsm_map(dev, 0);
5565 map->failed_disk_num = ~0;
0c046afd 5566 super->updates_pending++;
484240d8 5567 a->last_checkpoint = 0;
0c046afd
DW
5568 } else if (map_state == IMSM_T_STATE_DEGRADED &&
5569 map->map_state != map_state &&
5570 !dev->vol.migr_state) {
5571 dprintf("imsm: mark degraded\n");
5572 map->map_state = map_state;
5573 super->updates_pending++;
484240d8 5574 a->last_checkpoint = 0;
0c046afd
DW
5575 } else if (map_state == IMSM_T_STATE_FAILED &&
5576 map->map_state != map_state) {
5577 dprintf("imsm: mark failed\n");
f8f603f1 5578 end_migration(dev, map_state);
0c046afd 5579 super->updates_pending++;
484240d8 5580 a->last_checkpoint = 0;
28bce06f
AK
5581 } else if (is_gen_migration(dev)) {
5582 dprintf("imsm: Detected General Migration in state: ");
5583 if (map_state == IMSM_T_STATE_NORMAL) {
5584 end_migration(dev, map_state);
5585 map = get_imsm_map(dev, 0);
5586 map->failed_disk_num = ~0;
5587 dprintf("normal\n");
5588 } else {
5589 if (map_state == IMSM_T_STATE_DEGRADED) {
5590 printf("degraded\n");
5591 end_migration(dev, map_state);
5592 } else {
5593 dprintf("failed\n");
5594 }
5595 map->map_state = map_state;
5596 }
5597 super->updates_pending++;
5802a811 5598 }
845dea95
NB
5599}
5600
f796af5d 5601static int store_imsm_mpb(int fd, struct imsm_super *mpb)
c2a1e7da 5602{
f796af5d 5603 void *buf = mpb;
c2a1e7da
DW
5604 __u32 mpb_size = __le32_to_cpu(mpb->mpb_size);
5605 unsigned long long dsize;
5606 unsigned long long sectors;
5607
5608 get_dev_size(fd, NULL, &dsize);
5609
272f648f
DW
5610 if (mpb_size > 512) {
5611 /* -1 to account for anchor */
5612 sectors = mpb_sectors(mpb) - 1;
c2a1e7da 5613
272f648f
DW
5614 /* write the extended mpb to the sectors preceeding the anchor */
5615 if (lseek64(fd, dsize - (512 * (2 + sectors)), SEEK_SET) < 0)
5616 return 1;
c2a1e7da 5617
f21e18ca
N
5618 if ((unsigned long long)write(fd, buf + 512, 512 * sectors)
5619 != 512 * sectors)
272f648f
DW
5620 return 1;
5621 }
c2a1e7da 5622
272f648f
DW
5623 /* first block is stored on second to last sector of the disk */
5624 if (lseek64(fd, dsize - (512 * 2), SEEK_SET) < 0)
c2a1e7da
DW
5625 return 1;
5626
f796af5d 5627 if (write(fd, buf, 512) != 512)
c2a1e7da
DW
5628 return 1;
5629
c2a1e7da
DW
5630 return 0;
5631}
5632
2e735d19 5633static void imsm_sync_metadata(struct supertype *container)
845dea95 5634{
2e735d19 5635 struct intel_super *super = container->sb;
c2a1e7da 5636
1a64be56 5637 dprintf("sync metadata: %d\n", super->updates_pending);
c2a1e7da
DW
5638 if (!super->updates_pending)
5639 return;
5640
36988a3d 5641 write_super_imsm(container, 0);
c2a1e7da
DW
5642
5643 super->updates_pending = 0;
845dea95
NB
5644}
5645
272906ef
DW
5646static struct dl *imsm_readd(struct intel_super *super, int idx, struct active_array *a)
5647{
5648 struct imsm_dev *dev = get_imsm_dev(super, a->info.container_member);
98130f40 5649 int i = get_imsm_disk_idx(dev, idx, -1);
272906ef
DW
5650 struct dl *dl;
5651
5652 for (dl = super->disks; dl; dl = dl->next)
5653 if (dl->index == i)
5654 break;
5655
25ed7e59 5656 if (dl && is_failed(&dl->disk))
272906ef
DW
5657 dl = NULL;
5658
5659 if (dl)
5660 dprintf("%s: found %x:%x\n", __func__, dl->major, dl->minor);
5661
5662 return dl;
5663}
5664
a20d2ba5 5665static struct dl *imsm_add_spare(struct intel_super *super, int slot,
8ba77d32
AK
5666 struct active_array *a, int activate_new,
5667 struct mdinfo *additional_test_list)
272906ef
DW
5668{
5669 struct imsm_dev *dev = get_imsm_dev(super, a->info.container_member);
98130f40 5670 int idx = get_imsm_disk_idx(dev, slot, -1);
a20d2ba5
DW
5671 struct imsm_super *mpb = super->anchor;
5672 struct imsm_map *map;
272906ef
DW
5673 unsigned long long pos;
5674 struct mdinfo *d;
5675 struct extent *ex;
a20d2ba5 5676 int i, j;
272906ef 5677 int found;
569cc43f
DW
5678 __u32 array_start = 0;
5679 __u32 array_end = 0;
272906ef 5680 struct dl *dl;
6c932028 5681 struct mdinfo *test_list;
272906ef
DW
5682
5683 for (dl = super->disks; dl; dl = dl->next) {
5684 /* If in this array, skip */
5685 for (d = a->info.devs ; d ; d = d->next)
e553d2a4
DW
5686 if (d->state_fd >= 0 &&
5687 d->disk.major == dl->major &&
272906ef 5688 d->disk.minor == dl->minor) {
8ba77d32
AK
5689 dprintf("%x:%x already in array\n",
5690 dl->major, dl->minor);
272906ef
DW
5691 break;
5692 }
5693 if (d)
5694 continue;
6c932028
AK
5695 test_list = additional_test_list;
5696 while (test_list) {
5697 if (test_list->disk.major == dl->major &&
5698 test_list->disk.minor == dl->minor) {
8ba77d32
AK
5699 dprintf("%x:%x already in additional test list\n",
5700 dl->major, dl->minor);
5701 break;
5702 }
6c932028 5703 test_list = test_list->next;
8ba77d32 5704 }
6c932028 5705 if (test_list)
8ba77d32 5706 continue;
272906ef 5707
e553d2a4 5708 /* skip in use or failed drives */
25ed7e59 5709 if (is_failed(&dl->disk) || idx == dl->index ||
df474657
DW
5710 dl->index == -2) {
5711 dprintf("%x:%x status (failed: %d index: %d)\n",
25ed7e59 5712 dl->major, dl->minor, is_failed(&dl->disk), idx);
9a1608e5
DW
5713 continue;
5714 }
5715
a20d2ba5
DW
5716 /* skip pure spares when we are looking for partially
5717 * assimilated drives
5718 */
5719 if (dl->index == -1 && !activate_new)
5720 continue;
5721
272906ef 5722 /* Does this unused device have the requisite free space?
a20d2ba5 5723 * It needs to be able to cover all member volumes
272906ef
DW
5724 */
5725 ex = get_extents(super, dl);
5726 if (!ex) {
5727 dprintf("cannot get extents\n");
5728 continue;
5729 }
a20d2ba5
DW
5730 for (i = 0; i < mpb->num_raid_devs; i++) {
5731 dev = get_imsm_dev(super, i);
5732 map = get_imsm_map(dev, 0);
272906ef 5733
a20d2ba5
DW
5734 /* check if this disk is already a member of
5735 * this array
272906ef 5736 */
620b1713 5737 if (get_imsm_disk_slot(map, dl->index) >= 0)
a20d2ba5
DW
5738 continue;
5739
5740 found = 0;
5741 j = 0;
5742 pos = 0;
5743 array_start = __le32_to_cpu(map->pba_of_lba0);
329c8278
DW
5744 array_end = array_start +
5745 __le32_to_cpu(map->blocks_per_member) - 1;
a20d2ba5
DW
5746
5747 do {
5748 /* check that we can start at pba_of_lba0 with
5749 * blocks_per_member of space
5750 */
329c8278 5751 if (array_start >= pos && array_end < ex[j].start) {
a20d2ba5
DW
5752 found = 1;
5753 break;
5754 }
5755 pos = ex[j].start + ex[j].size;
5756 j++;
5757 } while (ex[j-1].size);
5758
5759 if (!found)
272906ef 5760 break;
a20d2ba5 5761 }
272906ef
DW
5762
5763 free(ex);
a20d2ba5 5764 if (i < mpb->num_raid_devs) {
329c8278
DW
5765 dprintf("%x:%x does not have %u to %u available\n",
5766 dl->major, dl->minor, array_start, array_end);
272906ef
DW
5767 /* No room */
5768 continue;
a20d2ba5
DW
5769 }
5770 return dl;
272906ef
DW
5771 }
5772
5773 return dl;
5774}
5775
95d07a2c
LM
5776
5777static int imsm_rebuild_allowed(struct supertype *cont, int dev_idx, int failed)
5778{
5779 struct imsm_dev *dev2;
5780 struct imsm_map *map;
5781 struct dl *idisk;
5782 int slot;
5783 int idx;
5784 __u8 state;
5785
5786 dev2 = get_imsm_dev(cont->sb, dev_idx);
5787 if (dev2) {
5788 state = imsm_check_degraded(cont->sb, dev2, failed);
5789 if (state == IMSM_T_STATE_FAILED) {
5790 map = get_imsm_map(dev2, 0);
5791 if (!map)
5792 return 1;
5793 for (slot = 0; slot < map->num_members; slot++) {
5794 /*
5795 * Check if failed disks are deleted from intel
5796 * disk list or are marked to be deleted
5797 */
98130f40 5798 idx = get_imsm_disk_idx(dev2, slot, -1);
95d07a2c
LM
5799 idisk = get_imsm_dl_disk(cont->sb, idx);
5800 /*
5801 * Do not rebuild the array if failed disks
5802 * from failed sub-array are not removed from
5803 * container.
5804 */
5805 if (idisk &&
5806 is_failed(&idisk->disk) &&
5807 (idisk->action != DISK_REMOVE))
5808 return 0;
5809 }
5810 }
5811 }
5812 return 1;
5813}
5814
88758e9d
DW
5815static struct mdinfo *imsm_activate_spare(struct active_array *a,
5816 struct metadata_update **updates)
5817{
5818 /**
d23fe947
DW
5819 * Find a device with unused free space and use it to replace a
5820 * failed/vacant region in an array. We replace failed regions one a
5821 * array at a time. The result is that a new spare disk will be added
5822 * to the first failed array and after the monitor has finished
5823 * propagating failures the remainder will be consumed.
88758e9d 5824 *
d23fe947
DW
5825 * FIXME add a capability for mdmon to request spares from another
5826 * container.
88758e9d
DW
5827 */
5828
5829 struct intel_super *super = a->container->sb;
88758e9d 5830 int inst = a->info.container_member;
949c47a0 5831 struct imsm_dev *dev = get_imsm_dev(super, inst);
a965f303 5832 struct imsm_map *map = get_imsm_map(dev, 0);
88758e9d
DW
5833 int failed = a->info.array.raid_disks;
5834 struct mdinfo *rv = NULL;
5835 struct mdinfo *d;
5836 struct mdinfo *di;
5837 struct metadata_update *mu;
5838 struct dl *dl;
5839 struct imsm_update_activate_spare *u;
5840 int num_spares = 0;
5841 int i;
95d07a2c 5842 int allowed;
88758e9d
DW
5843
5844 for (d = a->info.devs ; d ; d = d->next) {
5845 if ((d->curr_state & DS_FAULTY) &&
5846 d->state_fd >= 0)
5847 /* wait for Removal to happen */
5848 return NULL;
5849 if (d->state_fd >= 0)
5850 failed--;
5851 }
5852
5853 dprintf("imsm: activate spare: inst=%d failed=%d (%d) level=%d\n",
5854 inst, failed, a->info.array.raid_disks, a->info.array.level);
1af97990
AK
5855
5856 if (dev->vol.migr_state &&
5857 dev->vol.migr_type == MIGR_GEN_MIGR)
5858 /* No repair during migration */
5859 return NULL;
5860
89c67882
AK
5861 if (a->info.array.level == 4)
5862 /* No repair for takeovered array
5863 * imsm doesn't support raid4
5864 */
5865 return NULL;
5866
fb49eef2 5867 if (imsm_check_degraded(super, dev, failed) != IMSM_T_STATE_DEGRADED)
88758e9d
DW
5868 return NULL;
5869
95d07a2c
LM
5870 /*
5871 * If there are any failed disks check state of the other volume.
5872 * Block rebuild if the another one is failed until failed disks
5873 * are removed from container.
5874 */
5875 if (failed) {
5876 dprintf("found failed disks in %s, check if there another"
5877 "failed sub-array.\n",
5878 dev->volume);
5879 /* check if states of the other volumes allow for rebuild */
5880 for (i = 0; i < super->anchor->num_raid_devs; i++) {
5881 if (i != inst) {
5882 allowed = imsm_rebuild_allowed(a->container,
5883 i, failed);
5884 if (!allowed)
5885 return NULL;
5886 }
5887 }
5888 }
5889
88758e9d 5890 /* For each slot, if it is not working, find a spare */
88758e9d
DW
5891 for (i = 0; i < a->info.array.raid_disks; i++) {
5892 for (d = a->info.devs ; d ; d = d->next)
5893 if (d->disk.raid_disk == i)
5894 break;
5895 dprintf("found %d: %p %x\n", i, d, d?d->curr_state:0);
5896 if (d && (d->state_fd >= 0))
5897 continue;
5898
272906ef 5899 /*
a20d2ba5
DW
5900 * OK, this device needs recovery. Try to re-add the
5901 * previous occupant of this slot, if this fails see if
5902 * we can continue the assimilation of a spare that was
5903 * partially assimilated, finally try to activate a new
5904 * spare.
272906ef
DW
5905 */
5906 dl = imsm_readd(super, i, a);
5907 if (!dl)
8ba77d32 5908 dl = imsm_add_spare(super, i, a, 0, NULL);
a20d2ba5 5909 if (!dl)
8ba77d32 5910 dl = imsm_add_spare(super, i, a, 1, NULL);
272906ef
DW
5911 if (!dl)
5912 continue;
5913
5914 /* found a usable disk with enough space */
5915 di = malloc(sizeof(*di));
79244939
DW
5916 if (!di)
5917 continue;
272906ef
DW
5918 memset(di, 0, sizeof(*di));
5919
5920 /* dl->index will be -1 in the case we are activating a
5921 * pristine spare. imsm_process_update() will create a
5922 * new index in this case. Once a disk is found to be
5923 * failed in all member arrays it is kicked from the
5924 * metadata
5925 */
5926 di->disk.number = dl->index;
d23fe947 5927
272906ef
DW
5928 /* (ab)use di->devs to store a pointer to the device
5929 * we chose
5930 */
5931 di->devs = (struct mdinfo *) dl;
5932
5933 di->disk.raid_disk = i;
5934 di->disk.major = dl->major;
5935 di->disk.minor = dl->minor;
5936 di->disk.state = 0;
d23534e4 5937 di->recovery_start = 0;
272906ef
DW
5938 di->data_offset = __le32_to_cpu(map->pba_of_lba0);
5939 di->component_size = a->info.component_size;
5940 di->container_member = inst;
148acb7b 5941 super->random = random32();
272906ef
DW
5942 di->next = rv;
5943 rv = di;
5944 num_spares++;
5945 dprintf("%x:%x to be %d at %llu\n", dl->major, dl->minor,
5946 i, di->data_offset);
88758e9d 5947
272906ef 5948 break;
88758e9d
DW
5949 }
5950
5951 if (!rv)
5952 /* No spares found */
5953 return rv;
5954 /* Now 'rv' has a list of devices to return.
5955 * Create a metadata_update record to update the
5956 * disk_ord_tbl for the array
5957 */
5958 mu = malloc(sizeof(*mu));
79244939
DW
5959 if (mu) {
5960 mu->buf = malloc(sizeof(struct imsm_update_activate_spare) * num_spares);
5961 if (mu->buf == NULL) {
5962 free(mu);
5963 mu = NULL;
5964 }
5965 }
5966 if (!mu) {
5967 while (rv) {
5968 struct mdinfo *n = rv->next;
5969
5970 free(rv);
5971 rv = n;
5972 }
5973 return NULL;
5974 }
5975
88758e9d 5976 mu->space = NULL;
cb23f1f4 5977 mu->space_list = NULL;
88758e9d
DW
5978 mu->len = sizeof(struct imsm_update_activate_spare) * num_spares;
5979 mu->next = *updates;
5980 u = (struct imsm_update_activate_spare *) mu->buf;
5981
5982 for (di = rv ; di ; di = di->next) {
5983 u->type = update_activate_spare;
d23fe947
DW
5984 u->dl = (struct dl *) di->devs;
5985 di->devs = NULL;
88758e9d
DW
5986 u->slot = di->disk.raid_disk;
5987 u->array = inst;
5988 u->next = u + 1;
5989 u++;
5990 }
5991 (u-1)->next = NULL;
5992 *updates = mu;
5993
5994 return rv;
5995}
5996
54c2c1ea 5997static int disks_overlap(struct intel_super *super, int idx, struct imsm_update_create_array *u)
8273f55e 5998{
54c2c1ea
DW
5999 struct imsm_dev *dev = get_imsm_dev(super, idx);
6000 struct imsm_map *map = get_imsm_map(dev, 0);
6001 struct imsm_map *new_map = get_imsm_map(&u->dev, 0);
6002 struct disk_info *inf = get_disk_info(u);
6003 struct imsm_disk *disk;
8273f55e
DW
6004 int i;
6005 int j;
8273f55e 6006
54c2c1ea 6007 for (i = 0; i < map->num_members; i++) {
98130f40 6008 disk = get_imsm_disk(super, get_imsm_disk_idx(dev, i, -1));
54c2c1ea
DW
6009 for (j = 0; j < new_map->num_members; j++)
6010 if (serialcmp(disk->serial, inf[j].serial) == 0)
8273f55e
DW
6011 return 1;
6012 }
6013
6014 return 0;
6015}
6016
1a64be56
LM
6017
6018static struct dl *get_disk_super(struct intel_super *super, int major, int minor)
6019{
6020 struct dl *dl = NULL;
6021 for (dl = super->disks; dl; dl = dl->next)
6022 if ((dl->major == major) && (dl->minor == minor))
6023 return dl;
6024 return NULL;
6025}
6026
6027static int remove_disk_super(struct intel_super *super, int major, int minor)
6028{
6029 struct dl *prev = NULL;
6030 struct dl *dl;
6031
6032 prev = NULL;
6033 for (dl = super->disks; dl; dl = dl->next) {
6034 if ((dl->major == major) && (dl->minor == minor)) {
6035 /* remove */
6036 if (prev)
6037 prev->next = dl->next;
6038 else
6039 super->disks = dl->next;
6040 dl->next = NULL;
6041 __free_imsm_disk(dl);
6042 dprintf("%s: removed %x:%x\n",
6043 __func__, major, minor);
6044 break;
6045 }
6046 prev = dl;
6047 }
6048 return 0;
6049}
6050
f21e18ca 6051static void imsm_delete(struct intel_super *super, struct dl **dlp, unsigned index);
ae6aad82 6052
1a64be56
LM
6053static int add_remove_disk_update(struct intel_super *super)
6054{
6055 int check_degraded = 0;
6056 struct dl *disk = NULL;
6057 /* add/remove some spares to/from the metadata/contrainer */
6058 while (super->disk_mgmt_list) {
6059 struct dl *disk_cfg;
6060
6061 disk_cfg = super->disk_mgmt_list;
6062 super->disk_mgmt_list = disk_cfg->next;
6063 disk_cfg->next = NULL;
6064
6065 if (disk_cfg->action == DISK_ADD) {
6066 disk_cfg->next = super->disks;
6067 super->disks = disk_cfg;
6068 check_degraded = 1;
6069 dprintf("%s: added %x:%x\n",
6070 __func__, disk_cfg->major,
6071 disk_cfg->minor);
6072 } else if (disk_cfg->action == DISK_REMOVE) {
6073 dprintf("Disk remove action processed: %x.%x\n",
6074 disk_cfg->major, disk_cfg->minor);
6075 disk = get_disk_super(super,
6076 disk_cfg->major,
6077 disk_cfg->minor);
6078 if (disk) {
6079 /* store action status */
6080 disk->action = DISK_REMOVE;
6081 /* remove spare disks only */
6082 if (disk->index == -1) {
6083 remove_disk_super(super,
6084 disk_cfg->major,
6085 disk_cfg->minor);
6086 }
6087 }
6088 /* release allocate disk structure */
6089 __free_imsm_disk(disk_cfg);
6090 }
6091 }
6092 return check_degraded;
6093}
6094
a29911da
PC
6095
6096static int apply_reshape_migration_update(struct imsm_update_reshape_migration *u,
6097 struct intel_super *super,
6098 void ***space_list)
6099{
6100 struct intel_dev *id;
6101 void **tofree = NULL;
6102 int ret_val = 0;
6103
6104 dprintf("apply_reshape_migration_update()\n");
6105 if ((u->subdev < 0) ||
6106 (u->subdev > 1)) {
6107 dprintf("imsm: Error: Wrong subdev: %i\n", u->subdev);
6108 return ret_val;
6109 }
6110 if ((space_list == NULL) || (*space_list == NULL)) {
6111 dprintf("imsm: Error: Memory is not allocated\n");
6112 return ret_val;
6113 }
6114
6115 for (id = super->devlist ; id; id = id->next) {
6116 if (id->index == (unsigned)u->subdev) {
6117 struct imsm_dev *dev = get_imsm_dev(super, u->subdev);
6118 struct imsm_map *map;
6119 struct imsm_dev *new_dev =
6120 (struct imsm_dev *)*space_list;
6121 struct imsm_map *migr_map = get_imsm_map(dev, 1);
6122 int to_state;
6123 struct dl *new_disk;
6124
6125 if (new_dev == NULL)
6126 return ret_val;
6127 *space_list = **space_list;
6128 memcpy(new_dev, dev, sizeof_imsm_dev(dev, 0));
6129 map = get_imsm_map(new_dev, 0);
6130 if (migr_map) {
6131 dprintf("imsm: Error: migration in progress");
6132 return ret_val;
6133 }
6134
6135 to_state = map->map_state;
6136 if ((u->new_level == 5) && (map->raid_level == 0)) {
6137 map->num_members++;
6138 /* this should not happen */
6139 if (u->new_disks[0] < 0) {
6140 map->failed_disk_num =
6141 map->num_members - 1;
6142 to_state = IMSM_T_STATE_DEGRADED;
6143 } else
6144 to_state = IMSM_T_STATE_NORMAL;
6145 }
6146 migrate(new_dev, to_state, MIGR_GEN_MIGR);
6147 if (u->new_level > -1)
6148 map->raid_level = u->new_level;
6149 migr_map = get_imsm_map(new_dev, 1);
6150 if ((u->new_level == 5) &&
6151 (migr_map->raid_level == 0)) {
6152 int ord = map->num_members - 1;
6153 migr_map->num_members--;
6154 if (u->new_disks[0] < 0)
6155 ord |= IMSM_ORD_REBUILD;
6156 set_imsm_ord_tbl_ent(map,
6157 map->num_members - 1,
6158 ord);
6159 }
6160 id->dev = new_dev;
6161 tofree = (void **)dev;
6162
4bba0439
PC
6163 /* update chunk size
6164 */
6165 if (u->new_chunksize > 0)
6166 map->blocks_per_strip =
6167 __cpu_to_le16(u->new_chunksize * 2);
6168
a29911da
PC
6169 /* add disk
6170 */
6171 if ((u->new_level != 5) ||
6172 (migr_map->raid_level != 0) ||
6173 (migr_map->raid_level == map->raid_level))
6174 goto skip_disk_add;
6175
6176 if (u->new_disks[0] >= 0) {
6177 /* use passes spare
6178 */
6179 new_disk = get_disk_super(super,
6180 major(u->new_disks[0]),
6181 minor(u->new_disks[0]));
6182 dprintf("imsm: new disk for reshape is: %i:%i "
6183 "(%p, index = %i)\n",
6184 major(u->new_disks[0]),
6185 minor(u->new_disks[0]),
6186 new_disk, new_disk->index);
6187 if (new_disk == NULL)
6188 goto error_disk_add;
6189
6190 new_disk->index = map->num_members - 1;
6191 /* slot to fill in autolayout
6192 */
6193 new_disk->raiddisk = new_disk->index;
6194 new_disk->disk.status |= CONFIGURED_DISK;
6195 new_disk->disk.status &= ~SPARE_DISK;
6196 } else
6197 goto error_disk_add;
6198
6199skip_disk_add:
6200 *tofree = *space_list;
6201 /* calculate new size
6202 */
6203 imsm_set_array_size(new_dev);
6204
6205 ret_val = 1;
6206 }
6207 }
6208
6209 if (tofree)
6210 *space_list = tofree;
6211 return ret_val;
6212
6213error_disk_add:
6214 dprintf("Error: imsm: Cannot find disk.\n");
6215 return ret_val;
6216}
6217
6218
2e5dc010
N
6219static int apply_reshape_container_disks_update(struct imsm_update_reshape *u,
6220 struct intel_super *super,
6221 void ***space_list)
6222{
6223 struct dl *new_disk;
6224 struct intel_dev *id;
6225 int i;
6226 int delta_disks = u->new_raid_disks - u->old_raid_disks;
ee4beede 6227 int disk_count = u->old_raid_disks;
2e5dc010
N
6228 void **tofree = NULL;
6229 int devices_to_reshape = 1;
6230 struct imsm_super *mpb = super->anchor;
6231 int ret_val = 0;
d098291a 6232 unsigned int dev_id;
2e5dc010 6233
ed7333bd 6234 dprintf("imsm: apply_reshape_container_disks_update()\n");
2e5dc010
N
6235
6236 /* enable spares to use in array */
6237 for (i = 0; i < delta_disks; i++) {
6238 new_disk = get_disk_super(super,
6239 major(u->new_disks[i]),
6240 minor(u->new_disks[i]));
ed7333bd
AK
6241 dprintf("imsm: new disk for reshape is: %i:%i "
6242 "(%p, index = %i)\n",
2e5dc010
N
6243 major(u->new_disks[i]), minor(u->new_disks[i]),
6244 new_disk, new_disk->index);
6245 if ((new_disk == NULL) ||
6246 ((new_disk->index >= 0) &&
6247 (new_disk->index < u->old_raid_disks)))
6248 goto update_reshape_exit;
ee4beede 6249 new_disk->index = disk_count++;
2e5dc010
N
6250 /* slot to fill in autolayout
6251 */
6252 new_disk->raiddisk = new_disk->index;
6253 new_disk->disk.status |=
6254 CONFIGURED_DISK;
6255 new_disk->disk.status &= ~SPARE_DISK;
6256 }
6257
ed7333bd
AK
6258 dprintf("imsm: volume set mpb->num_raid_devs = %i\n",
6259 mpb->num_raid_devs);
2e5dc010
N
6260 /* manage changes in volume
6261 */
d098291a 6262 for (dev_id = 0; dev_id < mpb->num_raid_devs; dev_id++) {
2e5dc010
N
6263 void **sp = *space_list;
6264 struct imsm_dev *newdev;
6265 struct imsm_map *newmap, *oldmap;
6266
d098291a
AK
6267 for (id = super->devlist ; id; id = id->next) {
6268 if (id->index == dev_id)
6269 break;
6270 }
6271 if (id == NULL)
6272 break;
2e5dc010
N
6273 if (!sp)
6274 continue;
6275 *space_list = *sp;
6276 newdev = (void*)sp;
6277 /* Copy the dev, but not (all of) the map */
6278 memcpy(newdev, id->dev, sizeof(*newdev));
6279 oldmap = get_imsm_map(id->dev, 0);
6280 newmap = get_imsm_map(newdev, 0);
6281 /* Copy the current map */
6282 memcpy(newmap, oldmap, sizeof_imsm_map(oldmap));
6283 /* update one device only
6284 */
6285 if (devices_to_reshape) {
ed7333bd
AK
6286 dprintf("imsm: modifying subdev: %i\n",
6287 id->index);
2e5dc010
N
6288 devices_to_reshape--;
6289 newdev->vol.migr_state = 1;
6290 newdev->vol.curr_migr_unit = 0;
6291 newdev->vol.migr_type = MIGR_GEN_MIGR;
6292 newmap->num_members = u->new_raid_disks;
6293 for (i = 0; i < delta_disks; i++) {
6294 set_imsm_ord_tbl_ent(newmap,
6295 u->old_raid_disks + i,
6296 u->old_raid_disks + i);
6297 }
6298 /* New map is correct, now need to save old map
6299 */
6300 newmap = get_imsm_map(newdev, 1);
6301 memcpy(newmap, oldmap, sizeof_imsm_map(oldmap));
6302
70bdf0dc 6303 imsm_set_array_size(newdev);
2e5dc010
N
6304 }
6305
6306 sp = (void **)id->dev;
6307 id->dev = newdev;
6308 *sp = tofree;
6309 tofree = sp;
6310 }
819bc634
AK
6311 if (tofree)
6312 *space_list = tofree;
2e5dc010
N
6313 ret_val = 1;
6314
6315update_reshape_exit:
6316
6317 return ret_val;
6318}
6319
bb025c2f 6320static int apply_takeover_update(struct imsm_update_takeover *u,
8ca6df95
KW
6321 struct intel_super *super,
6322 void ***space_list)
bb025c2f
KW
6323{
6324 struct imsm_dev *dev = NULL;
8ca6df95
KW
6325 struct intel_dev *dv;
6326 struct imsm_dev *dev_new;
bb025c2f
KW
6327 struct imsm_map *map;
6328 struct dl *dm, *du;
8ca6df95 6329 int i;
bb025c2f
KW
6330
6331 for (dv = super->devlist; dv; dv = dv->next)
6332 if (dv->index == (unsigned int)u->subarray) {
6333 dev = dv->dev;
6334 break;
6335 }
6336
6337 if (dev == NULL)
6338 return 0;
6339
6340 map = get_imsm_map(dev, 0);
6341
6342 if (u->direction == R10_TO_R0) {
43d5ec18
KW
6343 /* Number of failed disks must be half of initial disk number */
6344 if (imsm_count_failed(super, dev) != (map->num_members / 2))
6345 return 0;
6346
bb025c2f
KW
6347 /* iterate through devices to mark removed disks as spare */
6348 for (dm = super->disks; dm; dm = dm->next) {
6349 if (dm->disk.status & FAILED_DISK) {
6350 int idx = dm->index;
6351 /* update indexes on the disk list */
6352/* FIXME this loop-with-the-loop looks wrong, I'm not convinced
6353 the index values will end up being correct.... NB */
6354 for (du = super->disks; du; du = du->next)
6355 if (du->index > idx)
6356 du->index--;
6357 /* mark as spare disk */
6358 dm->disk.status = SPARE_DISK;
6359 dm->index = -1;
6360 }
6361 }
bb025c2f
KW
6362 /* update map */
6363 map->num_members = map->num_members / 2;
6364 map->map_state = IMSM_T_STATE_NORMAL;
6365 map->num_domains = 1;
6366 map->raid_level = 0;
6367 map->failed_disk_num = -1;
6368 }
6369
8ca6df95
KW
6370 if (u->direction == R0_TO_R10) {
6371 void **space;
6372 /* update slots in current disk list */
6373 for (dm = super->disks; dm; dm = dm->next) {
6374 if (dm->index >= 0)
6375 dm->index *= 2;
6376 }
6377 /* create new *missing* disks */
6378 for (i = 0; i < map->num_members; i++) {
6379 space = *space_list;
6380 if (!space)
6381 continue;
6382 *space_list = *space;
6383 du = (void *)space;
6384 memcpy(du, super->disks, sizeof(*du));
8ca6df95
KW
6385 du->fd = -1;
6386 du->minor = 0;
6387 du->major = 0;
6388 du->index = (i * 2) + 1;
6389 sprintf((char *)du->disk.serial,
6390 " MISSING_%d", du->index);
6391 sprintf((char *)du->serial,
6392 "MISSING_%d", du->index);
6393 du->next = super->missing;
6394 super->missing = du;
6395 }
6396 /* create new dev and map */
6397 space = *space_list;
6398 if (!space)
6399 return 0;
6400 *space_list = *space;
6401 dev_new = (void *)space;
6402 memcpy(dev_new, dev, sizeof(*dev));
6403 /* update new map */
6404 map = get_imsm_map(dev_new, 0);
8ca6df95 6405 map->num_members = map->num_members * 2;
1a2487c2 6406 map->map_state = IMSM_T_STATE_DEGRADED;
8ca6df95
KW
6407 map->num_domains = 2;
6408 map->raid_level = 1;
6409 /* replace dev<->dev_new */
6410 dv->dev = dev_new;
6411 }
bb025c2f
KW
6412 /* update disk order table */
6413 for (du = super->disks; du; du = du->next)
6414 if (du->index >= 0)
6415 set_imsm_ord_tbl_ent(map, du->index, du->index);
8ca6df95 6416 for (du = super->missing; du; du = du->next)
1a2487c2
KW
6417 if (du->index >= 0) {
6418 set_imsm_ord_tbl_ent(map, du->index, du->index);
6419 mark_missing(dev_new, &du->disk, du->index);
6420 }
bb025c2f
KW
6421
6422 return 1;
6423}
6424
e8319a19
DW
6425static void imsm_process_update(struct supertype *st,
6426 struct metadata_update *update)
6427{
6428 /**
6429 * crack open the metadata_update envelope to find the update record
6430 * update can be one of:
d195167d
AK
6431 * update_reshape_container_disks - all the arrays in the container
6432 * are being reshaped to have more devices. We need to mark
6433 * the arrays for general migration and convert selected spares
6434 * into active devices.
6435 * update_activate_spare - a spare device has replaced a failed
e8319a19
DW
6436 * device in an array, update the disk_ord_tbl. If this disk is
6437 * present in all member arrays then also clear the SPARE_DISK
6438 * flag
d195167d
AK
6439 * update_create_array
6440 * update_kill_array
6441 * update_rename_array
6442 * update_add_remove_disk
e8319a19
DW
6443 */
6444 struct intel_super *super = st->sb;
4d7b1503 6445 struct imsm_super *mpb;
e8319a19
DW
6446 enum imsm_update_type type = *(enum imsm_update_type *) update->buf;
6447
4d7b1503
DW
6448 /* update requires a larger buf but the allocation failed */
6449 if (super->next_len && !super->next_buf) {
6450 super->next_len = 0;
6451 return;
6452 }
6453
6454 if (super->next_buf) {
6455 memcpy(super->next_buf, super->buf, super->len);
6456 free(super->buf);
6457 super->len = super->next_len;
6458 super->buf = super->next_buf;
6459
6460 super->next_len = 0;
6461 super->next_buf = NULL;
6462 }
6463
6464 mpb = super->anchor;
6465
e8319a19 6466 switch (type) {
bb025c2f
KW
6467 case update_takeover: {
6468 struct imsm_update_takeover *u = (void *)update->buf;
1a2487c2
KW
6469 if (apply_takeover_update(u, super, &update->space_list)) {
6470 imsm_update_version_info(super);
bb025c2f 6471 super->updates_pending++;
1a2487c2 6472 }
bb025c2f
KW
6473 break;
6474 }
6475
78b10e66 6476 case update_reshape_container_disks: {
d195167d 6477 struct imsm_update_reshape *u = (void *)update->buf;
2e5dc010
N
6478 if (apply_reshape_container_disks_update(
6479 u, super, &update->space_list))
6480 super->updates_pending++;
78b10e66
N
6481 break;
6482 }
48c5303a 6483 case update_reshape_migration: {
a29911da
PC
6484 struct imsm_update_reshape_migration *u = (void *)update->buf;
6485 if (apply_reshape_migration_update(
6486 u, super, &update->space_list))
6487 super->updates_pending++;
48c5303a
PC
6488 break;
6489 }
e8319a19
DW
6490 case update_activate_spare: {
6491 struct imsm_update_activate_spare *u = (void *) update->buf;
949c47a0 6492 struct imsm_dev *dev = get_imsm_dev(super, u->array);
a965f303 6493 struct imsm_map *map = get_imsm_map(dev, 0);
0c046afd 6494 struct imsm_map *migr_map;
e8319a19
DW
6495 struct active_array *a;
6496 struct imsm_disk *disk;
0c046afd 6497 __u8 to_state;
e8319a19 6498 struct dl *dl;
e8319a19 6499 unsigned int found;
0c046afd 6500 int failed;
98130f40 6501 int victim = get_imsm_disk_idx(dev, u->slot, -1);
e8319a19
DW
6502 int i;
6503
6504 for (dl = super->disks; dl; dl = dl->next)
d23fe947 6505 if (dl == u->dl)
e8319a19
DW
6506 break;
6507
6508 if (!dl) {
6509 fprintf(stderr, "error: imsm_activate_spare passed "
1f24f035
DW
6510 "an unknown disk (index: %d)\n",
6511 u->dl->index);
e8319a19
DW
6512 return;
6513 }
6514
6515 super->updates_pending++;
0c046afd
DW
6516 /* count failures (excluding rebuilds and the victim)
6517 * to determine map[0] state
6518 */
6519 failed = 0;
6520 for (i = 0; i < map->num_members; i++) {
6521 if (i == u->slot)
6522 continue;
98130f40
AK
6523 disk = get_imsm_disk(super,
6524 get_imsm_disk_idx(dev, i, -1));
25ed7e59 6525 if (!disk || is_failed(disk))
0c046afd
DW
6526 failed++;
6527 }
6528
d23fe947
DW
6529 /* adding a pristine spare, assign a new index */
6530 if (dl->index < 0) {
6531 dl->index = super->anchor->num_disks;
6532 super->anchor->num_disks++;
6533 }
d23fe947 6534 disk = &dl->disk;
f2f27e63
DW
6535 disk->status |= CONFIGURED_DISK;
6536 disk->status &= ~SPARE_DISK;
e8319a19 6537
0c046afd
DW
6538 /* mark rebuild */
6539 to_state = imsm_check_degraded(super, dev, failed);
6540 map->map_state = IMSM_T_STATE_DEGRADED;
e3bba0e0 6541 migrate(dev, to_state, MIGR_REBUILD);
0c046afd
DW
6542 migr_map = get_imsm_map(dev, 1);
6543 set_imsm_ord_tbl_ent(map, u->slot, dl->index);
6544 set_imsm_ord_tbl_ent(migr_map, u->slot, dl->index | IMSM_ORD_REBUILD);
6545
148acb7b
DW
6546 /* update the family_num to mark a new container
6547 * generation, being careful to record the existing
6548 * family_num in orig_family_num to clean up after
6549 * earlier mdadm versions that neglected to set it.
6550 */
6551 if (mpb->orig_family_num == 0)
6552 mpb->orig_family_num = mpb->family_num;
6553 mpb->family_num += super->random;
6554
e8319a19
DW
6555 /* count arrays using the victim in the metadata */
6556 found = 0;
6557 for (a = st->arrays; a ; a = a->next) {
949c47a0 6558 dev = get_imsm_dev(super, a->info.container_member);
620b1713
DW
6559 map = get_imsm_map(dev, 0);
6560
6561 if (get_imsm_disk_slot(map, victim) >= 0)
6562 found++;
e8319a19
DW
6563 }
6564
24565c9a 6565 /* delete the victim if it is no longer being
e8319a19
DW
6566 * utilized anywhere
6567 */
e8319a19 6568 if (!found) {
ae6aad82 6569 struct dl **dlp;
24565c9a 6570
47ee5a45
DW
6571 /* We know that 'manager' isn't touching anything,
6572 * so it is safe to delete
6573 */
24565c9a 6574 for (dlp = &super->disks; *dlp; dlp = &(*dlp)->next)
ae6aad82
DW
6575 if ((*dlp)->index == victim)
6576 break;
47ee5a45
DW
6577
6578 /* victim may be on the missing list */
6579 if (!*dlp)
6580 for (dlp = &super->missing; *dlp; dlp = &(*dlp)->next)
6581 if ((*dlp)->index == victim)
6582 break;
24565c9a 6583 imsm_delete(super, dlp, victim);
e8319a19 6584 }
8273f55e
DW
6585 break;
6586 }
6587 case update_create_array: {
6588 /* someone wants to create a new array, we need to be aware of
6589 * a few races/collisions:
6590 * 1/ 'Create' called by two separate instances of mdadm
6591 * 2/ 'Create' versus 'activate_spare': mdadm has chosen
6592 * devices that have since been assimilated via
6593 * activate_spare.
6594 * In the event this update can not be carried out mdadm will
6595 * (FIX ME) notice that its update did not take hold.
6596 */
6597 struct imsm_update_create_array *u = (void *) update->buf;
ba2de7ba 6598 struct intel_dev *dv;
8273f55e
DW
6599 struct imsm_dev *dev;
6600 struct imsm_map *map, *new_map;
6601 unsigned long long start, end;
6602 unsigned long long new_start, new_end;
6603 int i;
54c2c1ea
DW
6604 struct disk_info *inf;
6605 struct dl *dl;
8273f55e
DW
6606
6607 /* handle racing creates: first come first serve */
6608 if (u->dev_idx < mpb->num_raid_devs) {
6609 dprintf("%s: subarray %d already defined\n",
6610 __func__, u->dev_idx);
ba2de7ba 6611 goto create_error;
8273f55e
DW
6612 }
6613
6614 /* check update is next in sequence */
6615 if (u->dev_idx != mpb->num_raid_devs) {
6a3e913e
DW
6616 dprintf("%s: can not create array %d expected index %d\n",
6617 __func__, u->dev_idx, mpb->num_raid_devs);
ba2de7ba 6618 goto create_error;
8273f55e
DW
6619 }
6620
a965f303 6621 new_map = get_imsm_map(&u->dev, 0);
8273f55e
DW
6622 new_start = __le32_to_cpu(new_map->pba_of_lba0);
6623 new_end = new_start + __le32_to_cpu(new_map->blocks_per_member);
54c2c1ea 6624 inf = get_disk_info(u);
8273f55e
DW
6625
6626 /* handle activate_spare versus create race:
6627 * check to make sure that overlapping arrays do not include
6628 * overalpping disks
6629 */
6630 for (i = 0; i < mpb->num_raid_devs; i++) {
949c47a0 6631 dev = get_imsm_dev(super, i);
a965f303 6632 map = get_imsm_map(dev, 0);
8273f55e
DW
6633 start = __le32_to_cpu(map->pba_of_lba0);
6634 end = start + __le32_to_cpu(map->blocks_per_member);
6635 if ((new_start >= start && new_start <= end) ||
6636 (start >= new_start && start <= new_end))
54c2c1ea
DW
6637 /* overlap */;
6638 else
6639 continue;
6640
6641 if (disks_overlap(super, i, u)) {
8273f55e 6642 dprintf("%s: arrays overlap\n", __func__);
ba2de7ba 6643 goto create_error;
8273f55e
DW
6644 }
6645 }
8273f55e 6646
949c47a0
DW
6647 /* check that prepare update was successful */
6648 if (!update->space) {
6649 dprintf("%s: prepare update failed\n", __func__);
ba2de7ba 6650 goto create_error;
949c47a0
DW
6651 }
6652
54c2c1ea
DW
6653 /* check that all disks are still active before committing
6654 * changes. FIXME: could we instead handle this by creating a
6655 * degraded array? That's probably not what the user expects,
6656 * so better to drop this update on the floor.
6657 */
6658 for (i = 0; i < new_map->num_members; i++) {
6659 dl = serial_to_dl(inf[i].serial, super);
6660 if (!dl) {
6661 dprintf("%s: disk disappeared\n", __func__);
ba2de7ba 6662 goto create_error;
54c2c1ea 6663 }
949c47a0
DW
6664 }
6665
8273f55e 6666 super->updates_pending++;
54c2c1ea
DW
6667
6668 /* convert spares to members and fixup ord_tbl */
6669 for (i = 0; i < new_map->num_members; i++) {
6670 dl = serial_to_dl(inf[i].serial, super);
6671 if (dl->index == -1) {
6672 dl->index = mpb->num_disks;
6673 mpb->num_disks++;
6674 dl->disk.status |= CONFIGURED_DISK;
6675 dl->disk.status &= ~SPARE_DISK;
6676 }
6677 set_imsm_ord_tbl_ent(new_map, i, dl->index);
6678 }
6679
ba2de7ba
DW
6680 dv = update->space;
6681 dev = dv->dev;
949c47a0
DW
6682 update->space = NULL;
6683 imsm_copy_dev(dev, &u->dev);
ba2de7ba
DW
6684 dv->index = u->dev_idx;
6685 dv->next = super->devlist;
6686 super->devlist = dv;
8273f55e 6687 mpb->num_raid_devs++;
8273f55e 6688
4d1313e9 6689 imsm_update_version_info(super);
8273f55e 6690 break;
ba2de7ba
DW
6691 create_error:
6692 /* mdmon knows how to release update->space, but not
6693 * ((struct intel_dev *) update->space)->dev
6694 */
6695 if (update->space) {
6696 dv = update->space;
6697 free(dv->dev);
6698 }
8273f55e 6699 break;
e8319a19 6700 }
33414a01
DW
6701 case update_kill_array: {
6702 struct imsm_update_kill_array *u = (void *) update->buf;
6703 int victim = u->dev_idx;
6704 struct active_array *a;
6705 struct intel_dev **dp;
6706 struct imsm_dev *dev;
6707
6708 /* sanity check that we are not affecting the uuid of
6709 * active arrays, or deleting an active array
6710 *
6711 * FIXME when immutable ids are available, but note that
6712 * we'll also need to fixup the invalidated/active
6713 * subarray indexes in mdstat
6714 */
6715 for (a = st->arrays; a; a = a->next)
6716 if (a->info.container_member >= victim)
6717 break;
6718 /* by definition if mdmon is running at least one array
6719 * is active in the container, so checking
6720 * mpb->num_raid_devs is just extra paranoia
6721 */
6722 dev = get_imsm_dev(super, victim);
6723 if (a || !dev || mpb->num_raid_devs == 1) {
6724 dprintf("failed to delete subarray-%d\n", victim);
6725 break;
6726 }
6727
6728 for (dp = &super->devlist; *dp;)
f21e18ca 6729 if ((*dp)->index == (unsigned)super->current_vol) {
33414a01
DW
6730 *dp = (*dp)->next;
6731 } else {
f21e18ca 6732 if ((*dp)->index > (unsigned)victim)
33414a01
DW
6733 (*dp)->index--;
6734 dp = &(*dp)->next;
6735 }
6736 mpb->num_raid_devs--;
6737 super->updates_pending++;
6738 break;
6739 }
aa534678
DW
6740 case update_rename_array: {
6741 struct imsm_update_rename_array *u = (void *) update->buf;
6742 char name[MAX_RAID_SERIAL_LEN+1];
6743 int target = u->dev_idx;
6744 struct active_array *a;
6745 struct imsm_dev *dev;
6746
6747 /* sanity check that we are not affecting the uuid of
6748 * an active array
6749 */
6750 snprintf(name, MAX_RAID_SERIAL_LEN, "%s", (char *) u->name);
6751 name[MAX_RAID_SERIAL_LEN] = '\0';
6752 for (a = st->arrays; a; a = a->next)
6753 if (a->info.container_member == target)
6754 break;
6755 dev = get_imsm_dev(super, u->dev_idx);
6756 if (a || !dev || !check_name(super, name, 1)) {
6757 dprintf("failed to rename subarray-%d\n", target);
6758 break;
6759 }
6760
cdbe98cd 6761 snprintf((char *) dev->volume, MAX_RAID_SERIAL_LEN, "%s", name);
aa534678
DW
6762 super->updates_pending++;
6763 break;
6764 }
1a64be56 6765 case update_add_remove_disk: {
43dad3d6 6766 /* we may be able to repair some arrays if disks are
1a64be56
LM
6767 * being added, check teh status of add_remove_disk
6768 * if discs has been added.
6769 */
6770 if (add_remove_disk_update(super)) {
43dad3d6 6771 struct active_array *a;
072b727f
DW
6772
6773 super->updates_pending++;
1a64be56 6774 for (a = st->arrays; a; a = a->next)
43dad3d6
DW
6775 a->check_degraded = 1;
6776 }
43dad3d6 6777 break;
e8319a19 6778 }
1a64be56
LM
6779 default:
6780 fprintf(stderr, "error: unsuported process update type:"
6781 "(type: %d)\n", type);
6782 }
e8319a19 6783}
88758e9d 6784
bc0b9d34
PC
6785static struct mdinfo *get_spares_for_grow(struct supertype *st);
6786
8273f55e
DW
6787static void imsm_prepare_update(struct supertype *st,
6788 struct metadata_update *update)
6789{
949c47a0 6790 /**
4d7b1503
DW
6791 * Allocate space to hold new disk entries, raid-device entries or a new
6792 * mpb if necessary. The manager synchronously waits for updates to
6793 * complete in the monitor, so new mpb buffers allocated here can be
6794 * integrated by the monitor thread without worrying about live pointers
6795 * in the manager thread.
8273f55e 6796 */
949c47a0 6797 enum imsm_update_type type = *(enum imsm_update_type *) update->buf;
4d7b1503
DW
6798 struct intel_super *super = st->sb;
6799 struct imsm_super *mpb = super->anchor;
6800 size_t buf_len;
6801 size_t len = 0;
949c47a0
DW
6802
6803 switch (type) {
abedf5fc
KW
6804 case update_takeover: {
6805 struct imsm_update_takeover *u = (void *)update->buf;
6806 if (u->direction == R0_TO_R10) {
6807 void **tail = (void **)&update->space_list;
6808 struct imsm_dev *dev = get_imsm_dev(super, u->subarray);
6809 struct imsm_map *map = get_imsm_map(dev, 0);
6810 int num_members = map->num_members;
6811 void *space;
6812 int size, i;
6813 int err = 0;
6814 /* allocate memory for added disks */
6815 for (i = 0; i < num_members; i++) {
6816 size = sizeof(struct dl);
6817 space = malloc(size);
6818 if (!space) {
6819 err++;
6820 break;
6821 }
6822 *tail = space;
6823 tail = space;
6824 *tail = NULL;
6825 }
6826 /* allocate memory for new device */
6827 size = sizeof_imsm_dev(super->devlist->dev, 0) +
6828 (num_members * sizeof(__u32));
6829 space = malloc(size);
6830 if (!space)
6831 err++;
6832 else {
6833 *tail = space;
6834 tail = space;
6835 *tail = NULL;
6836 }
6837 if (!err) {
6838 len = disks_to_mpb_size(num_members * 2);
6839 } else {
6840 /* if allocation didn't success, free buffer */
6841 while (update->space_list) {
6842 void **sp = update->space_list;
6843 update->space_list = *sp;
6844 free(sp);
6845 }
6846 }
6847 }
6848
6849 break;
6850 }
78b10e66 6851 case update_reshape_container_disks: {
d195167d
AK
6852 /* Every raid device in the container is about to
6853 * gain some more devices, and we will enter a
6854 * reconfiguration.
6855 * So each 'imsm_map' will be bigger, and the imsm_vol
6856 * will now hold 2 of them.
6857 * Thus we need new 'struct imsm_dev' allocations sized
6858 * as sizeof_imsm_dev but with more devices in both maps.
6859 */
6860 struct imsm_update_reshape *u = (void *)update->buf;
6861 struct intel_dev *dl;
6862 void **space_tail = (void**)&update->space_list;
6863
6864 dprintf("imsm: imsm_prepare_update() for update_reshape\n");
6865
6866 for (dl = super->devlist; dl; dl = dl->next) {
6867 int size = sizeof_imsm_dev(dl->dev, 1);
6868 void *s;
d677e0b8
AK
6869 if (u->new_raid_disks > u->old_raid_disks)
6870 size += sizeof(__u32)*2*
6871 (u->new_raid_disks - u->old_raid_disks);
d195167d
AK
6872 s = malloc(size);
6873 if (!s)
6874 break;
6875 *space_tail = s;
6876 space_tail = s;
6877 *space_tail = NULL;
6878 }
6879
6880 len = disks_to_mpb_size(u->new_raid_disks);
6881 dprintf("New anchor length is %llu\n", (unsigned long long)len);
78b10e66
N
6882 break;
6883 }
48c5303a 6884 case update_reshape_migration: {
bc0b9d34
PC
6885 /* for migration level 0->5 we need to add disks
6886 * so the same as for container operation we will copy
6887 * device to the bigger location.
6888 * in memory prepared device and new disk area are prepared
6889 * for usage in process update
6890 */
6891 struct imsm_update_reshape_migration *u = (void *)update->buf;
6892 struct intel_dev *id;
6893 void **space_tail = (void **)&update->space_list;
6894 int size;
6895 void *s;
6896 int current_level = -1;
6897
6898 dprintf("imsm: imsm_prepare_update() for update_reshape\n");
6899
6900 /* add space for bigger array in update
6901 */
6902 for (id = super->devlist; id; id = id->next) {
6903 if (id->index == (unsigned)u->subdev) {
6904 size = sizeof_imsm_dev(id->dev, 1);
6905 if (u->new_raid_disks > u->old_raid_disks)
6906 size += sizeof(__u32)*2*
6907 (u->new_raid_disks - u->old_raid_disks);
6908 s = malloc(size);
6909 if (!s)
6910 break;
6911 *space_tail = s;
6912 space_tail = s;
6913 *space_tail = NULL;
6914 break;
6915 }
6916 }
6917 if (update->space_list == NULL)
6918 break;
6919
6920 /* add space for disk in update
6921 */
6922 size = sizeof(struct dl);
6923 s = malloc(size);
6924 if (!s) {
6925 free(update->space_list);
6926 update->space_list = NULL;
6927 break;
6928 }
6929 *space_tail = s;
6930 space_tail = s;
6931 *space_tail = NULL;
6932
6933 /* add spare device to update
6934 */
6935 for (id = super->devlist ; id; id = id->next)
6936 if (id->index == (unsigned)u->subdev) {
6937 struct imsm_dev *dev;
6938 struct imsm_map *map;
6939
6940 dev = get_imsm_dev(super, u->subdev);
6941 map = get_imsm_map(dev, 0);
6942 current_level = map->raid_level;
6943 break;
6944 }
6945 if ((u->new_level == 5) && (u->new_level != current_level)) {
6946 struct mdinfo *spares;
6947
6948 spares = get_spares_for_grow(st);
6949 if (spares) {
6950 struct dl *dl;
6951 struct mdinfo *dev;
6952
6953 dev = spares->devs;
6954 if (dev) {
6955 u->new_disks[0] =
6956 makedev(dev->disk.major,
6957 dev->disk.minor);
6958 dl = get_disk_super(super,
6959 dev->disk.major,
6960 dev->disk.minor);
6961 dl->index = u->old_raid_disks;
6962 dev = dev->next;
6963 }
6964 sysfs_free(spares);
6965 }
6966 }
6967 len = disks_to_mpb_size(u->new_raid_disks);
6968 dprintf("New anchor length is %llu\n", (unsigned long long)len);
48c5303a
PC
6969 break;
6970 }
949c47a0
DW
6971 case update_create_array: {
6972 struct imsm_update_create_array *u = (void *) update->buf;
ba2de7ba 6973 struct intel_dev *dv;
54c2c1ea
DW
6974 struct imsm_dev *dev = &u->dev;
6975 struct imsm_map *map = get_imsm_map(dev, 0);
6976 struct dl *dl;
6977 struct disk_info *inf;
6978 int i;
6979 int activate = 0;
949c47a0 6980
54c2c1ea
DW
6981 inf = get_disk_info(u);
6982 len = sizeof_imsm_dev(dev, 1);
ba2de7ba
DW
6983 /* allocate a new super->devlist entry */
6984 dv = malloc(sizeof(*dv));
6985 if (dv) {
6986 dv->dev = malloc(len);
6987 if (dv->dev)
6988 update->space = dv;
6989 else {
6990 free(dv);
6991 update->space = NULL;
6992 }
6993 }
949c47a0 6994
54c2c1ea
DW
6995 /* count how many spares will be converted to members */
6996 for (i = 0; i < map->num_members; i++) {
6997 dl = serial_to_dl(inf[i].serial, super);
6998 if (!dl) {
6999 /* hmm maybe it failed?, nothing we can do about
7000 * it here
7001 */
7002 continue;
7003 }
7004 if (count_memberships(dl, super) == 0)
7005 activate++;
7006 }
7007 len += activate * sizeof(struct imsm_disk);
949c47a0
DW
7008 break;
7009 default:
7010 break;
7011 }
7012 }
8273f55e 7013
4d7b1503
DW
7014 /* check if we need a larger metadata buffer */
7015 if (super->next_buf)
7016 buf_len = super->next_len;
7017 else
7018 buf_len = super->len;
7019
7020 if (__le32_to_cpu(mpb->mpb_size) + len > buf_len) {
7021 /* ok we need a larger buf than what is currently allocated
7022 * if this allocation fails process_update will notice that
7023 * ->next_len is set and ->next_buf is NULL
7024 */
7025 buf_len = ROUND_UP(__le32_to_cpu(mpb->mpb_size) + len, 512);
7026 if (super->next_buf)
7027 free(super->next_buf);
7028
7029 super->next_len = buf_len;
1f45a8ad
DW
7030 if (posix_memalign(&super->next_buf, 512, buf_len) == 0)
7031 memset(super->next_buf, 0, buf_len);
7032 else
4d7b1503
DW
7033 super->next_buf = NULL;
7034 }
8273f55e
DW
7035}
7036
ae6aad82 7037/* must be called while manager is quiesced */
f21e18ca 7038static void imsm_delete(struct intel_super *super, struct dl **dlp, unsigned index)
ae6aad82
DW
7039{
7040 struct imsm_super *mpb = super->anchor;
ae6aad82
DW
7041 struct dl *iter;
7042 struct imsm_dev *dev;
7043 struct imsm_map *map;
24565c9a
DW
7044 int i, j, num_members;
7045 __u32 ord;
ae6aad82 7046
24565c9a
DW
7047 dprintf("%s: deleting device[%d] from imsm_super\n",
7048 __func__, index);
ae6aad82
DW
7049
7050 /* shift all indexes down one */
7051 for (iter = super->disks; iter; iter = iter->next)
f21e18ca 7052 if (iter->index > (int)index)
ae6aad82 7053 iter->index--;
47ee5a45 7054 for (iter = super->missing; iter; iter = iter->next)
f21e18ca 7055 if (iter->index > (int)index)
47ee5a45 7056 iter->index--;
ae6aad82
DW
7057
7058 for (i = 0; i < mpb->num_raid_devs; i++) {
7059 dev = get_imsm_dev(super, i);
7060 map = get_imsm_map(dev, 0);
24565c9a
DW
7061 num_members = map->num_members;
7062 for (j = 0; j < num_members; j++) {
7063 /* update ord entries being careful not to propagate
7064 * ord-flags to the first map
7065 */
98130f40 7066 ord = get_imsm_ord_tbl_ent(dev, j, -1);
ae6aad82 7067
24565c9a
DW
7068 if (ord_to_idx(ord) <= index)
7069 continue;
ae6aad82 7070
24565c9a
DW
7071 map = get_imsm_map(dev, 0);
7072 set_imsm_ord_tbl_ent(map, j, ord_to_idx(ord - 1));
7073 map = get_imsm_map(dev, 1);
7074 if (map)
7075 set_imsm_ord_tbl_ent(map, j, ord - 1);
ae6aad82
DW
7076 }
7077 }
7078
7079 mpb->num_disks--;
7080 super->updates_pending++;
24565c9a
DW
7081 if (*dlp) {
7082 struct dl *dl = *dlp;
7083
7084 *dlp = (*dlp)->next;
7085 __free_imsm_disk(dl);
7086 }
ae6aad82
DW
7087}
7088
2cda7640
ML
7089static char disk_by_path[] = "/dev/disk/by-path/";
7090
7091static const char *imsm_get_disk_controller_domain(const char *path)
7092{
2cda7640 7093 char disk_path[PATH_MAX];
96234762
LM
7094 char *drv=NULL;
7095 struct stat st;
2cda7640 7096
96234762
LM
7097 strncpy(disk_path, disk_by_path, PATH_MAX - 1);
7098 strncat(disk_path, path, PATH_MAX - strlen(disk_path) - 1);
7099 if (stat(disk_path, &st) == 0) {
7100 struct sys_dev* hba;
7101 char *path=NULL;
7102
7103 path = devt_to_devpath(st.st_rdev);
7104 if (path == NULL)
7105 return "unknown";
7106 hba = find_disk_attached_hba(-1, path);
7107 if (hba && hba->type == SYS_DEV_SAS)
7108 drv = "isci";
7109 else if (hba && hba->type == SYS_DEV_SATA)
7110 drv = "ahci";
7111 else
7112 drv = "unknown";
7113 dprintf("path: %s hba: %s attached: %s\n",
7114 path, (hba) ? hba->path : "NULL", drv);
7115 free(path);
7116 if (hba)
7117 free_sys_dev(&hba);
2cda7640 7118 }
96234762 7119 return drv;
2cda7640
ML
7120}
7121
78b10e66
N
7122static int imsm_find_array_minor_by_subdev(int subdev, int container, int *minor)
7123{
7124 char subdev_name[20];
7125 struct mdstat_ent *mdstat;
7126
7127 sprintf(subdev_name, "%d", subdev);
7128 mdstat = mdstat_by_subdev(subdev_name, container);
7129 if (!mdstat)
7130 return -1;
7131
7132 *minor = mdstat->devnum;
7133 free_mdstat(mdstat);
7134 return 0;
7135}
7136
7137static int imsm_reshape_is_allowed_on_container(struct supertype *st,
7138 struct geo_params *geo,
7139 int *old_raid_disks)
7140{
694575e7
KW
7141 /* currently we only support increasing the number of devices
7142 * for a container. This increases the number of device for each
7143 * member array. They must all be RAID0 or RAID5.
7144 */
78b10e66
N
7145 int ret_val = 0;
7146 struct mdinfo *info, *member;
7147 int devices_that_can_grow = 0;
7148
7149 dprintf("imsm: imsm_reshape_is_allowed_on_container(ENTER): "
7150 "st->devnum = (%i)\n",
7151 st->devnum);
7152
7153 if (geo->size != -1 ||
7154 geo->level != UnSet ||
7155 geo->layout != UnSet ||
7156 geo->chunksize != 0 ||
7157 geo->raid_disks == UnSet) {
7158 dprintf("imsm: Container operation is allowed for "
7159 "raid disks number change only.\n");
7160 return ret_val;
7161 }
7162
7163 info = container_content_imsm(st, NULL);
7164 for (member = info; member; member = member->next) {
7165 int result;
7166 int minor;
7167
7168 dprintf("imsm: checking device_num: %i\n",
7169 member->container_member);
7170
d7d205bd 7171 if (geo->raid_disks <= member->array.raid_disks) {
78b10e66
N
7172 /* we work on container for Online Capacity Expansion
7173 * only so raid_disks has to grow
7174 */
7175 dprintf("imsm: for container operation raid disks "
7176 "increase is required\n");
7177 break;
7178 }
7179
7180 if ((info->array.level != 0) &&
7181 (info->array.level != 5)) {
7182 /* we cannot use this container with other raid level
7183 */
690aae1a 7184 dprintf("imsm: for container operation wrong"
78b10e66
N
7185 " raid level (%i) detected\n",
7186 info->array.level);
7187 break;
7188 } else {
7189 /* check for platform support
7190 * for this raid level configuration
7191 */
7192 struct intel_super *super = st->sb;
7193 if (!is_raid_level_supported(super->orom,
7194 member->array.level,
7195 geo->raid_disks)) {
690aae1a 7196 dprintf("platform does not support raid%d with"
78b10e66
N
7197 " %d disk%s\n",
7198 info->array.level,
7199 geo->raid_disks,
7200 geo->raid_disks > 1 ? "s" : "");
7201 break;
7202 }
2a4a08e7
AK
7203 /* check if component size is aligned to chunk size
7204 */
7205 if (info->component_size %
7206 (info->array.chunk_size/512)) {
7207 dprintf("Component size is not aligned to "
7208 "chunk size\n");
7209 break;
7210 }
78b10e66
N
7211 }
7212
7213 if (*old_raid_disks &&
7214 info->array.raid_disks != *old_raid_disks)
7215 break;
7216 *old_raid_disks = info->array.raid_disks;
7217
7218 /* All raid5 and raid0 volumes in container
7219 * have to be ready for Online Capacity Expansion
7220 * so they need to be assembled. We have already
7221 * checked that no recovery etc is happening.
7222 */
7223 result = imsm_find_array_minor_by_subdev(member->container_member,
7224 st->container_dev,
7225 &minor);
7226 if (result < 0) {
7227 dprintf("imsm: cannot find array\n");
7228 break;
7229 }
7230 devices_that_can_grow++;
7231 }
7232 sysfs_free(info);
7233 if (!member && devices_that_can_grow)
7234 ret_val = 1;
7235
7236 if (ret_val)
7237 dprintf("\tContainer operation allowed\n");
7238 else
7239 dprintf("\tError: %i\n", ret_val);
7240
7241 return ret_val;
7242}
7243
7244/* Function: get_spares_for_grow
7245 * Description: Allocates memory and creates list of spare devices
7246 * avaliable in container. Checks if spare drive size is acceptable.
7247 * Parameters: Pointer to the supertype structure
7248 * Returns: Pointer to the list of spare devices (mdinfo structure) on success,
7249 * NULL if fail
7250 */
7251static struct mdinfo *get_spares_for_grow(struct supertype *st)
7252{
78b10e66 7253 unsigned long long min_size = min_acceptable_spare_size_imsm(st);
326727d9 7254 return container_choose_spares(st, min_size, NULL, NULL, NULL, 0);
78b10e66
N
7255}
7256
7257/******************************************************************************
7258 * function: imsm_create_metadata_update_for_reshape
7259 * Function creates update for whole IMSM container.
7260 *
7261 ******************************************************************************/
7262static int imsm_create_metadata_update_for_reshape(
7263 struct supertype *st,
7264 struct geo_params *geo,
7265 int old_raid_disks,
7266 struct imsm_update_reshape **updatep)
7267{
7268 struct intel_super *super = st->sb;
7269 struct imsm_super *mpb = super->anchor;
7270 int update_memory_size = 0;
7271 struct imsm_update_reshape *u = NULL;
7272 struct mdinfo *spares = NULL;
7273 int i;
7274 int delta_disks = 0;
bbd24d86 7275 struct mdinfo *dev;
78b10e66
N
7276
7277 dprintf("imsm_update_metadata_for_reshape(enter) raid_disks = %i\n",
7278 geo->raid_disks);
7279
7280 delta_disks = geo->raid_disks - old_raid_disks;
7281
7282 /* size of all update data without anchor */
7283 update_memory_size = sizeof(struct imsm_update_reshape);
7284
7285 /* now add space for spare disks that we need to add. */
7286 update_memory_size += sizeof(u->new_disks[0]) * (delta_disks - 1);
7287
7288 u = calloc(1, update_memory_size);
7289 if (u == NULL) {
7290 dprintf("error: "
7291 "cannot get memory for imsm_update_reshape update\n");
7292 return 0;
7293 }
7294 u->type = update_reshape_container_disks;
7295 u->old_raid_disks = old_raid_disks;
7296 u->new_raid_disks = geo->raid_disks;
7297
7298 /* now get spare disks list
7299 */
7300 spares = get_spares_for_grow(st);
7301
7302 if (spares == NULL
7303 || delta_disks > spares->array.spare_disks) {
e14e5960
KW
7304 fprintf(stderr, Name ": imsm: ERROR: Cannot get spare devices "
7305 "for %s.\n", geo->dev_name);
78b10e66
N
7306 goto abort;
7307 }
7308
7309 /* we have got spares
7310 * update disk list in imsm_disk list table in anchor
7311 */
7312 dprintf("imsm: %i spares are available.\n\n",
7313 spares->array.spare_disks);
7314
bbd24d86 7315 dev = spares->devs;
78b10e66 7316 for (i = 0; i < delta_disks; i++) {
78b10e66
N
7317 struct dl *dl;
7318
bbd24d86
AK
7319 if (dev == NULL)
7320 break;
78b10e66
N
7321 u->new_disks[i] = makedev(dev->disk.major,
7322 dev->disk.minor);
7323 dl = get_disk_super(super, dev->disk.major, dev->disk.minor);
ee4beede
AK
7324 dl->index = mpb->num_disks;
7325 mpb->num_disks++;
bbd24d86 7326 dev = dev->next;
78b10e66 7327 }
78b10e66
N
7328
7329abort:
7330 /* free spares
7331 */
7332 sysfs_free(spares);
7333
d677e0b8 7334 dprintf("imsm: reshape update preparation :");
78b10e66 7335 if (i == delta_disks) {
d677e0b8 7336 dprintf(" OK\n");
78b10e66
N
7337 *updatep = u;
7338 return update_memory_size;
7339 }
7340 free(u);
d677e0b8 7341 dprintf(" Error\n");
78b10e66
N
7342
7343 return 0;
7344}
7345
48c5303a
PC
7346/******************************************************************************
7347 * function: imsm_create_metadata_update_for_migration()
7348 * Creates update for IMSM array.
7349 *
7350 ******************************************************************************/
7351static int imsm_create_metadata_update_for_migration(
7352 struct supertype *st,
7353 struct geo_params *geo,
7354 struct imsm_update_reshape_migration **updatep)
7355{
7356 struct intel_super *super = st->sb;
7357 int update_memory_size = 0;
7358 struct imsm_update_reshape_migration *u = NULL;
7359 struct imsm_dev *dev;
7360 int previous_level = -1;
7361
7362 dprintf("imsm_create_metadata_update_for_migration(enter)"
7363 " New Level = %i\n", geo->level);
7364
7365 /* size of all update data without anchor */
7366 update_memory_size = sizeof(struct imsm_update_reshape_migration);
7367
7368 u = calloc(1, update_memory_size);
7369 if (u == NULL) {
7370 dprintf("error: cannot get memory for "
7371 "imsm_create_metadata_update_for_migration\n");
7372 return 0;
7373 }
7374 u->type = update_reshape_migration;
7375 u->subdev = super->current_vol;
7376 u->new_level = geo->level;
7377 u->new_layout = geo->layout;
7378 u->new_raid_disks = u->old_raid_disks = geo->raid_disks;
7379 u->new_disks[0] = -1;
4bba0439 7380 u->new_chunksize = -1;
48c5303a
PC
7381
7382 dev = get_imsm_dev(super, u->subdev);
7383 if (dev) {
7384 struct imsm_map *map;
7385
7386 map = get_imsm_map(dev, 0);
4bba0439
PC
7387 if (map) {
7388 int current_chunk_size =
7389 __le16_to_cpu(map->blocks_per_strip) / 2;
7390
7391 if (geo->chunksize != current_chunk_size) {
7392 u->new_chunksize = geo->chunksize / 1024;
7393 dprintf("imsm: "
7394 "chunk size change from %i to %i\n",
7395 current_chunk_size, u->new_chunksize);
7396 }
48c5303a 7397 previous_level = map->raid_level;
4bba0439 7398 }
48c5303a
PC
7399 }
7400 if ((geo->level == 5) && (previous_level == 0)) {
7401 struct mdinfo *spares = NULL;
7402
7403 u->new_raid_disks++;
7404 spares = get_spares_for_grow(st);
7405 if ((spares == NULL) || (spares->array.spare_disks < 1)) {
7406 free(u);
7407 sysfs_free(spares);
7408 update_memory_size = 0;
7409 dprintf("error: cannot get spare device "
7410 "for requested migration");
7411 return 0;
7412 }
7413 sysfs_free(spares);
7414 }
7415 dprintf("imsm: reshape update preparation : OK\n");
7416 *updatep = u;
7417
7418 return update_memory_size;
7419}
7420
8dd70bce
AK
7421static void imsm_update_metadata_locally(struct supertype *st,
7422 void *buf, int len)
7423{
7424 struct metadata_update mu;
7425
7426 mu.buf = buf;
7427 mu.len = len;
7428 mu.space = NULL;
7429 mu.space_list = NULL;
7430 mu.next = NULL;
7431 imsm_prepare_update(st, &mu);
7432 imsm_process_update(st, &mu);
7433
7434 while (mu.space_list) {
7435 void **space = mu.space_list;
7436 mu.space_list = *space;
7437 free(space);
7438 }
7439}
78b10e66 7440
471bceb6 7441/***************************************************************************
694575e7 7442* Function: imsm_analyze_change
471bceb6
KW
7443* Description: Function analyze change for single volume
7444* and validate if transition is supported
694575e7
KW
7445* Parameters: Geometry parameters, supertype structure
7446* Returns: Operation type code on success, -1 if fail
471bceb6
KW
7447****************************************************************************/
7448enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
7449 struct geo_params *geo)
694575e7 7450{
471bceb6
KW
7451 struct mdinfo info;
7452 int change = -1;
7453 int check_devs = 0;
c21e737b 7454 int chunk;
471bceb6
KW
7455
7456 getinfo_super_imsm_volume(st, &info, NULL);
7457
7458 if ((geo->level != info.array.level) &&
7459 (geo->level >= 0) &&
7460 (geo->level != UnSet)) {
7461 switch (info.array.level) {
7462 case 0:
7463 if (geo->level == 5) {
b5347799 7464 change = CH_MIGRATION;
471bceb6
KW
7465 check_devs = 1;
7466 }
7467 if (geo->level == 10) {
7468 change = CH_TAKEOVER;
7469 check_devs = 1;
7470 }
dfe77a9e
KW
7471 break;
7472 case 1:
7473 if (geo->level == 0) {
7474 change = CH_TAKEOVER;
7475 check_devs = 1;
7476 }
471bceb6 7477 break;
471bceb6
KW
7478 case 10:
7479 if (geo->level == 0) {
7480 change = CH_TAKEOVER;
7481 check_devs = 1;
7482 }
7483 break;
7484 }
7485 if (change == -1) {
7486 fprintf(stderr,
7487 Name " Error. Level Migration from %d to %d "
7488 "not supported!\n",
7489 info.array.level, geo->level);
7490 goto analyse_change_exit;
7491 }
7492 } else
7493 geo->level = info.array.level;
7494
7495 if ((geo->layout != info.array.layout)
7496 && ((geo->layout != UnSet) && (geo->layout != -1))) {
b5347799 7497 change = CH_MIGRATION;
471bceb6
KW
7498 if ((info.array.layout == 0)
7499 && (info.array.level == 5)
7500 && (geo->layout == 5)) {
7501 /* reshape 5 -> 4 */
7502 } else if ((info.array.layout == 5)
7503 && (info.array.level == 5)
7504 && (geo->layout == 0)) {
7505 /* reshape 4 -> 5 */
7506 geo->layout = 0;
7507 geo->level = 5;
7508 } else {
7509 fprintf(stderr,
7510 Name " Error. Layout Migration from %d to %d "
7511 "not supported!\n",
7512 info.array.layout, geo->layout);
7513 change = -1;
7514 goto analyse_change_exit;
7515 }
7516 } else
7517 geo->layout = info.array.layout;
7518
7519 if ((geo->chunksize > 0) && (geo->chunksize != UnSet)
7520 && (geo->chunksize != info.array.chunk_size))
b5347799 7521 change = CH_MIGRATION;
471bceb6
KW
7522 else
7523 geo->chunksize = info.array.chunk_size;
7524
c21e737b 7525 chunk = geo->chunksize / 1024;
471bceb6
KW
7526 if (!validate_geometry_imsm(st,
7527 geo->level,
7528 geo->layout,
7529 geo->raid_disks,
c21e737b 7530 &chunk,
471bceb6
KW
7531 geo->size,
7532 0, 0, 1))
7533 change = -1;
7534
7535 if (check_devs) {
7536 struct intel_super *super = st->sb;
7537 struct imsm_super *mpb = super->anchor;
7538
7539 if (mpb->num_raid_devs > 1) {
7540 fprintf(stderr,
7541 Name " Error. Cannot perform operation on %s"
7542 "- for this operation it MUST be single "
7543 "array in container\n",
7544 geo->dev_name);
7545 change = -1;
7546 }
7547 }
7548
7549analyse_change_exit:
7550
7551 return change;
694575e7
KW
7552}
7553
bb025c2f
KW
7554int imsm_takeover(struct supertype *st, struct geo_params *geo)
7555{
7556 struct intel_super *super = st->sb;
7557 struct imsm_update_takeover *u;
7558
7559 u = malloc(sizeof(struct imsm_update_takeover));
7560 if (u == NULL)
7561 return 1;
7562
7563 u->type = update_takeover;
7564 u->subarray = super->current_vol;
7565
7566 /* 10->0 transition */
7567 if (geo->level == 0)
7568 u->direction = R10_TO_R0;
7569
0529c688
KW
7570 /* 0->10 transition */
7571 if (geo->level == 10)
7572 u->direction = R0_TO_R10;
7573
bb025c2f
KW
7574 /* update metadata locally */
7575 imsm_update_metadata_locally(st, u,
7576 sizeof(struct imsm_update_takeover));
7577 /* and possibly remotely */
7578 if (st->update_tail)
7579 append_metadata_update(st, u,
7580 sizeof(struct imsm_update_takeover));
7581 else
7582 free(u);
7583
7584 return 0;
7585}
7586
6dc0be30
AK
7587static int warn_user_about_risk(void)
7588{
7589 int rv = 0;
7590
7591 fprintf(stderr,
7592 "\nThis is an experimental feature. Data on the RAID volume(s) "
7593 "can be lost!!!\n\n"
7594 "To continue command execution please make sure that\n"
7595 "the grow process will not be interrupted. Use safe power\n"
7596 "supply to avoid unexpected system reboot. Make sure that\n"
7597 "reshaped container is not assembled automatically during\n"
7598 "system boot.\n"
7599 "If reshape is interrupted, assemble array manually\n"
7600 "using e.g. '-Ac' option and up to date mdadm.conf file.\n"
7601 "Assembly in scan mode is not possible in such case.\n"
7602 "Growing container with boot array is not possible.\n"
7603 "If boot array reshape is interrupted, whole file system\n"
7604 "can be lost.\n\n");
7605 rv = ask("Do you want to continue? ");
7606 fprintf(stderr, "\n");
7607
7608 return rv;
7609}
7610
78b10e66
N
7611static int imsm_reshape_super(struct supertype *st, long long size, int level,
7612 int layout, int chunksize, int raid_disks,
41784c88
AK
7613 int delta_disks, char *backup, char *dev,
7614 int verbose)
78b10e66 7615{
78b10e66
N
7616 int ret_val = 1;
7617 struct geo_params geo;
7618
7619 dprintf("imsm: reshape_super called.\n");
7620
71204a50 7621 memset(&geo, 0, sizeof(struct geo_params));
78b10e66
N
7622
7623 geo.dev_name = dev;
694575e7 7624 geo.dev_id = st->devnum;
78b10e66
N
7625 geo.size = size;
7626 geo.level = level;
7627 geo.layout = layout;
7628 geo.chunksize = chunksize;
7629 geo.raid_disks = raid_disks;
41784c88
AK
7630 if (delta_disks != UnSet)
7631 geo.raid_disks += delta_disks;
78b10e66
N
7632
7633 dprintf("\tfor level : %i\n", geo.level);
7634 dprintf("\tfor raid_disks : %i\n", geo.raid_disks);
7635
7636 if (experimental() == 0)
7637 return ret_val;
7638
78b10e66 7639 if (st->container_dev == st->devnum) {
694575e7
KW
7640 /* On container level we can only increase number of devices. */
7641 dprintf("imsm: info: Container operation\n");
78b10e66 7642 int old_raid_disks = 0;
6dc0be30
AK
7643
7644 /* this warning will be removed when imsm checkpointing
7645 * will be implemented, and restoring from check-point
7646 * operation will be transparent for reboot process
7647 */
7648 if (warn_user_about_risk() == 0)
7649 return ret_val;
7650
78b10e66
N
7651 if (imsm_reshape_is_allowed_on_container(
7652 st, &geo, &old_raid_disks)) {
7653 struct imsm_update_reshape *u = NULL;
7654 int len;
7655
7656 len = imsm_create_metadata_update_for_reshape(
7657 st, &geo, old_raid_disks, &u);
7658
ed08d51c
AK
7659 if (len <= 0) {
7660 dprintf("imsm: Cannot prepare update\n");
7661 goto exit_imsm_reshape_super;
7662 }
7663
8dd70bce
AK
7664 ret_val = 0;
7665 /* update metadata locally */
7666 imsm_update_metadata_locally(st, u, len);
7667 /* and possibly remotely */
7668 if (st->update_tail)
7669 append_metadata_update(st, u, len);
7670 else
ed08d51c 7671 free(u);
8dd70bce 7672
694575e7 7673 } else {
e7ff7e40
AK
7674 fprintf(stderr, Name ": (imsm) Operation "
7675 "is not allowed on this container\n");
694575e7
KW
7676 }
7677 } else {
7678 /* On volume level we support following operations
471bceb6
KW
7679 * - takeover: raid10 -> raid0; raid0 -> raid10
7680 * - chunk size migration
7681 * - migration: raid5 -> raid0; raid0 -> raid5
7682 */
7683 struct intel_super *super = st->sb;
7684 struct intel_dev *dev = super->devlist;
7685 int change, devnum;
694575e7 7686 dprintf("imsm: info: Volume operation\n");
471bceb6
KW
7687 /* find requested device */
7688 while (dev) {
7689 imsm_find_array_minor_by_subdev(dev->index, st->container_dev, &devnum);
7690 if (devnum == geo.dev_id)
7691 break;
7692 dev = dev->next;
7693 }
7694 if (dev == NULL) {
7695 fprintf(stderr, Name " Cannot find %s (%i) subarray\n",
7696 geo.dev_name, geo.dev_id);
7697 goto exit_imsm_reshape_super;
7698 }
7699 super->current_vol = dev->index;
694575e7
KW
7700 change = imsm_analyze_change(st, &geo);
7701 switch (change) {
471bceb6 7702 case CH_TAKEOVER:
bb025c2f 7703 ret_val = imsm_takeover(st, &geo);
694575e7 7704 break;
48c5303a
PC
7705 case CH_MIGRATION: {
7706 struct imsm_update_reshape_migration *u = NULL;
7707 int len =
7708 imsm_create_metadata_update_for_migration(
7709 st, &geo, &u);
7710 if (len < 1) {
7711 dprintf("imsm: "
7712 "Cannot prepare update\n");
7713 break;
7714 }
471bceb6 7715 ret_val = 0;
48c5303a
PC
7716 /* update metadata locally */
7717 imsm_update_metadata_locally(st, u, len);
7718 /* and possibly remotely */
7719 if (st->update_tail)
7720 append_metadata_update(st, u, len);
7721 else
7722 free(u);
7723 }
7724 break;
471bceb6
KW
7725 default:
7726 ret_val = 1;
694575e7 7727 }
694575e7 7728 }
78b10e66 7729
ed08d51c 7730exit_imsm_reshape_super:
78b10e66
N
7731 dprintf("imsm: reshape_super Exit code = %i\n", ret_val);
7732 return ret_val;
7733}
2cda7640 7734
999b4972
N
7735static int imsm_manage_reshape(
7736 int afd, struct mdinfo *sra, struct reshape *reshape,
7737 struct supertype *st, unsigned long stripes,
7738 int *fds, unsigned long long *offsets,
7739 int dests, int *destfd, unsigned long long *destoffsets)
7740{
7741 /* Just use child_monitor for now */
7742 return child_monitor(
7743 afd, sra, reshape, st, stripes,
7744 fds, offsets, dests, destfd, destoffsets);
7745}
71204a50 7746#endif /* MDASSEMBLE */
999b4972 7747
cdddbdbc
DW
7748struct superswitch super_imsm = {
7749#ifndef MDASSEMBLE
7750 .examine_super = examine_super_imsm,
7751 .brief_examine_super = brief_examine_super_imsm,
4737ae25 7752 .brief_examine_subarrays = brief_examine_subarrays_imsm,
9d84c8ea 7753 .export_examine_super = export_examine_super_imsm,
cdddbdbc
DW
7754 .detail_super = detail_super_imsm,
7755 .brief_detail_super = brief_detail_super_imsm,
bf5a934a 7756 .write_init_super = write_init_super_imsm,
0e600426
N
7757 .validate_geometry = validate_geometry_imsm,
7758 .add_to_super = add_to_super_imsm,
1a64be56 7759 .remove_from_super = remove_from_super_imsm,
d665cc31 7760 .detail_platform = detail_platform_imsm,
33414a01 7761 .kill_subarray = kill_subarray_imsm,
aa534678 7762 .update_subarray = update_subarray_imsm,
2b959fbf 7763 .load_container = load_container_imsm,
71204a50
N
7764 .default_geometry = default_geometry_imsm,
7765 .get_disk_controller_domain = imsm_get_disk_controller_domain,
7766 .reshape_super = imsm_reshape_super,
7767 .manage_reshape = imsm_manage_reshape,
cdddbdbc
DW
7768#endif
7769 .match_home = match_home_imsm,
7770 .uuid_from_super= uuid_from_super_imsm,
7771 .getinfo_super = getinfo_super_imsm,
5c4cd5da 7772 .getinfo_super_disks = getinfo_super_disks_imsm,
cdddbdbc
DW
7773 .update_super = update_super_imsm,
7774
7775 .avail_size = avail_size_imsm,
80e7f8c3 7776 .min_acceptable_spare_size = min_acceptable_spare_size_imsm,
cdddbdbc
DW
7777
7778 .compare_super = compare_super_imsm,
7779
7780 .load_super = load_super_imsm,
bf5a934a 7781 .init_super = init_super_imsm,
e683ca88 7782 .store_super = store_super_imsm,
cdddbdbc
DW
7783 .free_super = free_super_imsm,
7784 .match_metadata_desc = match_metadata_desc_imsm,
bf5a934a 7785 .container_content = container_content_imsm,
cdddbdbc 7786
cdddbdbc 7787 .external = 1,
4cce4069 7788 .name = "imsm",
845dea95 7789
0e600426 7790#ifndef MDASSEMBLE
845dea95
NB
7791/* for mdmon */
7792 .open_new = imsm_open_new,
ed9d66aa 7793 .set_array_state= imsm_set_array_state,
845dea95
NB
7794 .set_disk = imsm_set_disk,
7795 .sync_metadata = imsm_sync_metadata,
88758e9d 7796 .activate_spare = imsm_activate_spare,
e8319a19 7797 .process_update = imsm_process_update,
8273f55e 7798 .prepare_update = imsm_prepare_update,
0e600426 7799#endif /* MDASSEMBLE */
cdddbdbc 7800};