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