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