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