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