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