]> git.ipfire.org Git - thirdparty/mdadm.git/blame - super-intel.c
Grow: Add paranoid level checking to analyse_change.
[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
e2f41b2c
AK
2843/*******************************************************************************
2844 * Function: check_mpb_migr_compatibility
2845 * Description: Function checks for unsupported migration features:
2846 * - migration optimization area (pba_of_lba0)
2847 * - descending reshape (ascending_migr)
2848 * Parameters:
2849 * super : imsm metadata information
2850 * Returns:
2851 * 0 : migration is compatible
2852 * -1 : migration is not compatible
2853 ******************************************************************************/
2854int check_mpb_migr_compatibility(struct intel_super *super)
2855{
2856 struct imsm_map *map0, *map1;
2857 struct migr_record *migr_rec = super->migr_rec;
2858 int i;
2859
2860 for (i = 0; i < super->anchor->num_raid_devs; i++) {
2861 struct imsm_dev *dev_iter = __get_imsm_dev(super->anchor, i);
2862
2863 if (dev_iter &&
2864 dev_iter->vol.migr_state == 1 &&
2865 dev_iter->vol.migr_type == MIGR_GEN_MIGR) {
2866 /* This device is migrating */
2867 map0 = get_imsm_map(dev_iter, 0);
2868 map1 = get_imsm_map(dev_iter, 1);
2869 if (map0->pba_of_lba0 != map1->pba_of_lba0)
2870 /* migration optimization area was used */
2871 return -1;
2872 if (migr_rec->ascending_migr == 0
2873 && migr_rec->dest_depth_per_unit > 0)
2874 /* descending reshape not supported yet */
2875 return -1;
2876 }
2877 }
2878 return 0;
2879}
2880
d23fe947 2881static void __free_imsm(struct intel_super *super, int free_disks);
9ca2c81c 2882
cdddbdbc 2883/* load_imsm_mpb - read matrix metadata
f2f5c343 2884 * allocates super->mpb to be freed by free_imsm
cdddbdbc
DW
2885 */
2886static int load_imsm_mpb(int fd, struct intel_super *super, char *devname)
2887{
2888 unsigned long long dsize;
cdddbdbc
DW
2889 unsigned long long sectors;
2890 struct stat;
6416d527 2891 struct imsm_super *anchor;
cdddbdbc
DW
2892 __u32 check_sum;
2893
cdddbdbc 2894 get_dev_size(fd, NULL, &dsize);
64436f06
N
2895 if (dsize < 1024) {
2896 if (devname)
2897 fprintf(stderr,
2898 Name ": %s: device to small for imsm\n",
2899 devname);
2900 return 1;
2901 }
cdddbdbc
DW
2902
2903 if (lseek64(fd, dsize - (512 * 2), SEEK_SET) < 0) {
2904 if (devname)
2905 fprintf(stderr,
2906 Name ": Cannot seek to anchor block on %s: %s\n",
2907 devname, strerror(errno));
2908 return 1;
2909 }
2910
949c47a0 2911 if (posix_memalign((void**)&anchor, 512, 512) != 0) {
ad97895e
DW
2912 if (devname)
2913 fprintf(stderr,
2914 Name ": Failed to allocate imsm anchor buffer"
2915 " on %s\n", devname);
2916 return 1;
2917 }
949c47a0 2918 if (read(fd, anchor, 512) != 512) {
cdddbdbc
DW
2919 if (devname)
2920 fprintf(stderr,
2921 Name ": Cannot read anchor block on %s: %s\n",
2922 devname, strerror(errno));
6416d527 2923 free(anchor);
cdddbdbc
DW
2924 return 1;
2925 }
2926
6416d527 2927 if (strncmp((char *) anchor->sig, MPB_SIGNATURE, MPB_SIG_LEN) != 0) {
cdddbdbc
DW
2928 if (devname)
2929 fprintf(stderr,
2930 Name ": no IMSM anchor on %s\n", devname);
6416d527 2931 free(anchor);
cdddbdbc
DW
2932 return 2;
2933 }
2934
d23fe947 2935 __free_imsm(super, 0);
f2f5c343
LM
2936 /* reload capability and hba */
2937
2938 /* capability and hba must be updated with new super allocation */
d424212e 2939 find_intel_hba_capability(fd, super, devname);
949c47a0
DW
2940 super->len = ROUND_UP(anchor->mpb_size, 512);
2941 if (posix_memalign(&super->buf, 512, super->len) != 0) {
cdddbdbc
DW
2942 if (devname)
2943 fprintf(stderr,
2944 Name ": unable to allocate %zu byte mpb buffer\n",
949c47a0 2945 super->len);
6416d527 2946 free(anchor);
cdddbdbc
DW
2947 return 2;
2948 }
949c47a0 2949 memcpy(super->buf, anchor, 512);
cdddbdbc 2950
6416d527
NB
2951 sectors = mpb_sectors(anchor) - 1;
2952 free(anchor);
8e59f3d8
AK
2953
2954 if (posix_memalign(&super->migr_rec_buf, 512, 512) != 0) {
2955 fprintf(stderr, Name
2956 ": %s could not allocate migr_rec buffer\n", __func__);
2957 free(super->buf);
2958 return 2;
2959 }
2960
949c47a0 2961 if (!sectors) {
ecf45690
DW
2962 check_sum = __gen_imsm_checksum(super->anchor);
2963 if (check_sum != __le32_to_cpu(super->anchor->check_sum)) {
2964 if (devname)
2965 fprintf(stderr,
2966 Name ": IMSM checksum %x != %x on %s\n",
2967 check_sum,
2968 __le32_to_cpu(super->anchor->check_sum),
2969 devname);
2970 return 2;
2971 }
2972
a2b97981 2973 return 0;
949c47a0 2974 }
cdddbdbc
DW
2975
2976 /* read the extended mpb */
2977 if (lseek64(fd, dsize - (512 * (2 + sectors)), SEEK_SET) < 0) {
2978 if (devname)
2979 fprintf(stderr,
2980 Name ": Cannot seek to extended mpb on %s: %s\n",
2981 devname, strerror(errno));
2982 return 1;
2983 }
2984
f21e18ca 2985 if ((unsigned)read(fd, super->buf + 512, super->len - 512) != super->len - 512) {
cdddbdbc
DW
2986 if (devname)
2987 fprintf(stderr,
2988 Name ": Cannot read extended mpb on %s: %s\n",
2989 devname, strerror(errno));
2990 return 2;
2991 }
2992
949c47a0
DW
2993 check_sum = __gen_imsm_checksum(super->anchor);
2994 if (check_sum != __le32_to_cpu(super->anchor->check_sum)) {
cdddbdbc
DW
2995 if (devname)
2996 fprintf(stderr,
2997 Name ": IMSM checksum %x != %x on %s\n",
949c47a0 2998 check_sum, __le32_to_cpu(super->anchor->check_sum),
cdddbdbc 2999 devname);
db575f3b 3000 return 3;
cdddbdbc
DW
3001 }
3002
604b746f
JD
3003 /* FIXME the BBM log is disk specific so we cannot use this global
3004 * buffer for all disks. Ok for now since we only look at the global
3005 * bbm_log_size parameter to gate assembly
3006 */
3007 super->bbm_log = __get_imsm_bbm_log(super->anchor);
3008
a2b97981
DW
3009 return 0;
3010}
3011
8e59f3d8
AK
3012static int read_imsm_migr_rec(int fd, struct intel_super *super);
3013
a2b97981
DW
3014static int
3015load_and_parse_mpb(int fd, struct intel_super *super, char *devname, int keep_fd)
3016{
3017 int err;
3018
3019 err = load_imsm_mpb(fd, super, devname);
3020 if (err)
3021 return err;
3022 err = load_imsm_disk(fd, super, devname, keep_fd);
3023 if (err)
3024 return err;
3025 err = parse_raid_devices(super);
4d7b1503 3026
a2b97981 3027 return err;
cdddbdbc
DW
3028}
3029
ae6aad82
DW
3030static void __free_imsm_disk(struct dl *d)
3031{
3032 if (d->fd >= 0)
3033 close(d->fd);
3034 if (d->devname)
3035 free(d->devname);
0dcecb2e
DW
3036 if (d->e)
3037 free(d->e);
ae6aad82
DW
3038 free(d);
3039
3040}
1a64be56 3041
cdddbdbc
DW
3042static void free_imsm_disks(struct intel_super *super)
3043{
47ee5a45 3044 struct dl *d;
cdddbdbc 3045
47ee5a45
DW
3046 while (super->disks) {
3047 d = super->disks;
cdddbdbc 3048 super->disks = d->next;
ae6aad82 3049 __free_imsm_disk(d);
cdddbdbc 3050 }
cb82edca
AK
3051 while (super->disk_mgmt_list) {
3052 d = super->disk_mgmt_list;
3053 super->disk_mgmt_list = d->next;
3054 __free_imsm_disk(d);
3055 }
47ee5a45
DW
3056 while (super->missing) {
3057 d = super->missing;
3058 super->missing = d->next;
3059 __free_imsm_disk(d);
3060 }
3061
cdddbdbc
DW
3062}
3063
9ca2c81c 3064/* free all the pieces hanging off of a super pointer */
d23fe947 3065static void __free_imsm(struct intel_super *super, int free_disks)
cdddbdbc 3066{
88654014
LM
3067 struct intel_hba *elem, *next;
3068
9ca2c81c 3069 if (super->buf) {
949c47a0 3070 free(super->buf);
9ca2c81c
DW
3071 super->buf = NULL;
3072 }
f2f5c343
LM
3073 /* unlink capability description */
3074 super->orom = NULL;
8e59f3d8
AK
3075 if (super->migr_rec_buf) {
3076 free(super->migr_rec_buf);
3077 super->migr_rec_buf = NULL;
3078 }
d23fe947
DW
3079 if (free_disks)
3080 free_imsm_disks(super);
ba2de7ba 3081 free_devlist(super);
88654014
LM
3082 elem = super->hba;
3083 while (elem) {
3084 if (elem->path)
3085 free((void *)elem->path);
3086 next = elem->next;
3087 free(elem);
3088 elem = next;
88c32bb1 3089 }
88654014 3090 super->hba = NULL;
cdddbdbc
DW
3091}
3092
9ca2c81c
DW
3093static void free_imsm(struct intel_super *super)
3094{
d23fe947 3095 __free_imsm(super, 1);
9ca2c81c
DW
3096 free(super);
3097}
cdddbdbc
DW
3098
3099static void free_super_imsm(struct supertype *st)
3100{
3101 struct intel_super *super = st->sb;
3102
3103 if (!super)
3104 return;
3105
3106 free_imsm(super);
3107 st->sb = NULL;
3108}
3109
49133e57 3110static struct intel_super *alloc_super(void)
c2c087e6
DW
3111{
3112 struct intel_super *super = malloc(sizeof(*super));
3113
3114 if (super) {
3115 memset(super, 0, sizeof(*super));
bf5a934a 3116 super->current_vol = -1;
0dcecb2e 3117 super->create_offset = ~((__u32 ) 0);
c2c087e6 3118 }
c2c087e6
DW
3119 return super;
3120}
3121
f0f5a016
LM
3122/*
3123 * find and allocate hba and OROM/EFI based on valid fd of RAID component device
3124 */
d424212e 3125static int find_intel_hba_capability(int fd, struct intel_super *super, char *devname)
f0f5a016
LM
3126{
3127 struct sys_dev *hba_name;
3128 int rv = 0;
3129
3130 if ((fd < 0) || check_env("IMSM_NO_PLATFORM")) {
f2f5c343 3131 super->orom = NULL;
f0f5a016
LM
3132 super->hba = NULL;
3133 return 0;
3134 }
3135 hba_name = find_disk_attached_hba(fd, NULL);
3136 if (!hba_name) {
d424212e 3137 if (devname)
f0f5a016
LM
3138 fprintf(stderr,
3139 Name ": %s is not attached to Intel(R) RAID controller.\n",
d424212e 3140 devname);
f0f5a016
LM
3141 return 1;
3142 }
3143 rv = attach_hba_to_super(super, hba_name);
3144 if (rv == 2) {
d424212e
N
3145 if (devname) {
3146 struct intel_hba *hba = super->hba;
f0f5a016 3147
f0f5a016
LM
3148 fprintf(stderr, Name ": %s is attached to Intel(R) %s RAID "
3149 "controller (%s),\n"
3150 " but the container is assigned to Intel(R) "
3151 "%s RAID controller (",
d424212e 3152 devname,
f0f5a016
LM
3153 hba_name->path,
3154 hba_name->pci_id ? : "Err!",
3155 get_sys_dev_type(hba_name->type));
3156
f0f5a016
LM
3157 while (hba) {
3158 fprintf(stderr, "%s", hba->pci_id ? : "Err!");
3159 if (hba->next)
3160 fprintf(stderr, ", ");
3161 hba = hba->next;
3162 }
3163
3164 fprintf(stderr, ").\n"
3165 " Mixing devices attached to different controllers "
3166 "is not allowed.\n");
3167 }
3168 free_sys_dev(&hba_name);
3169 return 2;
3170 }
f2f5c343 3171 super->orom = find_imsm_capability(hba_name->type);
f0f5a016 3172 free_sys_dev(&hba_name);
f2f5c343
LM
3173 if (!super->orom)
3174 return 3;
f0f5a016
LM
3175 return 0;
3176}
3177
cdddbdbc 3178#ifndef MDASSEMBLE
47ee5a45
DW
3179/* find_missing - helper routine for load_super_imsm_all that identifies
3180 * disks that have disappeared from the system. This routine relies on
3181 * the mpb being uptodate, which it is at load time.
3182 */
3183static int find_missing(struct intel_super *super)
3184{
3185 int i;
3186 struct imsm_super *mpb = super->anchor;
3187 struct dl *dl;
3188 struct imsm_disk *disk;
47ee5a45
DW
3189
3190 for (i = 0; i < mpb->num_disks; i++) {
3191 disk = __get_imsm_disk(mpb, i);
54c2c1ea 3192 dl = serial_to_dl(disk->serial, super);
47ee5a45
DW
3193 if (dl)
3194 continue;
47ee5a45
DW
3195
3196 dl = malloc(sizeof(*dl));
3197 if (!dl)
3198 return 1;
3199 dl->major = 0;
3200 dl->minor = 0;
3201 dl->fd = -1;
3202 dl->devname = strdup("missing");
3203 dl->index = i;
3204 serialcpy(dl->serial, disk->serial);
3205 dl->disk = *disk;
689c9bf3 3206 dl->e = NULL;
47ee5a45
DW
3207 dl->next = super->missing;
3208 super->missing = dl;
3209 }
3210
3211 return 0;
3212}
3213
a2b97981
DW
3214static struct intel_disk *disk_list_get(__u8 *serial, struct intel_disk *disk_list)
3215{
3216 struct intel_disk *idisk = disk_list;
3217
3218 while (idisk) {
3219 if (serialcmp(idisk->disk.serial, serial) == 0)
3220 break;
3221 idisk = idisk->next;
3222 }
3223
3224 return idisk;
3225}
3226
3227static int __prep_thunderdome(struct intel_super **table, int tbl_size,
3228 struct intel_super *super,
3229 struct intel_disk **disk_list)
3230{
3231 struct imsm_disk *d = &super->disks->disk;
3232 struct imsm_super *mpb = super->anchor;
3233 int i, j;
3234
3235 for (i = 0; i < tbl_size; i++) {
3236 struct imsm_super *tbl_mpb = table[i]->anchor;
3237 struct imsm_disk *tbl_d = &table[i]->disks->disk;
3238
3239 if (tbl_mpb->family_num == mpb->family_num) {
3240 if (tbl_mpb->check_sum == mpb->check_sum) {
3241 dprintf("%s: mpb from %d:%d matches %d:%d\n",
3242 __func__, super->disks->major,
3243 super->disks->minor,
3244 table[i]->disks->major,
3245 table[i]->disks->minor);
3246 break;
3247 }
3248
3249 if (((is_configured(d) && !is_configured(tbl_d)) ||
3250 is_configured(d) == is_configured(tbl_d)) &&
3251 tbl_mpb->generation_num < mpb->generation_num) {
3252 /* current version of the mpb is a
3253 * better candidate than the one in
3254 * super_table, but copy over "cross
3255 * generational" status
3256 */
3257 struct intel_disk *idisk;
3258
3259 dprintf("%s: mpb from %d:%d replaces %d:%d\n",
3260 __func__, super->disks->major,
3261 super->disks->minor,
3262 table[i]->disks->major,
3263 table[i]->disks->minor);
3264
3265 idisk = disk_list_get(tbl_d->serial, *disk_list);
3266 if (idisk && is_failed(&idisk->disk))
3267 tbl_d->status |= FAILED_DISK;
3268 break;
3269 } else {
3270 struct intel_disk *idisk;
3271 struct imsm_disk *disk;
3272
3273 /* tbl_mpb is more up to date, but copy
3274 * over cross generational status before
3275 * returning
3276 */
3277 disk = __serial_to_disk(d->serial, mpb, NULL);
3278 if (disk && is_failed(disk))
3279 d->status |= FAILED_DISK;
3280
3281 idisk = disk_list_get(d->serial, *disk_list);
3282 if (idisk) {
3283 idisk->owner = i;
3284 if (disk && is_configured(disk))
3285 idisk->disk.status |= CONFIGURED_DISK;
3286 }
3287
3288 dprintf("%s: mpb from %d:%d prefer %d:%d\n",
3289 __func__, super->disks->major,
3290 super->disks->minor,
3291 table[i]->disks->major,
3292 table[i]->disks->minor);
3293
3294 return tbl_size;
3295 }
3296 }
3297 }
3298
3299 if (i >= tbl_size)
3300 table[tbl_size++] = super;
3301 else
3302 table[i] = super;
3303
3304 /* update/extend the merged list of imsm_disk records */
3305 for (j = 0; j < mpb->num_disks; j++) {
3306 struct imsm_disk *disk = __get_imsm_disk(mpb, j);
3307 struct intel_disk *idisk;
3308
3309 idisk = disk_list_get(disk->serial, *disk_list);
3310 if (idisk) {
3311 idisk->disk.status |= disk->status;
3312 if (is_configured(&idisk->disk) ||
3313 is_failed(&idisk->disk))
3314 idisk->disk.status &= ~(SPARE_DISK);
3315 } else {
3316 idisk = calloc(1, sizeof(*idisk));
3317 if (!idisk)
3318 return -1;
3319 idisk->owner = IMSM_UNKNOWN_OWNER;
3320 idisk->disk = *disk;
3321 idisk->next = *disk_list;
3322 *disk_list = idisk;
3323 }
3324
3325 if (serialcmp(idisk->disk.serial, d->serial) == 0)
3326 idisk->owner = i;
3327 }
3328
3329 return tbl_size;
3330}
3331
3332static struct intel_super *
3333validate_members(struct intel_super *super, struct intel_disk *disk_list,
3334 const int owner)
3335{
3336 struct imsm_super *mpb = super->anchor;
3337 int ok_count = 0;
3338 int i;
3339
3340 for (i = 0; i < mpb->num_disks; i++) {
3341 struct imsm_disk *disk = __get_imsm_disk(mpb, i);
3342 struct intel_disk *idisk;
3343
3344 idisk = disk_list_get(disk->serial, disk_list);
3345 if (idisk) {
3346 if (idisk->owner == owner ||
3347 idisk->owner == IMSM_UNKNOWN_OWNER)
3348 ok_count++;
3349 else
3350 dprintf("%s: '%.16s' owner %d != %d\n",
3351 __func__, disk->serial, idisk->owner,
3352 owner);
3353 } else {
3354 dprintf("%s: unknown disk %x [%d]: %.16s\n",
3355 __func__, __le32_to_cpu(mpb->family_num), i,
3356 disk->serial);
3357 break;
3358 }
3359 }
3360
3361 if (ok_count == mpb->num_disks)
3362 return super;
3363 return NULL;
3364}
3365
3366static void show_conflicts(__u32 family_num, struct intel_super *super_list)
3367{
3368 struct intel_super *s;
3369
3370 for (s = super_list; s; s = s->next) {
3371 if (family_num != s->anchor->family_num)
3372 continue;
3373 fprintf(stderr, "Conflict, offlining family %#x on '%s'\n",
3374 __le32_to_cpu(family_num), s->disks->devname);
3375 }
3376}
3377
3378static struct intel_super *
3379imsm_thunderdome(struct intel_super **super_list, int len)
3380{
3381 struct intel_super *super_table[len];
3382 struct intel_disk *disk_list = NULL;
3383 struct intel_super *champion, *spare;
3384 struct intel_super *s, **del;
3385 int tbl_size = 0;
3386 int conflict;
3387 int i;
3388
3389 memset(super_table, 0, sizeof(super_table));
3390 for (s = *super_list; s; s = s->next)
3391 tbl_size = __prep_thunderdome(super_table, tbl_size, s, &disk_list);
3392
3393 for (i = 0; i < tbl_size; i++) {
3394 struct imsm_disk *d;
3395 struct intel_disk *idisk;
3396 struct imsm_super *mpb = super_table[i]->anchor;
3397
3398 s = super_table[i];
3399 d = &s->disks->disk;
3400
3401 /* 'd' must appear in merged disk list for its
3402 * configuration to be valid
3403 */
3404 idisk = disk_list_get(d->serial, disk_list);
3405 if (idisk && idisk->owner == i)
3406 s = validate_members(s, disk_list, i);
3407 else
3408 s = NULL;
3409
3410 if (!s)
3411 dprintf("%s: marking family: %#x from %d:%d offline\n",
3412 __func__, mpb->family_num,
3413 super_table[i]->disks->major,
3414 super_table[i]->disks->minor);
3415 super_table[i] = s;
3416 }
3417
3418 /* This is where the mdadm implementation differs from the Windows
3419 * driver which has no strict concept of a container. We can only
3420 * assemble one family from a container, so when returning a prodigal
3421 * array member to this system the code will not be able to disambiguate
3422 * the container contents that should be assembled ("foreign" versus
3423 * "local"). It requires user intervention to set the orig_family_num
3424 * to a new value to establish a new container. The Windows driver in
3425 * this situation fixes up the volume name in place and manages the
3426 * foreign array as an independent entity.
3427 */
3428 s = NULL;
3429 spare = NULL;
3430 conflict = 0;
3431 for (i = 0; i < tbl_size; i++) {
3432 struct intel_super *tbl_ent = super_table[i];
3433 int is_spare = 0;
3434
3435 if (!tbl_ent)
3436 continue;
3437
3438 if (tbl_ent->anchor->num_raid_devs == 0) {
3439 spare = tbl_ent;
3440 is_spare = 1;
3441 }
3442
3443 if (s && !is_spare) {
3444 show_conflicts(tbl_ent->anchor->family_num, *super_list);
3445 conflict++;
3446 } else if (!s && !is_spare)
3447 s = tbl_ent;
3448 }
3449
3450 if (!s)
3451 s = spare;
3452 if (!s) {
3453 champion = NULL;
3454 goto out;
3455 }
3456 champion = s;
3457
3458 if (conflict)
3459 fprintf(stderr, "Chose family %#x on '%s', "
3460 "assemble conflicts to new container with '--update=uuid'\n",
3461 __le32_to_cpu(s->anchor->family_num), s->disks->devname);
3462
3463 /* collect all dl's onto 'champion', and update them to
3464 * champion's version of the status
3465 */
3466 for (s = *super_list; s; s = s->next) {
3467 struct imsm_super *mpb = champion->anchor;
3468 struct dl *dl = s->disks;
3469
3470 if (s == champion)
3471 continue;
3472
3473 for (i = 0; i < mpb->num_disks; i++) {
3474 struct imsm_disk *disk;
3475
3476 disk = __serial_to_disk(dl->serial, mpb, &dl->index);
3477 if (disk) {
3478 dl->disk = *disk;
3479 /* only set index on disks that are a member of
3480 * a populated contianer, i.e. one with
3481 * raid_devs
3482 */
3483 if (is_failed(&dl->disk))
3484 dl->index = -2;
3485 else if (is_spare(&dl->disk))
3486 dl->index = -1;
3487 break;
3488 }
3489 }
3490
3491 if (i >= mpb->num_disks) {
3492 struct intel_disk *idisk;
3493
3494 idisk = disk_list_get(dl->serial, disk_list);
ecf408e9 3495 if (idisk && is_spare(&idisk->disk) &&
a2b97981
DW
3496 !is_failed(&idisk->disk) && !is_configured(&idisk->disk))
3497 dl->index = -1;
3498 else {
3499 dl->index = -2;
3500 continue;
3501 }
3502 }
3503
3504 dl->next = champion->disks;
3505 champion->disks = dl;
3506 s->disks = NULL;
3507 }
3508
3509 /* delete 'champion' from super_list */
3510 for (del = super_list; *del; ) {
3511 if (*del == champion) {
3512 *del = (*del)->next;
3513 break;
3514 } else
3515 del = &(*del)->next;
3516 }
3517 champion->next = NULL;
3518
3519 out:
3520 while (disk_list) {
3521 struct intel_disk *idisk = disk_list;
3522
3523 disk_list = disk_list->next;
3524 free(idisk);
3525 }
3526
3527 return champion;
3528}
3529
cdddbdbc 3530static int load_super_imsm_all(struct supertype *st, int fd, void **sbp,
e1902a7b 3531 char *devname)
cdddbdbc
DW
3532{
3533 struct mdinfo *sra;
a2b97981
DW
3534 struct intel_super *super_list = NULL;
3535 struct intel_super *super = NULL;
db575f3b 3536 int devnum = fd2devnum(fd);
a2b97981 3537 struct mdinfo *sd;
db575f3b 3538 int retry;
a2b97981
DW
3539 int err = 0;
3540 int i;
dab4a513
DW
3541
3542 /* check if 'fd' an opened container */
b526e52d 3543 sra = sysfs_read(fd, 0, GET_LEVEL|GET_VERSION|GET_DEVS|GET_STATE);
cdddbdbc
DW
3544 if (!sra)
3545 return 1;
3546
3547 if (sra->array.major_version != -1 ||
3548 sra->array.minor_version != -2 ||
1602d52c
AW
3549 strcmp(sra->text_version, "imsm") != 0) {
3550 err = 1;
3551 goto error;
3552 }
a2b97981
DW
3553 /* load all mpbs */
3554 for (sd = sra->devs, i = 0; sd; sd = sd->next, i++) {
49133e57 3555 struct intel_super *s = alloc_super();
7a6ecd55 3556 char nm[32];
a2b97981 3557 int dfd;
f2f5c343 3558 int rv;
a2b97981
DW
3559
3560 err = 1;
3561 if (!s)
3562 goto error;
3563 s->next = super_list;
3564 super_list = s;
cdddbdbc 3565
a2b97981 3566 err = 2;
cdddbdbc 3567 sprintf(nm, "%d:%d", sd->disk.major, sd->disk.minor);
e1902a7b 3568 dfd = dev_open(nm, O_RDWR);
a2b97981
DW
3569 if (dfd < 0)
3570 goto error;
3571
d424212e 3572 rv = find_intel_hba_capability(dfd, s, devname);
f2f5c343
LM
3573 /* no orom/efi or non-intel hba of the disk */
3574 if (rv != 0)
3575 goto error;
3576
e1902a7b 3577 err = load_and_parse_mpb(dfd, s, NULL, 1);
db575f3b
DW
3578
3579 /* retry the load if we might have raced against mdmon */
a2b97981 3580 if (err == 3 && mdmon_running(devnum))
db575f3b
DW
3581 for (retry = 0; retry < 3; retry++) {
3582 usleep(3000);
e1902a7b 3583 err = load_and_parse_mpb(dfd, s, NULL, 1);
a2b97981 3584 if (err != 3)
db575f3b
DW
3585 break;
3586 }
a2b97981
DW
3587 if (err)
3588 goto error;
cdddbdbc
DW
3589 }
3590
a2b97981
DW
3591 /* all mpbs enter, maybe one leaves */
3592 super = imsm_thunderdome(&super_list, i);
3593 if (!super) {
3594 err = 1;
3595 goto error;
cdddbdbc
DW
3596 }
3597
47ee5a45
DW
3598 if (find_missing(super) != 0) {
3599 free_imsm(super);
a2b97981
DW
3600 err = 2;
3601 goto error;
47ee5a45 3602 }
8e59f3d8
AK
3603
3604 /* load migration record */
3605 err = load_imsm_migr_rec(super, NULL);
3606 if (err) {
3607 err = 4;
3608 goto error;
3609 }
e2f41b2c
AK
3610
3611 /* Check migration compatibility */
3612 if (check_mpb_migr_compatibility(super) != 0) {
3613 fprintf(stderr, Name ": Unsupported migration detected");
3614 if (devname)
3615 fprintf(stderr, " on %s\n", devname);
3616 else
3617 fprintf(stderr, " (IMSM).\n");
3618
3619 err = 5;
3620 goto error;
3621 }
3622
a2b97981
DW
3623 err = 0;
3624
3625 error:
3626 while (super_list) {
3627 struct intel_super *s = super_list;
3628
3629 super_list = super_list->next;
3630 free_imsm(s);
3631 }
1602d52c 3632 sysfs_free(sra);
a2b97981
DW
3633
3634 if (err)
3635 return err;
f7e7067b 3636
cdddbdbc 3637 *sbp = super;
db575f3b 3638 st->container_dev = devnum;
a2b97981 3639 if (err == 0 && st->ss == NULL) {
bf5a934a 3640 st->ss = &super_imsm;
cdddbdbc
DW
3641 st->minor_version = 0;
3642 st->max_devs = IMSM_MAX_DEVICES;
3643 }
cdddbdbc
DW
3644 return 0;
3645}
2b959fbf
N
3646
3647static int load_container_imsm(struct supertype *st, int fd, char *devname)
3648{
3649 return load_super_imsm_all(st, fd, &st->sb, devname);
3650}
cdddbdbc
DW
3651#endif
3652
3653static int load_super_imsm(struct supertype *st, int fd, char *devname)
3654{
3655 struct intel_super *super;
3656 int rv;
3657
691c6ee1
N
3658 if (test_partition(fd))
3659 /* IMSM not allowed on partitions */
3660 return 1;
3661
37424f13
DW
3662 free_super_imsm(st);
3663
49133e57 3664 super = alloc_super();
cdddbdbc
DW
3665 if (!super) {
3666 fprintf(stderr,
3667 Name ": malloc of %zu failed.\n",
3668 sizeof(*super));
3669 return 1;
3670 }
ea2bc72b
LM
3671 /* Load hba and capabilities if they exist.
3672 * But do not preclude loading metadata in case capabilities or hba are
3673 * non-compliant and ignore_hw_compat is set.
3674 */
d424212e 3675 rv = find_intel_hba_capability(fd, super, devname);
f2f5c343 3676 /* no orom/efi or non-intel hba of the disk */
ea2bc72b 3677 if ((rv != 0) && (st->ignore_hw_compat == 0)) {
f2f5c343
LM
3678 if (devname)
3679 fprintf(stderr,
3680 Name ": No OROM/EFI properties for %s\n", devname);
3681 free_imsm(super);
3682 return 2;
3683 }
a2b97981 3684 rv = load_and_parse_mpb(fd, super, devname, 0);
cdddbdbc
DW
3685
3686 if (rv) {
3687 if (devname)
3688 fprintf(stderr,
3689 Name ": Failed to load all information "
3690 "sections on %s\n", devname);
3691 free_imsm(super);
3692 return rv;
3693 }
3694
3695 st->sb = super;
3696 if (st->ss == NULL) {
3697 st->ss = &super_imsm;
3698 st->minor_version = 0;
3699 st->max_devs = IMSM_MAX_DEVICES;
3700 }
8e59f3d8
AK
3701
3702 /* load migration record */
3703 load_imsm_migr_rec(super, NULL);
3704
e2f41b2c
AK
3705 /* Check for unsupported migration features */
3706 if (check_mpb_migr_compatibility(super) != 0) {
3707 fprintf(stderr, Name ": Unsupported migration detected");
3708 if (devname)
3709 fprintf(stderr, " on %s\n", devname);
3710 else
3711 fprintf(stderr, " (IMSM).\n");
3712 return 3;
3713 }
3714
cdddbdbc
DW
3715 return 0;
3716}
3717
ef6ffade
DW
3718static __u16 info_to_blocks_per_strip(mdu_array_info_t *info)
3719{
3720 if (info->level == 1)
3721 return 128;
3722 return info->chunk_size >> 9;
3723}
3724
ff596308 3725static __u32 info_to_num_data_stripes(mdu_array_info_t *info, int num_domains)
ef6ffade
DW
3726{
3727 __u32 num_stripes;
3728
3729 num_stripes = (info->size * 2) / info_to_blocks_per_strip(info);
ff596308 3730 num_stripes /= num_domains;
ef6ffade
DW
3731
3732 return num_stripes;
3733}
3734
fcfd9599
DW
3735static __u32 info_to_blocks_per_member(mdu_array_info_t *info)
3736{
4025c288
DW
3737 if (info->level == 1)
3738 return info->size * 2;
3739 else
3740 return (info->size * 2) & ~(info_to_blocks_per_strip(info) - 1);
fcfd9599
DW
3741}
3742
4d1313e9
DW
3743static void imsm_update_version_info(struct intel_super *super)
3744{
3745 /* update the version and attributes */
3746 struct imsm_super *mpb = super->anchor;
3747 char *version;
3748 struct imsm_dev *dev;
3749 struct imsm_map *map;
3750 int i;
3751
3752 for (i = 0; i < mpb->num_raid_devs; i++) {
3753 dev = get_imsm_dev(super, i);
3754 map = get_imsm_map(dev, 0);
3755 if (__le32_to_cpu(dev->size_high) > 0)
3756 mpb->attributes |= MPB_ATTRIB_2TB;
3757
3758 /* FIXME detect when an array spans a port multiplier */
3759 #if 0
3760 mpb->attributes |= MPB_ATTRIB_PM;
3761 #endif
3762
3763 if (mpb->num_raid_devs > 1 ||
3764 mpb->attributes != MPB_ATTRIB_CHECKSUM_VERIFY) {
3765 version = MPB_VERSION_ATTRIBS;
3766 switch (get_imsm_raid_level(map)) {
3767 case 0: mpb->attributes |= MPB_ATTRIB_RAID0; break;
3768 case 1: mpb->attributes |= MPB_ATTRIB_RAID1; break;
3769 case 10: mpb->attributes |= MPB_ATTRIB_RAID10; break;
3770 case 5: mpb->attributes |= MPB_ATTRIB_RAID5; break;
3771 }
3772 } else {
3773 if (map->num_members >= 5)
3774 version = MPB_VERSION_5OR6_DISK_ARRAY;
3775 else if (dev->status == DEV_CLONE_N_GO)
3776 version = MPB_VERSION_CNG;
3777 else if (get_imsm_raid_level(map) == 5)
3778 version = MPB_VERSION_RAID5;
3779 else if (map->num_members >= 3)
3780 version = MPB_VERSION_3OR4_DISK_ARRAY;
3781 else if (get_imsm_raid_level(map) == 1)
3782 version = MPB_VERSION_RAID1;
3783 else
3784 version = MPB_VERSION_RAID0;
3785 }
3786 strcpy(((char *) mpb->sig) + strlen(MPB_SIGNATURE), version);
3787 }
3788}
3789
aa534678
DW
3790static int check_name(struct intel_super *super, char *name, int quiet)
3791{
3792 struct imsm_super *mpb = super->anchor;
3793 char *reason = NULL;
3794 int i;
3795
3796 if (strlen(name) > MAX_RAID_SERIAL_LEN)
3797 reason = "must be 16 characters or less";
3798
3799 for (i = 0; i < mpb->num_raid_devs; i++) {
3800 struct imsm_dev *dev = get_imsm_dev(super, i);
3801
3802 if (strncmp((char *) dev->volume, name, MAX_RAID_SERIAL_LEN) == 0) {
3803 reason = "already exists";
3804 break;
3805 }
3806 }
3807
3808 if (reason && !quiet)
3809 fprintf(stderr, Name ": imsm volume name %s\n", reason);
3810
3811 return !reason;
3812}
3813
8b353278
DW
3814static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
3815 unsigned long long size, char *name,
3816 char *homehost, int *uuid)
cdddbdbc 3817{
c2c087e6
DW
3818 /* We are creating a volume inside a pre-existing container.
3819 * so st->sb is already set.
3820 */
3821 struct intel_super *super = st->sb;
949c47a0 3822 struct imsm_super *mpb = super->anchor;
ba2de7ba 3823 struct intel_dev *dv;
c2c087e6
DW
3824 struct imsm_dev *dev;
3825 struct imsm_vol *vol;
3826 struct imsm_map *map;
3827 int idx = mpb->num_raid_devs;
3828 int i;
3829 unsigned long long array_blocks;
2c092cad 3830 size_t size_old, size_new;
ff596308 3831 __u32 num_data_stripes;
cdddbdbc 3832
88c32bb1 3833 if (super->orom && mpb->num_raid_devs >= super->orom->vpa) {
c2c087e6 3834 fprintf(stderr, Name": This imsm-container already has the "
88c32bb1 3835 "maximum of %d volumes\n", super->orom->vpa);
c2c087e6
DW
3836 return 0;
3837 }
3838
2c092cad
DW
3839 /* ensure the mpb is large enough for the new data */
3840 size_old = __le32_to_cpu(mpb->mpb_size);
3841 size_new = disks_to_mpb_size(info->nr_disks);
3842 if (size_new > size_old) {
3843 void *mpb_new;
3844 size_t size_round = ROUND_UP(size_new, 512);
3845
3846 if (posix_memalign(&mpb_new, 512, size_round) != 0) {
3847 fprintf(stderr, Name": could not allocate new mpb\n");
3848 return 0;
3849 }
8e59f3d8
AK
3850 if (posix_memalign(&super->migr_rec_buf, 512, 512) != 0) {
3851 fprintf(stderr, Name
3852 ": %s could not allocate migr_rec buffer\n",
3853 __func__);
3854 free(super->buf);
3855 free(super);
3856 return 0;
3857 }
2c092cad
DW
3858 memcpy(mpb_new, mpb, size_old);
3859 free(mpb);
3860 mpb = mpb_new;
949c47a0 3861 super->anchor = mpb_new;
2c092cad
DW
3862 mpb->mpb_size = __cpu_to_le32(size_new);
3863 memset(mpb_new + size_old, 0, size_round - size_old);
3864 }
bf5a934a 3865 super->current_vol = idx;
d23fe947
DW
3866 /* when creating the first raid device in this container set num_disks
3867 * to zero, i.e. delete this spare and add raid member devices in
3868 * add_to_super_imsm_volume()
3869 */
3870 if (super->current_vol == 0)
3871 mpb->num_disks = 0;
5a038140 3872
aa534678
DW
3873 if (!check_name(super, name, 0))
3874 return 0;
ba2de7ba
DW
3875 dv = malloc(sizeof(*dv));
3876 if (!dv) {
3877 fprintf(stderr, Name ": failed to allocate device list entry\n");
3878 return 0;
3879 }
1a2487c2 3880 dev = calloc(1, sizeof(*dev) + sizeof(__u32) * (info->raid_disks - 1));
949c47a0 3881 if (!dev) {
ba2de7ba 3882 free(dv);
949c47a0
DW
3883 fprintf(stderr, Name": could not allocate raid device\n");
3884 return 0;
3885 }
1a2487c2 3886
c2c087e6 3887 strncpy((char *) dev->volume, name, MAX_RAID_SERIAL_LEN);
03bcbc65
DW
3888 if (info->level == 1)
3889 array_blocks = info_to_blocks_per_member(info);
3890 else
3891 array_blocks = calc_array_size(info->level, info->raid_disks,
3892 info->layout, info->chunk_size,
3893 info->size*2);
979d38be
DW
3894 /* round array size down to closest MB */
3895 array_blocks = (array_blocks >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT;
3896
c2c087e6
DW
3897 dev->size_low = __cpu_to_le32((__u32) array_blocks);
3898 dev->size_high = __cpu_to_le32((__u32) (array_blocks >> 32));
1a2487c2 3899 dev->status = (DEV_READ_COALESCING | DEV_WRITE_COALESCING);
c2c087e6
DW
3900 vol = &dev->vol;
3901 vol->migr_state = 0;
1484e727 3902 set_migr_type(dev, MIGR_INIT);
c2c087e6 3903 vol->dirty = 0;
f8f603f1 3904 vol->curr_migr_unit = 0;
a965f303 3905 map = get_imsm_map(dev, 0);
0dcecb2e 3906 map->pba_of_lba0 = __cpu_to_le32(super->create_offset);
fcfd9599 3907 map->blocks_per_member = __cpu_to_le32(info_to_blocks_per_member(info));
ef6ffade 3908 map->blocks_per_strip = __cpu_to_le16(info_to_blocks_per_strip(info));
0556e1a2 3909 map->failed_disk_num = ~0;
c2c087e6
DW
3910 map->map_state = info->level ? IMSM_T_STATE_UNINITIALIZED :
3911 IMSM_T_STATE_NORMAL;
252d23c0 3912 map->ddf = 1;
ef6ffade
DW
3913
3914 if (info->level == 1 && info->raid_disks > 2) {
38950822
AW
3915 free(dev);
3916 free(dv);
ef6ffade
DW
3917 fprintf(stderr, Name": imsm does not support more than 2 disks"
3918 "in a raid1 volume\n");
3919 return 0;
3920 }
81062a36
DW
3921
3922 map->raid_level = info->level;
4d1313e9 3923 if (info->level == 10) {
c2c087e6 3924 map->raid_level = 1;
4d1313e9 3925 map->num_domains = info->raid_disks / 2;
81062a36
DW
3926 } else if (info->level == 1)
3927 map->num_domains = info->raid_disks;
3928 else
ff596308 3929 map->num_domains = 1;
81062a36 3930
ff596308
DW
3931 num_data_stripes = info_to_num_data_stripes(info, map->num_domains);
3932 map->num_data_stripes = __cpu_to_le32(num_data_stripes);
ef6ffade 3933
c2c087e6
DW
3934 map->num_members = info->raid_disks;
3935 for (i = 0; i < map->num_members; i++) {
3936 /* initialized in add_to_super */
4eb26970 3937 set_imsm_ord_tbl_ent(map, i, IMSM_ORD_REBUILD);
c2c087e6 3938 }
949c47a0 3939 mpb->num_raid_devs++;
ba2de7ba
DW
3940
3941 dv->dev = dev;
3942 dv->index = super->current_vol;
3943 dv->next = super->devlist;
3944 super->devlist = dv;
c2c087e6 3945
4d1313e9
DW
3946 imsm_update_version_info(super);
3947
c2c087e6 3948 return 1;
cdddbdbc
DW
3949}
3950
bf5a934a
DW
3951static int init_super_imsm(struct supertype *st, mdu_array_info_t *info,
3952 unsigned long long size, char *name,
3953 char *homehost, int *uuid)
3954{
3955 /* This is primarily called by Create when creating a new array.
3956 * We will then get add_to_super called for each component, and then
3957 * write_init_super called to write it out to each device.
3958 * For IMSM, Create can create on fresh devices or on a pre-existing
3959 * array.
3960 * To create on a pre-existing array a different method will be called.
3961 * This one is just for fresh drives.
3962 */
3963 struct intel_super *super;
3964 struct imsm_super *mpb;
3965 size_t mpb_size;
4d1313e9 3966 char *version;
bf5a934a 3967
bf5a934a 3968 if (st->sb)
e683ca88
DW
3969 return init_super_imsm_volume(st, info, size, name, homehost, uuid);
3970
3971 if (info)
3972 mpb_size = disks_to_mpb_size(info->nr_disks);
3973 else
3974 mpb_size = 512;
bf5a934a 3975
49133e57 3976 super = alloc_super();
e683ca88 3977 if (super && posix_memalign(&super->buf, 512, mpb_size) != 0) {
bf5a934a 3978 free(super);
e683ca88
DW
3979 super = NULL;
3980 }
3981 if (!super) {
3982 fprintf(stderr, Name
3983 ": %s could not allocate superblock\n", __func__);
bf5a934a
DW
3984 return 0;
3985 }
8e59f3d8
AK
3986 if (posix_memalign(&super->migr_rec_buf, 512, 512) != 0) {
3987 fprintf(stderr, Name
3988 ": %s could not allocate migr_rec buffer\n", __func__);
3989 free(super->buf);
3990 free(super);
3991 return 0;
3992 }
e683ca88 3993 memset(super->buf, 0, mpb_size);
ef649044 3994 mpb = super->buf;
e683ca88
DW
3995 mpb->mpb_size = __cpu_to_le32(mpb_size);
3996 st->sb = super;
3997
3998 if (info == NULL) {
3999 /* zeroing superblock */
4000 return 0;
4001 }
bf5a934a 4002
4d1313e9
DW
4003 mpb->attributes = MPB_ATTRIB_CHECKSUM_VERIFY;
4004
4005 version = (char *) mpb->sig;
4006 strcpy(version, MPB_SIGNATURE);
4007 version += strlen(MPB_SIGNATURE);
4008 strcpy(version, MPB_VERSION_RAID0);
bf5a934a 4009
bf5a934a
DW
4010 return 1;
4011}
4012
0e600426 4013#ifndef MDASSEMBLE
f20c3968 4014static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
bf5a934a
DW
4015 int fd, char *devname)
4016{
4017 struct intel_super *super = st->sb;
d23fe947 4018 struct imsm_super *mpb = super->anchor;
bf5a934a
DW
4019 struct dl *dl;
4020 struct imsm_dev *dev;
4021 struct imsm_map *map;
4eb26970 4022 int slot;
bf5a934a 4023
949c47a0 4024 dev = get_imsm_dev(super, super->current_vol);
a965f303 4025 map = get_imsm_map(dev, 0);
bf5a934a 4026
208933a7
N
4027 if (! (dk->state & (1<<MD_DISK_SYNC))) {
4028 fprintf(stderr, Name ": %s: Cannot add spare devices to IMSM volume\n",
4029 devname);
4030 return 1;
4031 }
4032
efb30e7f
DW
4033 if (fd == -1) {
4034 /* we're doing autolayout so grab the pre-marked (in
4035 * validate_geometry) raid_disk
4036 */
4037 for (dl = super->disks; dl; dl = dl->next)
4038 if (dl->raiddisk == dk->raid_disk)
4039 break;
4040 } else {
4041 for (dl = super->disks; dl ; dl = dl->next)
4042 if (dl->major == dk->major &&
4043 dl->minor == dk->minor)
4044 break;
4045 }
d23fe947 4046
208933a7
N
4047 if (!dl) {
4048 fprintf(stderr, Name ": %s is not a member of the same container\n", devname);
f20c3968 4049 return 1;
208933a7 4050 }
bf5a934a 4051
d23fe947
DW
4052 /* add a pristine spare to the metadata */
4053 if (dl->index < 0) {
4054 dl->index = super->anchor->num_disks;
4055 super->anchor->num_disks++;
4056 }
4eb26970
DW
4057 /* Check the device has not already been added */
4058 slot = get_imsm_disk_slot(map, dl->index);
4059 if (slot >= 0 &&
98130f40 4060 (get_imsm_ord_tbl_ent(dev, slot, -1) & IMSM_ORD_REBUILD) == 0) {
4eb26970
DW
4061 fprintf(stderr, Name ": %s has been included in this array twice\n",
4062 devname);
4063 return 1;
4064 }
be73972f 4065 set_imsm_ord_tbl_ent(map, dk->number, dl->index);
ee5aad5a 4066 dl->disk.status = CONFIGURED_DISK;
d23fe947
DW
4067
4068 /* if we are creating the first raid device update the family number */
4069 if (super->current_vol == 0) {
4070 __u32 sum;
4071 struct imsm_dev *_dev = __get_imsm_dev(mpb, 0);
4072 struct imsm_disk *_disk = __get_imsm_disk(mpb, dl->index);
4073
791b666a
AW
4074 if (!_dev || !_disk) {
4075 fprintf(stderr, Name ": BUG mpb setup error\n");
4076 return 1;
4077 }
d23fe947
DW
4078 *_dev = *dev;
4079 *_disk = dl->disk;
148acb7b
DW
4080 sum = random32();
4081 sum += __gen_imsm_checksum(mpb);
d23fe947 4082 mpb->family_num = __cpu_to_le32(sum);
148acb7b 4083 mpb->orig_family_num = mpb->family_num;
d23fe947 4084 }
f20c3968
DW
4085
4086 return 0;
bf5a934a
DW
4087}
4088
88654014 4089
f20c3968 4090static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
88654014 4091 int fd, char *devname)
cdddbdbc 4092{
c2c087e6 4093 struct intel_super *super = st->sb;
c2c087e6
DW
4094 struct dl *dd;
4095 unsigned long long size;
f2f27e63 4096 __u32 id;
c2c087e6
DW
4097 int rv;
4098 struct stat stb;
4099
88654014
LM
4100 /* If we are on an RAID enabled platform check that the disk is
4101 * attached to the raid controller.
4102 * We do not need to test disks attachment for container based additions,
4103 * they shall be already tested when container was created/assembled.
88c32bb1 4104 */
d424212e 4105 rv = find_intel_hba_capability(fd, super, devname);
f2f5c343 4106 /* no orom/efi or non-intel hba of the disk */
f0f5a016
LM
4107 if (rv != 0) {
4108 dprintf("capability: %p fd: %d ret: %d\n",
4109 super->orom, fd, rv);
4110 return 1;
88c32bb1
DW
4111 }
4112
f20c3968
DW
4113 if (super->current_vol >= 0)
4114 return add_to_super_imsm_volume(st, dk, fd, devname);
bf5a934a 4115
c2c087e6
DW
4116 fstat(fd, &stb);
4117 dd = malloc(sizeof(*dd));
b9f594fe 4118 if (!dd) {
c2c087e6
DW
4119 fprintf(stderr,
4120 Name ": malloc failed %s:%d.\n", __func__, __LINE__);
f20c3968 4121 return 1;
c2c087e6
DW
4122 }
4123 memset(dd, 0, sizeof(*dd));
4124 dd->major = major(stb.st_rdev);
4125 dd->minor = minor(stb.st_rdev);
b9f594fe 4126 dd->index = -1;
c2c087e6 4127 dd->devname = devname ? strdup(devname) : NULL;
c2c087e6 4128 dd->fd = fd;
689c9bf3 4129 dd->e = NULL;
1a64be56 4130 dd->action = DISK_ADD;
c2c087e6 4131 rv = imsm_read_serial(fd, devname, dd->serial);
32ba9157 4132 if (rv) {
c2c087e6 4133 fprintf(stderr,
0030e8d6 4134 Name ": failed to retrieve scsi serial, aborting\n");
949c47a0 4135 free(dd);
0030e8d6 4136 abort();
c2c087e6
DW
4137 }
4138
c2c087e6
DW
4139 get_dev_size(fd, NULL, &size);
4140 size /= 512;
1f24f035 4141 serialcpy(dd->disk.serial, dd->serial);
b9f594fe 4142 dd->disk.total_blocks = __cpu_to_le32(size);
ee5aad5a 4143 dd->disk.status = SPARE_DISK;
c2c087e6 4144 if (sysfs_disk_to_scsi_id(fd, &id) == 0)
b9f594fe 4145 dd->disk.scsi_id = __cpu_to_le32(id);
c2c087e6 4146 else
b9f594fe 4147 dd->disk.scsi_id = __cpu_to_le32(0);
43dad3d6
DW
4148
4149 if (st->update_tail) {
1a64be56
LM
4150 dd->next = super->disk_mgmt_list;
4151 super->disk_mgmt_list = dd;
43dad3d6
DW
4152 } else {
4153 dd->next = super->disks;
4154 super->disks = dd;
ceaf0ee1 4155 super->updates_pending++;
43dad3d6 4156 }
f20c3968
DW
4157
4158 return 0;
cdddbdbc
DW
4159}
4160
1a64be56
LM
4161
4162static int remove_from_super_imsm(struct supertype *st, mdu_disk_info_t *dk)
4163{
4164 struct intel_super *super = st->sb;
4165 struct dl *dd;
4166
4167 /* remove from super works only in mdmon - for communication
4168 * manager - monitor. Check if communication memory buffer
4169 * is prepared.
4170 */
4171 if (!st->update_tail) {
4172 fprintf(stderr,
4173 Name ": %s shall be used in mdmon context only"
4174 "(line %d).\n", __func__, __LINE__);
4175 return 1;
4176 }
4177 dd = malloc(sizeof(*dd));
4178 if (!dd) {
4179 fprintf(stderr,
4180 Name ": malloc failed %s:%d.\n", __func__, __LINE__);
4181 return 1;
4182 }
4183 memset(dd, 0, sizeof(*dd));
4184 dd->major = dk->major;
4185 dd->minor = dk->minor;
4186 dd->index = -1;
4187 dd->fd = -1;
4188 dd->disk.status = SPARE_DISK;
4189 dd->action = DISK_REMOVE;
4190
4191 dd->next = super->disk_mgmt_list;
4192 super->disk_mgmt_list = dd;
4193
4194
4195 return 0;
4196}
4197
f796af5d
DW
4198static int store_imsm_mpb(int fd, struct imsm_super *mpb);
4199
4200static union {
4201 char buf[512];
4202 struct imsm_super anchor;
4203} spare_record __attribute__ ((aligned(512)));
c2c087e6 4204
d23fe947
DW
4205/* spare records have their own family number and do not have any defined raid
4206 * devices
4207 */
4208static int write_super_imsm_spares(struct intel_super *super, int doclose)
4209{
d23fe947 4210 struct imsm_super *mpb = super->anchor;
f796af5d 4211 struct imsm_super *spare = &spare_record.anchor;
d23fe947
DW
4212 __u32 sum;
4213 struct dl *d;
4214
f796af5d
DW
4215 spare->mpb_size = __cpu_to_le32(sizeof(struct imsm_super)),
4216 spare->generation_num = __cpu_to_le32(1UL),
4217 spare->attributes = MPB_ATTRIB_CHECKSUM_VERIFY;
4218 spare->num_disks = 1,
4219 spare->num_raid_devs = 0,
4220 spare->cache_size = mpb->cache_size,
4221 spare->pwr_cycle_count = __cpu_to_le32(1),
4222
4223 snprintf((char *) spare->sig, MAX_SIGNATURE_LENGTH,
4224 MPB_SIGNATURE MPB_VERSION_RAID0);
d23fe947
DW
4225
4226 for (d = super->disks; d; d = d->next) {
8796fdc4 4227 if (d->index != -1)
d23fe947
DW
4228 continue;
4229
f796af5d
DW
4230 spare->disk[0] = d->disk;
4231 sum = __gen_imsm_checksum(spare);
4232 spare->family_num = __cpu_to_le32(sum);
4233 spare->orig_family_num = 0;
4234 sum = __gen_imsm_checksum(spare);
4235 spare->check_sum = __cpu_to_le32(sum);
d23fe947 4236
f796af5d 4237 if (store_imsm_mpb(d->fd, spare)) {
d23fe947
DW
4238 fprintf(stderr, "%s: failed for device %d:%d %s\n",
4239 __func__, d->major, d->minor, strerror(errno));
e74255d9 4240 return 1;
d23fe947
DW
4241 }
4242 if (doclose) {
4243 close(d->fd);
4244 d->fd = -1;
4245 }
4246 }
4247
e74255d9 4248 return 0;
d23fe947
DW
4249}
4250
36988a3d 4251static int write_super_imsm(struct supertype *st, int doclose)
cdddbdbc 4252{
36988a3d 4253 struct intel_super *super = st->sb;
949c47a0 4254 struct imsm_super *mpb = super->anchor;
c2c087e6
DW
4255 struct dl *d;
4256 __u32 generation;
4257 __u32 sum;
d23fe947 4258 int spares = 0;
949c47a0 4259 int i;
a48ac0a8 4260 __u32 mpb_size = sizeof(struct imsm_super) - sizeof(struct imsm_disk);
36988a3d 4261 int num_disks = 0;
cdddbdbc 4262
c2c087e6
DW
4263 /* 'generation' is incremented everytime the metadata is written */
4264 generation = __le32_to_cpu(mpb->generation_num);
4265 generation++;
4266 mpb->generation_num = __cpu_to_le32(generation);
4267
148acb7b
DW
4268 /* fix up cases where previous mdadm releases failed to set
4269 * orig_family_num
4270 */
4271 if (mpb->orig_family_num == 0)
4272 mpb->orig_family_num = mpb->family_num;
4273
d23fe947 4274 for (d = super->disks; d; d = d->next) {
8796fdc4 4275 if (d->index == -1)
d23fe947 4276 spares++;
36988a3d 4277 else {
d23fe947 4278 mpb->disk[d->index] = d->disk;
36988a3d
AK
4279 num_disks++;
4280 }
d23fe947 4281 }
36988a3d 4282 for (d = super->missing; d; d = d->next) {
47ee5a45 4283 mpb->disk[d->index] = d->disk;
36988a3d
AK
4284 num_disks++;
4285 }
4286 mpb->num_disks = num_disks;
4287 mpb_size += sizeof(struct imsm_disk) * mpb->num_disks;
b9f594fe 4288
949c47a0
DW
4289 for (i = 0; i < mpb->num_raid_devs; i++) {
4290 struct imsm_dev *dev = __get_imsm_dev(mpb, i);
36988a3d
AK
4291 struct imsm_dev *dev2 = get_imsm_dev(super, i);
4292 if (dev && dev2) {
4293 imsm_copy_dev(dev, dev2);
4294 mpb_size += sizeof_imsm_dev(dev, 0);
4295 }
949c47a0 4296 }
a48ac0a8
DW
4297 mpb_size += __le32_to_cpu(mpb->bbm_log_size);
4298 mpb->mpb_size = __cpu_to_le32(mpb_size);
949c47a0 4299
c2c087e6 4300 /* recalculate checksum */
949c47a0 4301 sum = __gen_imsm_checksum(mpb);
c2c087e6
DW
4302 mpb->check_sum = __cpu_to_le32(sum);
4303
d23fe947 4304 /* write the mpb for disks that compose raid devices */
c2c087e6 4305 for (d = super->disks; d ; d = d->next) {
d23fe947
DW
4306 if (d->index < 0)
4307 continue;
f796af5d 4308 if (store_imsm_mpb(d->fd, mpb))
c2c087e6
DW
4309 fprintf(stderr, "%s: failed for device %d:%d %s\n",
4310 __func__, d->major, d->minor, strerror(errno));
c2c087e6
DW
4311 if (doclose) {
4312 close(d->fd);
4313 d->fd = -1;
4314 }
4315 }
4316
d23fe947
DW
4317 if (spares)
4318 return write_super_imsm_spares(super, doclose);
4319
e74255d9 4320 return 0;
c2c087e6
DW
4321}
4322
0e600426 4323
9b1fb677 4324static int create_array(struct supertype *st, int dev_idx)
43dad3d6
DW
4325{
4326 size_t len;
4327 struct imsm_update_create_array *u;
4328 struct intel_super *super = st->sb;
9b1fb677 4329 struct imsm_dev *dev = get_imsm_dev(super, dev_idx);
54c2c1ea
DW
4330 struct imsm_map *map = get_imsm_map(dev, 0);
4331 struct disk_info *inf;
4332 struct imsm_disk *disk;
4333 int i;
43dad3d6 4334
54c2c1ea
DW
4335 len = sizeof(*u) - sizeof(*dev) + sizeof_imsm_dev(dev, 0) +
4336 sizeof(*inf) * map->num_members;
43dad3d6
DW
4337 u = malloc(len);
4338 if (!u) {
4339 fprintf(stderr, "%s: failed to allocate update buffer\n",
4340 __func__);
4341 return 1;
4342 }
4343
4344 u->type = update_create_array;
9b1fb677 4345 u->dev_idx = dev_idx;
43dad3d6 4346 imsm_copy_dev(&u->dev, dev);
54c2c1ea
DW
4347 inf = get_disk_info(u);
4348 for (i = 0; i < map->num_members; i++) {
98130f40 4349 int idx = get_imsm_disk_idx(dev, i, -1);
9b1fb677 4350
54c2c1ea
DW
4351 disk = get_imsm_disk(super, idx);
4352 serialcpy(inf[i].serial, disk->serial);
4353 }
43dad3d6
DW
4354 append_metadata_update(st, u, len);
4355
4356 return 0;
4357}
4358
1a64be56 4359static int mgmt_disk(struct supertype *st)
43dad3d6
DW
4360{
4361 struct intel_super *super = st->sb;
4362 size_t len;
1a64be56 4363 struct imsm_update_add_remove_disk *u;
43dad3d6 4364
1a64be56 4365 if (!super->disk_mgmt_list)
43dad3d6
DW
4366 return 0;
4367
4368 len = sizeof(*u);
4369 u = malloc(len);
4370 if (!u) {
4371 fprintf(stderr, "%s: failed to allocate update buffer\n",
4372 __func__);
4373 return 1;
4374 }
4375
1a64be56 4376 u->type = update_add_remove_disk;
43dad3d6
DW
4377 append_metadata_update(st, u, len);
4378
4379 return 0;
4380}
4381
c2c087e6
DW
4382static int write_init_super_imsm(struct supertype *st)
4383{
9b1fb677
DW
4384 struct intel_super *super = st->sb;
4385 int current_vol = super->current_vol;
4386
4387 /* we are done with current_vol reset it to point st at the container */
4388 super->current_vol = -1;
4389
8273f55e 4390 if (st->update_tail) {
43dad3d6
DW
4391 /* queue the recently created array / added disk
4392 * as a metadata update */
43dad3d6 4393 int rv;
8273f55e 4394
43dad3d6 4395 /* determine if we are creating a volume or adding a disk */
9b1fb677 4396 if (current_vol < 0) {
1a64be56
LM
4397 /* in the mgmt (add/remove) disk case we are running
4398 * in mdmon context, so don't close fd's
43dad3d6 4399 */
1a64be56 4400 return mgmt_disk(st);
43dad3d6 4401 } else
9b1fb677 4402 rv = create_array(st, current_vol);
8273f55e 4403
43dad3d6 4404 return rv;
d682f344
N
4405 } else {
4406 struct dl *d;
4407 for (d = super->disks; d; d = d->next)
4408 Kill(d->devname, NULL, 0, 1, 1);
36988a3d 4409 return write_super_imsm(st, 1);
d682f344 4410 }
cdddbdbc 4411}
0e600426 4412#endif
cdddbdbc 4413
e683ca88 4414static int store_super_imsm(struct supertype *st, int fd)
cdddbdbc 4415{
e683ca88
DW
4416 struct intel_super *super = st->sb;
4417 struct imsm_super *mpb = super ? super->anchor : NULL;
551c80c1 4418
e683ca88 4419 if (!mpb)
ad97895e
DW
4420 return 1;
4421
1799c9e8 4422#ifndef MDASSEMBLE
e683ca88 4423 return store_imsm_mpb(fd, mpb);
1799c9e8
N
4424#else
4425 return 1;
4426#endif
cdddbdbc
DW
4427}
4428
0e600426
N
4429static int imsm_bbm_log_size(struct imsm_super *mpb)
4430{
4431 return __le32_to_cpu(mpb->bbm_log_size);
4432}
4433
4434#ifndef MDASSEMBLE
cdddbdbc
DW
4435static int validate_geometry_imsm_container(struct supertype *st, int level,
4436 int layout, int raiddisks, int chunk,
c2c087e6 4437 unsigned long long size, char *dev,
2c514b71
NB
4438 unsigned long long *freesize,
4439 int verbose)
cdddbdbc 4440{
c2c087e6
DW
4441 int fd;
4442 unsigned long long ldsize;
f2f5c343
LM
4443 struct intel_super *super=NULL;
4444 int rv = 0;
cdddbdbc 4445
c2c087e6
DW
4446 if (level != LEVEL_CONTAINER)
4447 return 0;
4448 if (!dev)
4449 return 1;
4450
4451 fd = open(dev, O_RDONLY|O_EXCL, 0);
4452 if (fd < 0) {
2c514b71
NB
4453 if (verbose)
4454 fprintf(stderr, Name ": imsm: Cannot open %s: %s\n",
4455 dev, strerror(errno));
c2c087e6
DW
4456 return 0;
4457 }
4458 if (!get_dev_size(fd, dev, &ldsize)) {
4459 close(fd);
4460 return 0;
4461 }
f2f5c343
LM
4462
4463 /* capabilities retrieve could be possible
4464 * note that there is no fd for the disks in array.
4465 */
4466 super = alloc_super();
4467 if (!super) {
4468 fprintf(stderr,
4469 Name ": malloc of %zu failed.\n",
4470 sizeof(*super));
4471 close(fd);
4472 return 0;
4473 }
4474
d424212e 4475 rv = find_intel_hba_capability(fd, super, verbose ? dev : NULL);
f2f5c343
LM
4476 if (rv != 0) {
4477#if DEBUG
4478 char str[256];
4479 fd2devname(fd, str);
4480 dprintf("validate_geometry_imsm_container: fd: %d %s orom: %p rv: %d raiddisk: %d\n",
4481 fd, str, super->orom, rv, raiddisks);
4482#endif
4483 /* no orom/efi or non-intel hba of the disk */
4484 close(fd);
4485 free_imsm(super);
4486 return 0;
4487 }
c2c087e6 4488 close(fd);
f2f5c343
LM
4489 if (super->orom && raiddisks > super->orom->tds) {
4490 if (verbose)
4491 fprintf(stderr, Name ": %d exceeds maximum number of"
4492 " platform supported disks: %d\n",
4493 raiddisks, super->orom->tds);
4494
4495 free_imsm(super);
4496 return 0;
4497 }
c2c087e6
DW
4498
4499 *freesize = avail_size_imsm(st, ldsize >> 9);
f2f5c343 4500 free_imsm(super);
c2c087e6
DW
4501
4502 return 1;
cdddbdbc
DW
4503}
4504
0dcecb2e
DW
4505static unsigned long long find_size(struct extent *e, int *idx, int num_extents)
4506{
4507 const unsigned long long base_start = e[*idx].start;
4508 unsigned long long end = base_start + e[*idx].size;
4509 int i;
4510
4511 if (base_start == end)
4512 return 0;
4513
4514 *idx = *idx + 1;
4515 for (i = *idx; i < num_extents; i++) {
4516 /* extend overlapping extents */
4517 if (e[i].start >= base_start &&
4518 e[i].start <= end) {
4519 if (e[i].size == 0)
4520 return 0;
4521 if (e[i].start + e[i].size > end)
4522 end = e[i].start + e[i].size;
4523 } else if (e[i].start > end) {
4524 *idx = i;
4525 break;
4526 }
4527 }
4528
4529 return end - base_start;
4530}
4531
4532static unsigned long long merge_extents(struct intel_super *super, int sum_extents)
4533{
4534 /* build a composite disk with all known extents and generate a new
4535 * 'maxsize' given the "all disks in an array must share a common start
4536 * offset" constraint
4537 */
4538 struct extent *e = calloc(sum_extents, sizeof(*e));
4539 struct dl *dl;
4540 int i, j;
4541 int start_extent;
4542 unsigned long long pos;
b9d77223 4543 unsigned long long start = 0;
0dcecb2e
DW
4544 unsigned long long maxsize;
4545 unsigned long reserve;
4546
4547 if (!e)
a7dd165b 4548 return 0;
0dcecb2e
DW
4549
4550 /* coalesce and sort all extents. also, check to see if we need to
4551 * reserve space between member arrays
4552 */
4553 j = 0;
4554 for (dl = super->disks; dl; dl = dl->next) {
4555 if (!dl->e)
4556 continue;
4557 for (i = 0; i < dl->extent_cnt; i++)
4558 e[j++] = dl->e[i];
4559 }
4560 qsort(e, sum_extents, sizeof(*e), cmp_extent);
4561
4562 /* merge extents */
4563 i = 0;
4564 j = 0;
4565 while (i < sum_extents) {
4566 e[j].start = e[i].start;
4567 e[j].size = find_size(e, &i, sum_extents);
4568 j++;
4569 if (e[j-1].size == 0)
4570 break;
4571 }
4572
4573 pos = 0;
4574 maxsize = 0;
4575 start_extent = 0;
4576 i = 0;
4577 do {
4578 unsigned long long esize;
4579
4580 esize = e[i].start - pos;
4581 if (esize >= maxsize) {
4582 maxsize = esize;
4583 start = pos;
4584 start_extent = i;
4585 }
4586 pos = e[i].start + e[i].size;
4587 i++;
4588 } while (e[i-1].size);
4589 free(e);
4590
a7dd165b
DW
4591 if (maxsize == 0)
4592 return 0;
4593
4594 /* FIXME assumes volume at offset 0 is the first volume in a
4595 * container
4596 */
0dcecb2e
DW
4597 if (start_extent > 0)
4598 reserve = IMSM_RESERVED_SECTORS; /* gap between raid regions */
4599 else
4600 reserve = 0;
4601
4602 if (maxsize < reserve)
a7dd165b 4603 return 0;
0dcecb2e
DW
4604
4605 super->create_offset = ~((__u32) 0);
4606 if (start + reserve > super->create_offset)
a7dd165b 4607 return 0; /* start overflows create_offset */
0dcecb2e
DW
4608 super->create_offset = start + reserve;
4609
4610 return maxsize - reserve;
4611}
4612
88c32bb1
DW
4613static int is_raid_level_supported(const struct imsm_orom *orom, int level, int raiddisks)
4614{
4615 if (level < 0 || level == 6 || level == 4)
4616 return 0;
4617
4618 /* if we have an orom prevent invalid raid levels */
4619 if (orom)
4620 switch (level) {
4621 case 0: return imsm_orom_has_raid0(orom);
4622 case 1:
4623 if (raiddisks > 2)
4624 return imsm_orom_has_raid1e(orom);
1c556e92
DW
4625 return imsm_orom_has_raid1(orom) && raiddisks == 2;
4626 case 10: return imsm_orom_has_raid10(orom) && raiddisks == 4;
4627 case 5: return imsm_orom_has_raid5(orom) && raiddisks > 2;
88c32bb1
DW
4628 }
4629 else
4630 return 1; /* not on an Intel RAID platform so anything goes */
4631
4632 return 0;
4633}
4634
73408129 4635
35f81cbb 4636#define pr_vrb(fmt, arg...) (void) (verbose && fprintf(stderr, Name fmt, ##arg))
73408129
LM
4637/*
4638 * validate volume parameters with OROM/EFI capabilities
4639 */
6592ce37
DW
4640static int
4641validate_geometry_imsm_orom(struct intel_super *super, int level, int layout,
c21e737b 4642 int raiddisks, int *chunk, int verbose)
6592ce37 4643{
73408129
LM
4644#if DEBUG
4645 verbose = 1;
4646#endif
4647 /* validate container capabilities */
4648 if (super->orom && raiddisks > super->orom->tds) {
4649 if (verbose)
4650 fprintf(stderr, Name ": %d exceeds maximum number of"
4651 " platform supported disks: %d\n",
4652 raiddisks, super->orom->tds);
4653 return 0;
4654 }
4655
4656 /* capabilities of OROM tested - copied from validate_geometry_imsm_volume */
4657 if (super->orom && (!is_raid_level_supported(super->orom, level,
4658 raiddisks))) {
6592ce37
DW
4659 pr_vrb(": platform does not support raid%d with %d disk%s\n",
4660 level, raiddisks, raiddisks > 1 ? "s" : "");
4661 return 0;
4662 }
c21e737b
CA
4663 if (super->orom && level != 1) {
4664 if (chunk && (*chunk == 0 || *chunk == UnSet))
4665 *chunk = imsm_orom_default_chunk(super->orom);
4666 else if (chunk && !imsm_orom_has_chunk(super->orom, *chunk)) {
4667 pr_vrb(": platform does not support a chunk size of: "
4668 "%d\n", *chunk);
4669 return 0;
4670 }
6592ce37
DW
4671 }
4672 if (layout != imsm_level_to_layout(level)) {
4673 if (level == 5)
4674 pr_vrb(": imsm raid 5 only supports the left-asymmetric layout\n");
4675 else if (level == 10)
4676 pr_vrb(": imsm raid 10 only supports the n2 layout\n");
4677 else
4678 pr_vrb(": imsm unknown layout %#x for this raid level %d\n",
4679 layout, level);
4680 return 0;
4681 }
6592ce37
DW
4682 return 1;
4683}
4684
c2c087e6
DW
4685/* validate_geometry_imsm_volume - lifted from validate_geometry_ddf_bvd
4686 * FIX ME add ahci details
4687 */
8b353278 4688static int validate_geometry_imsm_volume(struct supertype *st, int level,
c21e737b 4689 int layout, int raiddisks, int *chunk,
c2c087e6 4690 unsigned long long size, char *dev,
2c514b71
NB
4691 unsigned long long *freesize,
4692 int verbose)
cdddbdbc 4693{
c2c087e6
DW
4694 struct stat stb;
4695 struct intel_super *super = st->sb;
a20d2ba5 4696 struct imsm_super *mpb = super->anchor;
c2c087e6
DW
4697 struct dl *dl;
4698 unsigned long long pos = 0;
4699 unsigned long long maxsize;
4700 struct extent *e;
4701 int i;
cdddbdbc 4702
88c32bb1
DW
4703 /* We must have the container info already read in. */
4704 if (!super)
c2c087e6
DW
4705 return 0;
4706
d54559f0
LM
4707 if (!validate_geometry_imsm_orom(super, level, layout, raiddisks, chunk, verbose)) {
4708 fprintf(stderr, Name ": RAID gemetry validation failed. "
4709 "Cannot proceed with the action(s).\n");
c2c087e6 4710 return 0;
d54559f0 4711 }
c2c087e6
DW
4712 if (!dev) {
4713 /* General test: make sure there is space for
2da8544a
DW
4714 * 'raiddisks' device extents of size 'size' at a given
4715 * offset
c2c087e6 4716 */
e46273eb 4717 unsigned long long minsize = size;
b7528a20 4718 unsigned long long start_offset = MaxSector;
c2c087e6
DW
4719 int dcnt = 0;
4720 if (minsize == 0)
4721 minsize = MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS;
4722 for (dl = super->disks; dl ; dl = dl->next) {
4723 int found = 0;
4724
bf5a934a 4725 pos = 0;
c2c087e6
DW
4726 i = 0;
4727 e = get_extents(super, dl);
4728 if (!e) continue;
4729 do {
4730 unsigned long long esize;
4731 esize = e[i].start - pos;
4732 if (esize >= minsize)
4733 found = 1;
b7528a20 4734 if (found && start_offset == MaxSector) {
2da8544a
DW
4735 start_offset = pos;
4736 break;
4737 } else if (found && pos != start_offset) {
4738 found = 0;
4739 break;
4740 }
c2c087e6
DW
4741 pos = e[i].start + e[i].size;
4742 i++;
4743 } while (e[i-1].size);
4744 if (found)
4745 dcnt++;
4746 free(e);
4747 }
4748 if (dcnt < raiddisks) {
2c514b71
NB
4749 if (verbose)
4750 fprintf(stderr, Name ": imsm: Not enough "
4751 "devices with space for this array "
4752 "(%d < %d)\n",
4753 dcnt, raiddisks);
c2c087e6
DW
4754 return 0;
4755 }
4756 return 1;
4757 }
0dcecb2e 4758
c2c087e6
DW
4759 /* This device must be a member of the set */
4760 if (stat(dev, &stb) < 0)
4761 return 0;
4762 if ((S_IFMT & stb.st_mode) != S_IFBLK)
4763 return 0;
4764 for (dl = super->disks ; dl ; dl = dl->next) {
f21e18ca
N
4765 if (dl->major == (int)major(stb.st_rdev) &&
4766 dl->minor == (int)minor(stb.st_rdev))
c2c087e6
DW
4767 break;
4768 }
4769 if (!dl) {
2c514b71
NB
4770 if (verbose)
4771 fprintf(stderr, Name ": %s is not in the "
4772 "same imsm set\n", dev);
c2c087e6 4773 return 0;
a20d2ba5
DW
4774 } else if (super->orom && dl->index < 0 && mpb->num_raid_devs) {
4775 /* If a volume is present then the current creation attempt
4776 * cannot incorporate new spares because the orom may not
4777 * understand this configuration (all member disks must be
4778 * members of each array in the container).
4779 */
4780 fprintf(stderr, Name ": %s is a spare and a volume"
4781 " is already defined for this container\n", dev);
4782 fprintf(stderr, Name ": The option-rom requires all member"
4783 " disks to be a member of all volumes\n");
4784 return 0;
c2c087e6 4785 }
0dcecb2e
DW
4786
4787 /* retrieve the largest free space block */
c2c087e6
DW
4788 e = get_extents(super, dl);
4789 maxsize = 0;
4790 i = 0;
0dcecb2e
DW
4791 if (e) {
4792 do {
4793 unsigned long long esize;
4794
4795 esize = e[i].start - pos;
4796 if (esize >= maxsize)
4797 maxsize = esize;
4798 pos = e[i].start + e[i].size;
4799 i++;
4800 } while (e[i-1].size);
4801 dl->e = e;
4802 dl->extent_cnt = i;
4803 } else {
4804 if (verbose)
4805 fprintf(stderr, Name ": unable to determine free space for: %s\n",
4806 dev);
4807 return 0;
4808 }
4809 if (maxsize < size) {
4810 if (verbose)
4811 fprintf(stderr, Name ": %s not enough space (%llu < %llu)\n",
4812 dev, maxsize, size);
4813 return 0;
4814 }
4815
4816 /* count total number of extents for merge */
4817 i = 0;
4818 for (dl = super->disks; dl; dl = dl->next)
4819 if (dl->e)
4820 i += dl->extent_cnt;
4821
4822 maxsize = merge_extents(super, i);
a7dd165b 4823 if (maxsize < size || maxsize == 0) {
0dcecb2e
DW
4824 if (verbose)
4825 fprintf(stderr, Name ": not enough space after merge (%llu < %llu)\n",
4826 maxsize, size);
4827 return 0;
0dcecb2e
DW
4828 }
4829
c2c087e6
DW
4830 *freesize = maxsize;
4831
4832 return 1;
cdddbdbc
DW
4833}
4834
efb30e7f
DW
4835static int reserve_space(struct supertype *st, int raiddisks,
4836 unsigned long long size, int chunk,
4837 unsigned long long *freesize)
4838{
4839 struct intel_super *super = st->sb;
4840 struct imsm_super *mpb = super->anchor;
4841 struct dl *dl;
4842 int i;
4843 int extent_cnt;
4844 struct extent *e;
4845 unsigned long long maxsize;
4846 unsigned long long minsize;
4847 int cnt;
4848 int used;
4849
4850 /* find the largest common start free region of the possible disks */
4851 used = 0;
4852 extent_cnt = 0;
4853 cnt = 0;
4854 for (dl = super->disks; dl; dl = dl->next) {
4855 dl->raiddisk = -1;
4856
4857 if (dl->index >= 0)
4858 used++;
4859
4860 /* don't activate new spares if we are orom constrained
4861 * and there is already a volume active in the container
4862 */
4863 if (super->orom && dl->index < 0 && mpb->num_raid_devs)
4864 continue;
4865
4866 e = get_extents(super, dl);
4867 if (!e)
4868 continue;
4869 for (i = 1; e[i-1].size; i++)
4870 ;
4871 dl->e = e;
4872 dl->extent_cnt = i;
4873 extent_cnt += i;
4874 cnt++;
4875 }
4876
4877 maxsize = merge_extents(super, extent_cnt);
4878 minsize = size;
4879 if (size == 0)
612e59d8
CA
4880 /* chunk is in K */
4881 minsize = chunk * 2;
efb30e7f
DW
4882
4883 if (cnt < raiddisks ||
4884 (super->orom && used && used != raiddisks) ||
a7dd165b
DW
4885 maxsize < minsize ||
4886 maxsize == 0) {
efb30e7f
DW
4887 fprintf(stderr, Name ": not enough devices with space to create array.\n");
4888 return 0; /* No enough free spaces large enough */
4889 }
4890
4891 if (size == 0) {
4892 size = maxsize;
4893 if (chunk) {
612e59d8
CA
4894 size /= 2 * chunk;
4895 size *= 2 * chunk;
efb30e7f
DW
4896 }
4897 }
4898
4899 cnt = 0;
4900 for (dl = super->disks; dl; dl = dl->next)
4901 if (dl->e)
4902 dl->raiddisk = cnt++;
4903
4904 *freesize = size;
4905
4906 return 1;
4907}
4908
bf5a934a 4909static int validate_geometry_imsm(struct supertype *st, int level, int layout,
c21e737b 4910 int raiddisks, int *chunk, unsigned long long size,
bf5a934a
DW
4911 char *dev, unsigned long long *freesize,
4912 int verbose)
4913{
4914 int fd, cfd;
4915 struct mdinfo *sra;
20cbe8d2 4916 int is_member = 0;
bf5a934a 4917
d54559f0
LM
4918 /* load capability
4919 * if given unused devices create a container
bf5a934a
DW
4920 * if given given devices in a container create a member volume
4921 */
4922 if (level == LEVEL_CONTAINER) {
4923 /* Must be a fresh device to add to a container */
4924 return validate_geometry_imsm_container(st, level, layout,
c21e737b
CA
4925 raiddisks,
4926 chunk?*chunk:0, size,
bf5a934a
DW
4927 dev, freesize,
4928 verbose);
4929 }
4930
8592f29d
N
4931 if (!dev) {
4932 if (st->sb && freesize) {
efb30e7f
DW
4933 /* we are being asked to automatically layout a
4934 * new volume based on the current contents of
4935 * the container. If the the parameters can be
4936 * satisfied reserve_space will record the disks,
4937 * start offset, and size of the volume to be
4938 * created. add_to_super and getinfo_super
4939 * detect when autolayout is in progress.
4940 */
6592ce37
DW
4941 if (!validate_geometry_imsm_orom(st->sb, level, layout,
4942 raiddisks, chunk,
4943 verbose))
4944 return 0;
c21e737b
CA
4945 return reserve_space(st, raiddisks, size,
4946 chunk?*chunk:0, freesize);
8592f29d
N
4947 }
4948 return 1;
4949 }
bf5a934a
DW
4950 if (st->sb) {
4951 /* creating in a given container */
4952 return validate_geometry_imsm_volume(st, level, layout,
4953 raiddisks, chunk, size,
4954 dev, freesize, verbose);
4955 }
4956
bf5a934a
DW
4957 /* This device needs to be a device in an 'imsm' container */
4958 fd = open(dev, O_RDONLY|O_EXCL, 0);
4959 if (fd >= 0) {
4960 if (verbose)
4961 fprintf(stderr,
4962 Name ": Cannot create this array on device %s\n",
4963 dev);
4964 close(fd);
4965 return 0;
4966 }
4967 if (errno != EBUSY || (fd = open(dev, O_RDONLY, 0)) < 0) {
4968 if (verbose)
4969 fprintf(stderr, Name ": Cannot open %s: %s\n",
4970 dev, strerror(errno));
4971 return 0;
4972 }
4973 /* Well, it is in use by someone, maybe an 'imsm' container. */
4974 cfd = open_container(fd);
20cbe8d2 4975 close(fd);
bf5a934a 4976 if (cfd < 0) {
bf5a934a
DW
4977 if (verbose)
4978 fprintf(stderr, Name ": Cannot use %s: It is busy\n",
4979 dev);
4980 return 0;
4981 }
4982 sra = sysfs_read(cfd, 0, GET_VERSION);
bf5a934a 4983 if (sra && sra->array.major_version == -1 &&
20cbe8d2
AW
4984 strcmp(sra->text_version, "imsm") == 0)
4985 is_member = 1;
4986 sysfs_free(sra);
4987 if (is_member) {
bf5a934a
DW
4988 /* This is a member of a imsm container. Load the container
4989 * and try to create a volume
4990 */
4991 struct intel_super *super;
4992
e1902a7b 4993 if (load_super_imsm_all(st, cfd, (void **) &super, NULL) == 0) {
bf5a934a
DW
4994 st->sb = super;
4995 st->container_dev = fd2devnum(cfd);
4996 close(cfd);
4997 return validate_geometry_imsm_volume(st, level, layout,
4998 raiddisks, chunk,
4999 size, dev,
5000 freesize, verbose);
5001 }
20cbe8d2 5002 }
bf5a934a 5003
20cbe8d2
AW
5004 if (verbose)
5005 fprintf(stderr, Name ": failed container membership check\n");
5006
5007 close(cfd);
5008 return 0;
bf5a934a 5009}
0bd16cf2 5010
30f58b22 5011static void default_geometry_imsm(struct supertype *st, int *level, int *layout, int *chunk)
0bd16cf2
DJ
5012{
5013 struct intel_super *super = st->sb;
5014
30f58b22
DW
5015 if (level && *level == UnSet)
5016 *level = LEVEL_CONTAINER;
5017
5018 if (level && layout && *layout == UnSet)
5019 *layout = imsm_level_to_layout(*level);
0bd16cf2 5020
1d54f286
N
5021 if (chunk && (*chunk == UnSet || *chunk == 0) &&
5022 super && super->orom)
30f58b22 5023 *chunk = imsm_orom_default_chunk(super->orom);
0bd16cf2
DJ
5024}
5025
33414a01
DW
5026static void handle_missing(struct intel_super *super, struct imsm_dev *dev);
5027
5028static int kill_subarray_imsm(struct supertype *st)
5029{
5030 /* remove the subarray currently referenced by ->current_vol */
5031 __u8 i;
5032 struct intel_dev **dp;
5033 struct intel_super *super = st->sb;
5034 __u8 current_vol = super->current_vol;
5035 struct imsm_super *mpb = super->anchor;
5036
5037 if (super->current_vol < 0)
5038 return 2;
5039 super->current_vol = -1; /* invalidate subarray cursor */
5040
5041 /* block deletions that would change the uuid of active subarrays
5042 *
5043 * FIXME when immutable ids are available, but note that we'll
5044 * also need to fixup the invalidated/active subarray indexes in
5045 * mdstat
5046 */
5047 for (i = 0; i < mpb->num_raid_devs; i++) {
5048 char subarray[4];
5049
5050 if (i < current_vol)
5051 continue;
5052 sprintf(subarray, "%u", i);
5053 if (is_subarray_active(subarray, st->devname)) {
5054 fprintf(stderr,
5055 Name ": deleting subarray-%d would change the UUID of active subarray-%d, aborting\n",
5056 current_vol, i);
5057
5058 return 2;
5059 }
5060 }
5061
5062 if (st->update_tail) {
5063 struct imsm_update_kill_array *u = malloc(sizeof(*u));
5064
5065 if (!u)
5066 return 2;
5067 u->type = update_kill_array;
5068 u->dev_idx = current_vol;
5069 append_metadata_update(st, u, sizeof(*u));
5070
5071 return 0;
5072 }
5073
5074 for (dp = &super->devlist; *dp;)
5075 if ((*dp)->index == current_vol) {
5076 *dp = (*dp)->next;
5077 } else {
5078 handle_missing(super, (*dp)->dev);
5079 if ((*dp)->index > current_vol)
5080 (*dp)->index--;
5081 dp = &(*dp)->next;
5082 }
5083
5084 /* no more raid devices, all active components are now spares,
5085 * but of course failed are still failed
5086 */
5087 if (--mpb->num_raid_devs == 0) {
5088 struct dl *d;
5089
5090 for (d = super->disks; d; d = d->next)
5091 if (d->index > -2) {
5092 d->index = -1;
5093 d->disk.status = SPARE_DISK;
5094 }
5095 }
5096
5097 super->updates_pending++;
5098
5099 return 0;
5100}
aa534678 5101
a951a4f7 5102static int update_subarray_imsm(struct supertype *st, char *subarray,
fa56eddb 5103 char *update, struct mddev_ident *ident)
aa534678
DW
5104{
5105 /* update the subarray currently referenced by ->current_vol */
5106 struct intel_super *super = st->sb;
5107 struct imsm_super *mpb = super->anchor;
5108
aa534678
DW
5109 if (strcmp(update, "name") == 0) {
5110 char *name = ident->name;
a951a4f7
N
5111 char *ep;
5112 int vol;
aa534678 5113
a951a4f7 5114 if (is_subarray_active(subarray, st->devname)) {
aa534678
DW
5115 fprintf(stderr,
5116 Name ": Unable to update name of active subarray\n");
5117 return 2;
5118 }
5119
5120 if (!check_name(super, name, 0))
5121 return 2;
5122
a951a4f7
N
5123 vol = strtoul(subarray, &ep, 10);
5124 if (*ep != '\0' || vol >= super->anchor->num_raid_devs)
5125 return 2;
5126
aa534678
DW
5127 if (st->update_tail) {
5128 struct imsm_update_rename_array *u = malloc(sizeof(*u));
5129
5130 if (!u)
5131 return 2;
5132 u->type = update_rename_array;
a951a4f7 5133 u->dev_idx = vol;
aa534678
DW
5134 snprintf((char *) u->name, MAX_RAID_SERIAL_LEN, "%s", name);
5135 append_metadata_update(st, u, sizeof(*u));
5136 } else {
5137 struct imsm_dev *dev;
5138 int i;
5139
a951a4f7 5140 dev = get_imsm_dev(super, vol);
aa534678
DW
5141 snprintf((char *) dev->volume, MAX_RAID_SERIAL_LEN, "%s", name);
5142 for (i = 0; i < mpb->num_raid_devs; i++) {
5143 dev = get_imsm_dev(super, i);
5144 handle_missing(super, dev);
5145 }
5146 super->updates_pending++;
5147 }
5148 } else
5149 return 2;
5150
5151 return 0;
5152}
bf5a934a 5153
28bce06f
AK
5154static int is_gen_migration(struct imsm_dev *dev)
5155{
5156 if (!dev->vol.migr_state)
5157 return 0;
5158
5159 if (migr_type(dev) == MIGR_GEN_MIGR)
5160 return 1;
5161
5162 return 0;
5163}
71204a50 5164#endif /* MDASSEMBLE */
28bce06f 5165
1e5c6983
DW
5166static int is_rebuilding(struct imsm_dev *dev)
5167{
5168 struct imsm_map *migr_map;
5169
5170 if (!dev->vol.migr_state)
5171 return 0;
5172
5173 if (migr_type(dev) != MIGR_REBUILD)
5174 return 0;
5175
5176 migr_map = get_imsm_map(dev, 1);
5177
5178 if (migr_map->map_state == IMSM_T_STATE_DEGRADED)
5179 return 1;
5180 else
5181 return 0;
5182}
5183
5184static void update_recovery_start(struct imsm_dev *dev, struct mdinfo *array)
5185{
5186 struct mdinfo *rebuild = NULL;
5187 struct mdinfo *d;
5188 __u32 units;
5189
5190 if (!is_rebuilding(dev))
5191 return;
5192
5193 /* Find the rebuild target, but punt on the dual rebuild case */
5194 for (d = array->devs; d; d = d->next)
5195 if (d->recovery_start == 0) {
5196 if (rebuild)
5197 return;
5198 rebuild = d;
5199 }
5200
4363fd80
DW
5201 if (!rebuild) {
5202 /* (?) none of the disks are marked with
5203 * IMSM_ORD_REBUILD, so assume they are missing and the
5204 * disk_ord_tbl was not correctly updated
5205 */
5206 dprintf("%s: failed to locate out-of-sync disk\n", __func__);
5207 return;
5208 }
5209
1e5c6983
DW
5210 units = __le32_to_cpu(dev->vol.curr_migr_unit);
5211 rebuild->recovery_start = units * blocks_per_migr_unit(dev);
5212}
5213
5214
00bbdbda 5215static struct mdinfo *container_content_imsm(struct supertype *st, char *subarray)
cdddbdbc 5216{
4f5bc454
DW
5217 /* Given a container loaded by load_super_imsm_all,
5218 * extract information about all the arrays into
5219 * an mdinfo tree.
00bbdbda 5220 * If 'subarray' is given, just extract info about that array.
4f5bc454
DW
5221 *
5222 * For each imsm_dev create an mdinfo, fill it in,
5223 * then look for matching devices in super->disks
5224 * and create appropriate device mdinfo.
5225 */
5226 struct intel_super *super = st->sb;
949c47a0 5227 struct imsm_super *mpb = super->anchor;
4f5bc454 5228 struct mdinfo *rest = NULL;
00bbdbda 5229 unsigned int i;
a06d022d 5230 int bbm_errors = 0;
abef11a3
AK
5231 struct dl *d;
5232 int spare_disks = 0;
cdddbdbc 5233
a06d022d
KW
5234 /* check for bad blocks */
5235 if (imsm_bbm_log_size(super->anchor))
5236 bbm_errors = 1;
604b746f 5237
abef11a3
AK
5238 /* count spare devices, not used in maps
5239 */
5240 for (d = super->disks; d; d = d->next)
5241 if (d->index == -1)
5242 spare_disks++;
5243
4f5bc454 5244 for (i = 0; i < mpb->num_raid_devs; i++) {
00bbdbda
N
5245 struct imsm_dev *dev;
5246 struct imsm_map *map;
86e3692b 5247 struct imsm_map *map2;
4f5bc454 5248 struct mdinfo *this;
2db86302 5249 int slot, chunk;
00bbdbda
N
5250 char *ep;
5251
5252 if (subarray &&
5253 (i != strtoul(subarray, &ep, 10) || *ep != '\0'))
5254 continue;
5255
5256 dev = get_imsm_dev(super, i);
5257 map = get_imsm_map(dev, 0);
86e3692b 5258 map2 = get_imsm_map(dev, 1);
4f5bc454 5259
1ce0101c
DW
5260 /* do not publish arrays that are in the middle of an
5261 * unsupported migration
5262 */
5263 if (dev->vol.migr_state &&
28bce06f 5264 (migr_type(dev) == MIGR_STATE_CHANGE)) {
1ce0101c
DW
5265 fprintf(stderr, Name ": cannot assemble volume '%.16s':"
5266 " unsupported migration in progress\n",
5267 dev->volume);
5268 continue;
5269 }
2db86302
LM
5270 /* do not publish arrays that are not support by controller's
5271 * OROM/EFI
5272 */
1ce0101c 5273
2db86302 5274 chunk = __le16_to_cpu(map->blocks_per_strip) >> 1;
7b0bbd0f 5275#ifndef MDASSEMBLE
2db86302
LM
5276 if (!validate_geometry_imsm_orom(super,
5277 get_imsm_raid_level(map), /* RAID level */
5278 imsm_level_to_layout(get_imsm_raid_level(map)),
5279 map->num_members, /* raid disks */
5280 &chunk,
5281 1 /* verbose */)) {
5282 fprintf(stderr, Name ": RAID gemetry validation failed. "
5283 "Cannot proceed with the action(s).\n");
5284 continue;
5285 }
7b0bbd0f 5286#endif /* MDASSEMBLE */
4f5bc454 5287 this = malloc(sizeof(*this));
0fbd635c 5288 if (!this) {
cf1be220 5289 fprintf(stderr, Name ": failed to allocate %zu bytes\n",
0fbd635c
AW
5290 sizeof(*this));
5291 break;
5292 }
4f5bc454
DW
5293 memset(this, 0, sizeof(*this));
5294 this->next = rest;
4f5bc454 5295
301406c9 5296 super->current_vol = i;
a5d85af7 5297 getinfo_super_imsm_volume(st, this, NULL);
4f5bc454 5298 for (slot = 0 ; slot < map->num_members; slot++) {
1e5c6983 5299 unsigned long long recovery_start;
4f5bc454
DW
5300 struct mdinfo *info_d;
5301 struct dl *d;
5302 int idx;
9a1608e5 5303 int skip;
7eef0453 5304 __u32 ord;
4f5bc454 5305
9a1608e5 5306 skip = 0;
98130f40 5307 idx = get_imsm_disk_idx(dev, slot, 0);
196b0d44 5308 ord = get_imsm_ord_tbl_ent(dev, slot, -1);
4f5bc454
DW
5309 for (d = super->disks; d ; d = d->next)
5310 if (d->index == idx)
0fbd635c 5311 break;
4f5bc454 5312
1e5c6983 5313 recovery_start = MaxSector;
4f5bc454 5314 if (d == NULL)
9a1608e5 5315 skip = 1;
25ed7e59 5316 if (d && is_failed(&d->disk))
9a1608e5 5317 skip = 1;
7eef0453 5318 if (ord & IMSM_ORD_REBUILD)
1e5c6983 5319 recovery_start = 0;
9a1608e5
DW
5320
5321 /*
5322 * if we skip some disks the array will be assmebled degraded;
1e5c6983
DW
5323 * reset resync start to avoid a dirty-degraded
5324 * situation when performing the intial sync
9a1608e5
DW
5325 *
5326 * FIXME handle dirty degraded
5327 */
1e5c6983 5328 if ((skip || recovery_start == 0) && !dev->vol.dirty)
b7528a20 5329 this->resync_start = MaxSector;
9a1608e5
DW
5330 if (skip)
5331 continue;
4f5bc454 5332
1e5c6983 5333 info_d = calloc(1, sizeof(*info_d));
9a1608e5
DW
5334 if (!info_d) {
5335 fprintf(stderr, Name ": failed to allocate disk"
1ce0101c 5336 " for volume %.16s\n", dev->volume);
1e5c6983
DW
5337 info_d = this->devs;
5338 while (info_d) {
5339 struct mdinfo *d = info_d->next;
5340
5341 free(info_d);
5342 info_d = d;
5343 }
9a1608e5
DW
5344 free(this);
5345 this = rest;
5346 break;
5347 }
4f5bc454
DW
5348 info_d->next = this->devs;
5349 this->devs = info_d;
5350
4f5bc454
DW
5351 info_d->disk.number = d->index;
5352 info_d->disk.major = d->major;
5353 info_d->disk.minor = d->minor;
5354 info_d->disk.raid_disk = slot;
1e5c6983 5355 info_d->recovery_start = recovery_start;
86e3692b
AK
5356 if (map2) {
5357 if (slot < map2->num_members)
5358 info_d->disk.state = (1 << MD_DISK_ACTIVE);
04c3c514
AK
5359 else
5360 this->array.spare_disks++;
86e3692b
AK
5361 } else {
5362 if (slot < map->num_members)
5363 info_d->disk.state = (1 << MD_DISK_ACTIVE);
04c3c514
AK
5364 else
5365 this->array.spare_disks++;
86e3692b 5366 }
1e5c6983
DW
5367 if (info_d->recovery_start == MaxSector)
5368 this->array.working_disks++;
4f5bc454
DW
5369
5370 info_d->events = __le32_to_cpu(mpb->generation_num);
5371 info_d->data_offset = __le32_to_cpu(map->pba_of_lba0);
5372 info_d->component_size = __le32_to_cpu(map->blocks_per_member);
4f5bc454 5373 }
1e5c6983
DW
5374 /* now that the disk list is up-to-date fixup recovery_start */
5375 update_recovery_start(dev, this);
abef11a3 5376 this->array.spare_disks += spare_disks;
9a1608e5 5377 rest = this;
4f5bc454
DW
5378 }
5379
a06d022d
KW
5380 /* if array has bad blocks, set suitable bit in array status */
5381 if (bbm_errors)
5382 rest->array.state |= (1<<MD_SB_BBM_ERRORS);
5383
4f5bc454 5384 return rest;
cdddbdbc
DW
5385}
5386
845dea95 5387
fb49eef2 5388static __u8 imsm_check_degraded(struct intel_super *super, struct imsm_dev *dev, int failed)
c2a1e7da 5389{
a965f303 5390 struct imsm_map *map = get_imsm_map(dev, 0);
c2a1e7da
DW
5391
5392 if (!failed)
3393c6af
DW
5393 return map->map_state == IMSM_T_STATE_UNINITIALIZED ?
5394 IMSM_T_STATE_UNINITIALIZED : IMSM_T_STATE_NORMAL;
c2a1e7da
DW
5395
5396 switch (get_imsm_raid_level(map)) {
5397 case 0:
5398 return IMSM_T_STATE_FAILED;
5399 break;
5400 case 1:
5401 if (failed < map->num_members)
5402 return IMSM_T_STATE_DEGRADED;
5403 else
5404 return IMSM_T_STATE_FAILED;
5405 break;
5406 case 10:
5407 {
5408 /**
c92a2527
DW
5409 * check to see if any mirrors have failed, otherwise we
5410 * are degraded. Even numbered slots are mirrored on
5411 * slot+1
c2a1e7da 5412 */
c2a1e7da 5413 int i;
d9b420a5
N
5414 /* gcc -Os complains that this is unused */
5415 int insync = insync;
c2a1e7da
DW
5416
5417 for (i = 0; i < map->num_members; i++) {
98130f40 5418 __u32 ord = get_imsm_ord_tbl_ent(dev, i, -1);
c92a2527
DW
5419 int idx = ord_to_idx(ord);
5420 struct imsm_disk *disk;
c2a1e7da 5421
c92a2527
DW
5422 /* reset the potential in-sync count on even-numbered
5423 * slots. num_copies is always 2 for imsm raid10
5424 */
5425 if ((i & 1) == 0)
5426 insync = 2;
c2a1e7da 5427
c92a2527 5428 disk = get_imsm_disk(super, idx);
25ed7e59 5429 if (!disk || is_failed(disk) || ord & IMSM_ORD_REBUILD)
c92a2527 5430 insync--;
c2a1e7da 5431
c92a2527
DW
5432 /* no in-sync disks left in this mirror the
5433 * array has failed
5434 */
5435 if (insync == 0)
5436 return IMSM_T_STATE_FAILED;
c2a1e7da
DW
5437 }
5438
5439 return IMSM_T_STATE_DEGRADED;
5440 }
5441 case 5:
5442 if (failed < 2)
5443 return IMSM_T_STATE_DEGRADED;
5444 else
5445 return IMSM_T_STATE_FAILED;
5446 break;
5447 default:
5448 break;
5449 }
5450
5451 return map->map_state;
5452}
5453
ff077194 5454static int imsm_count_failed(struct intel_super *super, struct imsm_dev *dev)
c2a1e7da
DW
5455{
5456 int i;
5457 int failed = 0;
5458 struct imsm_disk *disk;
ff077194 5459 struct imsm_map *map = get_imsm_map(dev, 0);
0556e1a2
DW
5460 struct imsm_map *prev = get_imsm_map(dev, dev->vol.migr_state);
5461 __u32 ord;
5462 int idx;
c2a1e7da 5463
0556e1a2
DW
5464 /* at the beginning of migration we set IMSM_ORD_REBUILD on
5465 * disks that are being rebuilt. New failures are recorded to
5466 * map[0]. So we look through all the disks we started with and
5467 * see if any failures are still present, or if any new ones
5468 * have arrived
5469 *
5470 * FIXME add support for online capacity expansion and
5471 * raid-level-migration
5472 */
5473 for (i = 0; i < prev->num_members; i++) {
5474 ord = __le32_to_cpu(prev->disk_ord_tbl[i]);
5475 ord |= __le32_to_cpu(map->disk_ord_tbl[i]);
5476 idx = ord_to_idx(ord);
c2a1e7da 5477
949c47a0 5478 disk = get_imsm_disk(super, idx);
25ed7e59 5479 if (!disk || is_failed(disk) || ord & IMSM_ORD_REBUILD)
fcb84475 5480 failed++;
c2a1e7da
DW
5481 }
5482
5483 return failed;
845dea95
NB
5484}
5485
97b4d0e9
DW
5486#ifndef MDASSEMBLE
5487static int imsm_open_new(struct supertype *c, struct active_array *a,
5488 char *inst)
5489{
5490 struct intel_super *super = c->sb;
5491 struct imsm_super *mpb = super->anchor;
5492
5493 if (atoi(inst) >= mpb->num_raid_devs) {
5494 fprintf(stderr, "%s: subarry index %d, out of range\n",
5495 __func__, atoi(inst));
5496 return -ENODEV;
5497 }
5498
5499 dprintf("imsm: open_new %s\n", inst);
5500 a->info.container_member = atoi(inst);
5501 return 0;
5502}
5503
0c046afd
DW
5504static int is_resyncing(struct imsm_dev *dev)
5505{
5506 struct imsm_map *migr_map;
5507
5508 if (!dev->vol.migr_state)
5509 return 0;
5510
1484e727
DW
5511 if (migr_type(dev) == MIGR_INIT ||
5512 migr_type(dev) == MIGR_REPAIR)
0c046afd
DW
5513 return 1;
5514
4c9bc37b
AK
5515 if (migr_type(dev) == MIGR_GEN_MIGR)
5516 return 0;
5517
0c046afd
DW
5518 migr_map = get_imsm_map(dev, 1);
5519
4c9bc37b
AK
5520 if ((migr_map->map_state == IMSM_T_STATE_NORMAL) &&
5521 (dev->vol.migr_type != MIGR_GEN_MIGR))
0c046afd
DW
5522 return 1;
5523 else
5524 return 0;
5525}
5526
0556e1a2
DW
5527/* return true if we recorded new information */
5528static int mark_failure(struct imsm_dev *dev, struct imsm_disk *disk, int idx)
47ee5a45 5529{
0556e1a2
DW
5530 __u32 ord;
5531 int slot;
5532 struct imsm_map *map;
5533
5534 /* new failures are always set in map[0] */
5535 map = get_imsm_map(dev, 0);
5536
5537 slot = get_imsm_disk_slot(map, idx);
5538 if (slot < 0)
5539 return 0;
5540
5541 ord = __le32_to_cpu(map->disk_ord_tbl[slot]);
25ed7e59 5542 if (is_failed(disk) && (ord & IMSM_ORD_REBUILD))
0556e1a2
DW
5543 return 0;
5544
f2f27e63 5545 disk->status |= FAILED_DISK;
0556e1a2 5546 set_imsm_ord_tbl_ent(map, slot, idx | IMSM_ORD_REBUILD);
f21e18ca 5547 if (map->failed_disk_num == 0xff)
0556e1a2
DW
5548 map->failed_disk_num = slot;
5549 return 1;
5550}
5551
5552static void mark_missing(struct imsm_dev *dev, struct imsm_disk *disk, int idx)
5553{
5554 mark_failure(dev, disk, idx);
5555
5556 if (disk->scsi_id == __cpu_to_le32(~(__u32)0))
5557 return;
5558
47ee5a45
DW
5559 disk->scsi_id = __cpu_to_le32(~(__u32)0);
5560 memmove(&disk->serial[0], &disk->serial[1], MAX_RAID_SERIAL_LEN - 1);
5561}
5562
33414a01
DW
5563static void handle_missing(struct intel_super *super, struct imsm_dev *dev)
5564{
5565 __u8 map_state;
5566 struct dl *dl;
5567 int failed;
5568
5569 if (!super->missing)
5570 return;
5571 failed = imsm_count_failed(super, dev);
5572 map_state = imsm_check_degraded(super, dev, failed);
5573
5574 dprintf("imsm: mark missing\n");
5575 end_migration(dev, map_state);
5576 for (dl = super->missing; dl; dl = dl->next)
5577 mark_missing(dev, &dl->disk, dl->index);
5578 super->updates_pending++;
5579}
5580
70bdf0dc
AK
5581static unsigned long long imsm_set_array_size(struct imsm_dev *dev)
5582{
5583 int used_disks = imsm_num_data_members(dev, 0);
5584 unsigned long long array_blocks;
5585 struct imsm_map *map;
5586
5587 if (used_disks == 0) {
5588 /* when problems occures
5589 * return current array_blocks value
5590 */
5591 array_blocks = __le32_to_cpu(dev->size_high);
5592 array_blocks = array_blocks << 32;
5593 array_blocks += __le32_to_cpu(dev->size_low);
5594
5595 return array_blocks;
5596 }
5597
5598 /* set array size in metadata
5599 */
5600 map = get_imsm_map(dev, 0);
5601 array_blocks = map->blocks_per_member * used_disks;
5602
5603 /* round array size down to closest MB
5604 */
5605 array_blocks = (array_blocks >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT;
5606 dev->size_low = __cpu_to_le32((__u32)array_blocks);
5607 dev->size_high = __cpu_to_le32((__u32)(array_blocks >> 32));
5608
5609 return array_blocks;
5610}
5611
28bce06f
AK
5612static void imsm_set_disk(struct active_array *a, int n, int state);
5613
0e2d1a4e
AK
5614static void imsm_progress_container_reshape(struct intel_super *super)
5615{
5616 /* if no device has a migr_state, but some device has a
5617 * different number of members than the previous device, start
5618 * changing the number of devices in this device to match
5619 * previous.
5620 */
5621 struct imsm_super *mpb = super->anchor;
5622 int prev_disks = -1;
5623 int i;
1dfaa380 5624 int copy_map_size;
0e2d1a4e
AK
5625
5626 for (i = 0; i < mpb->num_raid_devs; i++) {
5627 struct imsm_dev *dev = get_imsm_dev(super, i);
5628 struct imsm_map *map = get_imsm_map(dev, 0);
5629 struct imsm_map *map2;
5630 int prev_num_members;
0e2d1a4e
AK
5631
5632 if (dev->vol.migr_state)
5633 return;
5634
5635 if (prev_disks == -1)
5636 prev_disks = map->num_members;
5637 if (prev_disks == map->num_members)
5638 continue;
5639
5640 /* OK, this array needs to enter reshape mode.
5641 * i.e it needs a migr_state
5642 */
5643
1dfaa380 5644 copy_map_size = sizeof_imsm_map(map);
0e2d1a4e
AK
5645 prev_num_members = map->num_members;
5646 map->num_members = prev_disks;
5647 dev->vol.migr_state = 1;
5648 dev->vol.curr_migr_unit = 0;
5649 dev->vol.migr_type = MIGR_GEN_MIGR;
5650 for (i = prev_num_members;
5651 i < map->num_members; i++)
5652 set_imsm_ord_tbl_ent(map, i, i);
5653 map2 = get_imsm_map(dev, 1);
5654 /* Copy the current map */
1dfaa380 5655 memcpy(map2, map, copy_map_size);
0e2d1a4e
AK
5656 map2->num_members = prev_num_members;
5657
70bdf0dc 5658 imsm_set_array_size(dev);
0e2d1a4e
AK
5659 super->updates_pending++;
5660 }
5661}
5662
aad6f216 5663/* Handle dirty -> clean transititions, resync and reshape. Degraded and rebuild
0c046afd
DW
5664 * states are handled in imsm_set_disk() with one exception, when a
5665 * resync is stopped due to a new failure this routine will set the
5666 * 'degraded' state for the array.
5667 */
01f157d7 5668static int imsm_set_array_state(struct active_array *a, int consistent)
a862209d
DW
5669{
5670 int inst = a->info.container_member;
5671 struct intel_super *super = a->container->sb;
949c47a0 5672 struct imsm_dev *dev = get_imsm_dev(super, inst);
a965f303 5673 struct imsm_map *map = get_imsm_map(dev, 0);
0c046afd
DW
5674 int failed = imsm_count_failed(super, dev);
5675 __u8 map_state = imsm_check_degraded(super, dev, failed);
1e5c6983 5676 __u32 blocks_per_unit;
a862209d 5677
1af97990
AK
5678 if (dev->vol.migr_state &&
5679 dev->vol.migr_type == MIGR_GEN_MIGR) {
5680 /* array state change is blocked due to reshape action
aad6f216
N
5681 * We might need to
5682 * - abort the reshape (if last_checkpoint is 0 and action!= reshape)
5683 * - finish the reshape (if last_checkpoint is big and action != reshape)
5684 * - update curr_migr_unit
1af97990 5685 */
aad6f216
N
5686 if (a->curr_action == reshape) {
5687 /* still reshaping, maybe update curr_migr_unit */
633b5610 5688 goto mark_checkpoint;
aad6f216
N
5689 } else {
5690 if (a->last_checkpoint == 0 && a->prev_action == reshape) {
5691 /* for some reason we aborted the reshape.
5692 * Better clean up
5693 */
5694 struct imsm_map *map2 = get_imsm_map(dev, 1);
5695 dev->vol.migr_state = 0;
5696 dev->vol.migr_type = 0;
5697 dev->vol.curr_migr_unit = 0;
5698 memcpy(map, map2, sizeof_imsm_map(map2));
5699 super->updates_pending++;
5700 }
5701 if (a->last_checkpoint >= a->info.component_size) {
5702 unsigned long long array_blocks;
5703 int used_disks;
e154ced3 5704 struct mdinfo *mdi;
aad6f216 5705
9653001d 5706 used_disks = imsm_num_data_members(dev, 0);
d55adef9
AK
5707 if (used_disks > 0) {
5708 array_blocks =
5709 map->blocks_per_member *
5710 used_disks;
5711 /* round array size down to closest MB
5712 */
5713 array_blocks = (array_blocks
5714 >> SECT_PER_MB_SHIFT)
5715 << SECT_PER_MB_SHIFT;
d55adef9
AK
5716 a->info.custom_array_size = array_blocks;
5717 /* encourage manager to update array
5718 * size
5719 */
e154ced3 5720
d55adef9 5721 a->check_reshape = 1;
633b5610 5722 }
e154ced3
AK
5723 /* finalize online capacity expansion/reshape */
5724 for (mdi = a->info.devs; mdi; mdi = mdi->next)
5725 imsm_set_disk(a,
5726 mdi->disk.raid_disk,
5727 mdi->curr_state);
5728
0e2d1a4e 5729 imsm_progress_container_reshape(super);
e154ced3 5730 }
aad6f216 5731 }
1af97990
AK
5732 }
5733
47ee5a45 5734 /* before we activate this array handle any missing disks */
33414a01
DW
5735 if (consistent == 2)
5736 handle_missing(super, dev);
1e5c6983 5737
0c046afd 5738 if (consistent == 2 &&
b7941fd6 5739 (!is_resync_complete(&a->info) ||
0c046afd
DW
5740 map_state != IMSM_T_STATE_NORMAL ||
5741 dev->vol.migr_state))
01f157d7 5742 consistent = 0;
272906ef 5743
b7941fd6 5744 if (is_resync_complete(&a->info)) {
0c046afd 5745 /* complete intialization / resync,
0556e1a2
DW
5746 * recovery and interrupted recovery is completed in
5747 * ->set_disk
0c046afd
DW
5748 */
5749 if (is_resyncing(dev)) {
5750 dprintf("imsm: mark resync done\n");
f8f603f1 5751 end_migration(dev, map_state);
115c3803 5752 super->updates_pending++;
484240d8 5753 a->last_checkpoint = 0;
115c3803 5754 }
0c046afd
DW
5755 } else if (!is_resyncing(dev) && !failed) {
5756 /* mark the start of the init process if nothing is failed */
b7941fd6 5757 dprintf("imsm: mark resync start\n");
1484e727 5758 if (map->map_state == IMSM_T_STATE_UNINITIALIZED)
8e59f3d8 5759 migrate(dev, super, IMSM_T_STATE_NORMAL, MIGR_INIT);
1484e727 5760 else
8e59f3d8 5761 migrate(dev, super, IMSM_T_STATE_NORMAL, MIGR_REPAIR);
3393c6af 5762 super->updates_pending++;
115c3803 5763 }
a862209d 5764
633b5610 5765mark_checkpoint:
1e5c6983
DW
5766 /* check if we can update curr_migr_unit from resync_start, recovery_start */
5767 blocks_per_unit = blocks_per_migr_unit(dev);
4f0a7acc 5768 if (blocks_per_unit) {
1e5c6983
DW
5769 __u32 units32;
5770 __u64 units;
5771
4f0a7acc 5772 units = a->last_checkpoint / blocks_per_unit;
1e5c6983
DW
5773 units32 = units;
5774
5775 /* check that we did not overflow 32-bits, and that
5776 * curr_migr_unit needs updating
5777 */
5778 if (units32 == units &&
bfd80a56 5779 units32 != 0 &&
1e5c6983
DW
5780 __le32_to_cpu(dev->vol.curr_migr_unit) != units32) {
5781 dprintf("imsm: mark checkpoint (%u)\n", units32);
5782 dev->vol.curr_migr_unit = __cpu_to_le32(units32);
5783 super->updates_pending++;
5784 }
5785 }
f8f603f1 5786
3393c6af 5787 /* mark dirty / clean */
0c046afd 5788 if (dev->vol.dirty != !consistent) {
b7941fd6 5789 dprintf("imsm: mark '%s'\n", consistent ? "clean" : "dirty");
0c046afd
DW
5790 if (consistent)
5791 dev->vol.dirty = 0;
5792 else
5793 dev->vol.dirty = 1;
a862209d
DW
5794 super->updates_pending++;
5795 }
28bce06f 5796
01f157d7 5797 return consistent;
a862209d
DW
5798}
5799
8d45d196 5800static void imsm_set_disk(struct active_array *a, int n, int state)
845dea95 5801{
8d45d196
DW
5802 int inst = a->info.container_member;
5803 struct intel_super *super = a->container->sb;
949c47a0 5804 struct imsm_dev *dev = get_imsm_dev(super, inst);
a965f303 5805 struct imsm_map *map = get_imsm_map(dev, 0);
8d45d196 5806 struct imsm_disk *disk;
0c046afd 5807 int failed;
b10b37b8 5808 __u32 ord;
0c046afd 5809 __u8 map_state;
8d45d196
DW
5810
5811 if (n > map->num_members)
5812 fprintf(stderr, "imsm: set_disk %d out of range 0..%d\n",
5813 n, map->num_members - 1);
5814
5815 if (n < 0)
5816 return;
5817
4e6e574a 5818 dprintf("imsm: set_disk %d:%x\n", n, state);
8d45d196 5819
98130f40 5820 ord = get_imsm_ord_tbl_ent(dev, n, -1);
b10b37b8 5821 disk = get_imsm_disk(super, ord_to_idx(ord));
8d45d196 5822
5802a811 5823 /* check for new failures */
0556e1a2
DW
5824 if (state & DS_FAULTY) {
5825 if (mark_failure(dev, disk, ord_to_idx(ord)))
5826 super->updates_pending++;
8d45d196 5827 }
47ee5a45 5828
19859edc 5829 /* check if in_sync */
0556e1a2 5830 if (state & DS_INSYNC && ord & IMSM_ORD_REBUILD && is_rebuilding(dev)) {
b10b37b8
DW
5831 struct imsm_map *migr_map = get_imsm_map(dev, 1);
5832
5833 set_imsm_ord_tbl_ent(migr_map, n, ord_to_idx(ord));
19859edc
DW
5834 super->updates_pending++;
5835 }
8d45d196 5836
0c046afd
DW
5837 failed = imsm_count_failed(super, dev);
5838 map_state = imsm_check_degraded(super, dev, failed);
5802a811 5839
0c046afd
DW
5840 /* check if recovery complete, newly degraded, or failed */
5841 if (map_state == IMSM_T_STATE_NORMAL && is_rebuilding(dev)) {
f8f603f1 5842 end_migration(dev, map_state);
0556e1a2
DW
5843 map = get_imsm_map(dev, 0);
5844 map->failed_disk_num = ~0;
0c046afd 5845 super->updates_pending++;
484240d8 5846 a->last_checkpoint = 0;
0c046afd
DW
5847 } else if (map_state == IMSM_T_STATE_DEGRADED &&
5848 map->map_state != map_state &&
5849 !dev->vol.migr_state) {
5850 dprintf("imsm: mark degraded\n");
5851 map->map_state = map_state;
5852 super->updates_pending++;
484240d8 5853 a->last_checkpoint = 0;
0c046afd
DW
5854 } else if (map_state == IMSM_T_STATE_FAILED &&
5855 map->map_state != map_state) {
5856 dprintf("imsm: mark failed\n");
f8f603f1 5857 end_migration(dev, map_state);
0c046afd 5858 super->updates_pending++;
484240d8 5859 a->last_checkpoint = 0;
28bce06f
AK
5860 } else if (is_gen_migration(dev)) {
5861 dprintf("imsm: Detected General Migration in state: ");
5862 if (map_state == IMSM_T_STATE_NORMAL) {
5863 end_migration(dev, map_state);
5864 map = get_imsm_map(dev, 0);
5865 map->failed_disk_num = ~0;
5866 dprintf("normal\n");
5867 } else {
5868 if (map_state == IMSM_T_STATE_DEGRADED) {
5869 printf("degraded\n");
5870 end_migration(dev, map_state);
5871 } else {
5872 dprintf("failed\n");
5873 }
5874 map->map_state = map_state;
5875 }
5876 super->updates_pending++;
5802a811 5877 }
845dea95
NB
5878}
5879
f796af5d 5880static int store_imsm_mpb(int fd, struct imsm_super *mpb)
c2a1e7da 5881{
f796af5d 5882 void *buf = mpb;
c2a1e7da
DW
5883 __u32 mpb_size = __le32_to_cpu(mpb->mpb_size);
5884 unsigned long long dsize;
5885 unsigned long long sectors;
5886
5887 get_dev_size(fd, NULL, &dsize);
5888
272f648f
DW
5889 if (mpb_size > 512) {
5890 /* -1 to account for anchor */
5891 sectors = mpb_sectors(mpb) - 1;
c2a1e7da 5892
272f648f
DW
5893 /* write the extended mpb to the sectors preceeding the anchor */
5894 if (lseek64(fd, dsize - (512 * (2 + sectors)), SEEK_SET) < 0)
5895 return 1;
c2a1e7da 5896
f21e18ca
N
5897 if ((unsigned long long)write(fd, buf + 512, 512 * sectors)
5898 != 512 * sectors)
272f648f
DW
5899 return 1;
5900 }
c2a1e7da 5901
272f648f
DW
5902 /* first block is stored on second to last sector of the disk */
5903 if (lseek64(fd, dsize - (512 * 2), SEEK_SET) < 0)
c2a1e7da
DW
5904 return 1;
5905
f796af5d 5906 if (write(fd, buf, 512) != 512)
c2a1e7da
DW
5907 return 1;
5908
c2a1e7da
DW
5909 return 0;
5910}
5911
2e735d19 5912static void imsm_sync_metadata(struct supertype *container)
845dea95 5913{
2e735d19 5914 struct intel_super *super = container->sb;
c2a1e7da 5915
1a64be56 5916 dprintf("sync metadata: %d\n", super->updates_pending);
c2a1e7da
DW
5917 if (!super->updates_pending)
5918 return;
5919
36988a3d 5920 write_super_imsm(container, 0);
c2a1e7da
DW
5921
5922 super->updates_pending = 0;
845dea95
NB
5923}
5924
272906ef
DW
5925static struct dl *imsm_readd(struct intel_super *super, int idx, struct active_array *a)
5926{
5927 struct imsm_dev *dev = get_imsm_dev(super, a->info.container_member);
98130f40 5928 int i = get_imsm_disk_idx(dev, idx, -1);
272906ef
DW
5929 struct dl *dl;
5930
5931 for (dl = super->disks; dl; dl = dl->next)
5932 if (dl->index == i)
5933 break;
5934
25ed7e59 5935 if (dl && is_failed(&dl->disk))
272906ef
DW
5936 dl = NULL;
5937
5938 if (dl)
5939 dprintf("%s: found %x:%x\n", __func__, dl->major, dl->minor);
5940
5941 return dl;
5942}
5943
a20d2ba5 5944static struct dl *imsm_add_spare(struct intel_super *super, int slot,
8ba77d32
AK
5945 struct active_array *a, int activate_new,
5946 struct mdinfo *additional_test_list)
272906ef
DW
5947{
5948 struct imsm_dev *dev = get_imsm_dev(super, a->info.container_member);
98130f40 5949 int idx = get_imsm_disk_idx(dev, slot, -1);
a20d2ba5
DW
5950 struct imsm_super *mpb = super->anchor;
5951 struct imsm_map *map;
272906ef
DW
5952 unsigned long long pos;
5953 struct mdinfo *d;
5954 struct extent *ex;
a20d2ba5 5955 int i, j;
272906ef 5956 int found;
569cc43f
DW
5957 __u32 array_start = 0;
5958 __u32 array_end = 0;
272906ef 5959 struct dl *dl;
6c932028 5960 struct mdinfo *test_list;
272906ef
DW
5961
5962 for (dl = super->disks; dl; dl = dl->next) {
5963 /* If in this array, skip */
5964 for (d = a->info.devs ; d ; d = d->next)
e553d2a4
DW
5965 if (d->state_fd >= 0 &&
5966 d->disk.major == dl->major &&
272906ef 5967 d->disk.minor == dl->minor) {
8ba77d32
AK
5968 dprintf("%x:%x already in array\n",
5969 dl->major, dl->minor);
272906ef
DW
5970 break;
5971 }
5972 if (d)
5973 continue;
6c932028
AK
5974 test_list = additional_test_list;
5975 while (test_list) {
5976 if (test_list->disk.major == dl->major &&
5977 test_list->disk.minor == dl->minor) {
8ba77d32
AK
5978 dprintf("%x:%x already in additional test list\n",
5979 dl->major, dl->minor);
5980 break;
5981 }
6c932028 5982 test_list = test_list->next;
8ba77d32 5983 }
6c932028 5984 if (test_list)
8ba77d32 5985 continue;
272906ef 5986
e553d2a4 5987 /* skip in use or failed drives */
25ed7e59 5988 if (is_failed(&dl->disk) || idx == dl->index ||
df474657
DW
5989 dl->index == -2) {
5990 dprintf("%x:%x status (failed: %d index: %d)\n",
25ed7e59 5991 dl->major, dl->minor, is_failed(&dl->disk), idx);
9a1608e5
DW
5992 continue;
5993 }
5994
a20d2ba5
DW
5995 /* skip pure spares when we are looking for partially
5996 * assimilated drives
5997 */
5998 if (dl->index == -1 && !activate_new)
5999 continue;
6000
272906ef 6001 /* Does this unused device have the requisite free space?
a20d2ba5 6002 * It needs to be able to cover all member volumes
272906ef
DW
6003 */
6004 ex = get_extents(super, dl);
6005 if (!ex) {
6006 dprintf("cannot get extents\n");
6007 continue;
6008 }
a20d2ba5
DW
6009 for (i = 0; i < mpb->num_raid_devs; i++) {
6010 dev = get_imsm_dev(super, i);
6011 map = get_imsm_map(dev, 0);
272906ef 6012
a20d2ba5
DW
6013 /* check if this disk is already a member of
6014 * this array
272906ef 6015 */
620b1713 6016 if (get_imsm_disk_slot(map, dl->index) >= 0)
a20d2ba5
DW
6017 continue;
6018
6019 found = 0;
6020 j = 0;
6021 pos = 0;
6022 array_start = __le32_to_cpu(map->pba_of_lba0);
329c8278
DW
6023 array_end = array_start +
6024 __le32_to_cpu(map->blocks_per_member) - 1;
a20d2ba5
DW
6025
6026 do {
6027 /* check that we can start at pba_of_lba0 with
6028 * blocks_per_member of space
6029 */
329c8278 6030 if (array_start >= pos && array_end < ex[j].start) {
a20d2ba5
DW
6031 found = 1;
6032 break;
6033 }
6034 pos = ex[j].start + ex[j].size;
6035 j++;
6036 } while (ex[j-1].size);
6037
6038 if (!found)
272906ef 6039 break;
a20d2ba5 6040 }
272906ef
DW
6041
6042 free(ex);
a20d2ba5 6043 if (i < mpb->num_raid_devs) {
329c8278
DW
6044 dprintf("%x:%x does not have %u to %u available\n",
6045 dl->major, dl->minor, array_start, array_end);
272906ef
DW
6046 /* No room */
6047 continue;
a20d2ba5
DW
6048 }
6049 return dl;
272906ef
DW
6050 }
6051
6052 return dl;
6053}
6054
95d07a2c
LM
6055
6056static int imsm_rebuild_allowed(struct supertype *cont, int dev_idx, int failed)
6057{
6058 struct imsm_dev *dev2;
6059 struct imsm_map *map;
6060 struct dl *idisk;
6061 int slot;
6062 int idx;
6063 __u8 state;
6064
6065 dev2 = get_imsm_dev(cont->sb, dev_idx);
6066 if (dev2) {
6067 state = imsm_check_degraded(cont->sb, dev2, failed);
6068 if (state == IMSM_T_STATE_FAILED) {
6069 map = get_imsm_map(dev2, 0);
6070 if (!map)
6071 return 1;
6072 for (slot = 0; slot < map->num_members; slot++) {
6073 /*
6074 * Check if failed disks are deleted from intel
6075 * disk list or are marked to be deleted
6076 */
98130f40 6077 idx = get_imsm_disk_idx(dev2, slot, -1);
95d07a2c
LM
6078 idisk = get_imsm_dl_disk(cont->sb, idx);
6079 /*
6080 * Do not rebuild the array if failed disks
6081 * from failed sub-array are not removed from
6082 * container.
6083 */
6084 if (idisk &&
6085 is_failed(&idisk->disk) &&
6086 (idisk->action != DISK_REMOVE))
6087 return 0;
6088 }
6089 }
6090 }
6091 return 1;
6092}
6093
88758e9d
DW
6094static struct mdinfo *imsm_activate_spare(struct active_array *a,
6095 struct metadata_update **updates)
6096{
6097 /**
d23fe947
DW
6098 * Find a device with unused free space and use it to replace a
6099 * failed/vacant region in an array. We replace failed regions one a
6100 * array at a time. The result is that a new spare disk will be added
6101 * to the first failed array and after the monitor has finished
6102 * propagating failures the remainder will be consumed.
88758e9d 6103 *
d23fe947
DW
6104 * FIXME add a capability for mdmon to request spares from another
6105 * container.
88758e9d
DW
6106 */
6107
6108 struct intel_super *super = a->container->sb;
88758e9d 6109 int inst = a->info.container_member;
949c47a0 6110 struct imsm_dev *dev = get_imsm_dev(super, inst);
a965f303 6111 struct imsm_map *map = get_imsm_map(dev, 0);
88758e9d
DW
6112 int failed = a->info.array.raid_disks;
6113 struct mdinfo *rv = NULL;
6114 struct mdinfo *d;
6115 struct mdinfo *di;
6116 struct metadata_update *mu;
6117 struct dl *dl;
6118 struct imsm_update_activate_spare *u;
6119 int num_spares = 0;
6120 int i;
95d07a2c 6121 int allowed;
88758e9d
DW
6122
6123 for (d = a->info.devs ; d ; d = d->next) {
6124 if ((d->curr_state & DS_FAULTY) &&
6125 d->state_fd >= 0)
6126 /* wait for Removal to happen */
6127 return NULL;
6128 if (d->state_fd >= 0)
6129 failed--;
6130 }
6131
6132 dprintf("imsm: activate spare: inst=%d failed=%d (%d) level=%d\n",
6133 inst, failed, a->info.array.raid_disks, a->info.array.level);
1af97990
AK
6134
6135 if (dev->vol.migr_state &&
6136 dev->vol.migr_type == MIGR_GEN_MIGR)
6137 /* No repair during migration */
6138 return NULL;
6139
89c67882
AK
6140 if (a->info.array.level == 4)
6141 /* No repair for takeovered array
6142 * imsm doesn't support raid4
6143 */
6144 return NULL;
6145
fb49eef2 6146 if (imsm_check_degraded(super, dev, failed) != IMSM_T_STATE_DEGRADED)
88758e9d
DW
6147 return NULL;
6148
95d07a2c
LM
6149 /*
6150 * If there are any failed disks check state of the other volume.
6151 * Block rebuild if the another one is failed until failed disks
6152 * are removed from container.
6153 */
6154 if (failed) {
6155 dprintf("found failed disks in %s, check if there another"
6156 "failed sub-array.\n",
6157 dev->volume);
6158 /* check if states of the other volumes allow for rebuild */
6159 for (i = 0; i < super->anchor->num_raid_devs; i++) {
6160 if (i != inst) {
6161 allowed = imsm_rebuild_allowed(a->container,
6162 i, failed);
6163 if (!allowed)
6164 return NULL;
6165 }
6166 }
6167 }
6168
88758e9d 6169 /* For each slot, if it is not working, find a spare */
88758e9d
DW
6170 for (i = 0; i < a->info.array.raid_disks; i++) {
6171 for (d = a->info.devs ; d ; d = d->next)
6172 if (d->disk.raid_disk == i)
6173 break;
6174 dprintf("found %d: %p %x\n", i, d, d?d->curr_state:0);
6175 if (d && (d->state_fd >= 0))
6176 continue;
6177
272906ef 6178 /*
a20d2ba5
DW
6179 * OK, this device needs recovery. Try to re-add the
6180 * previous occupant of this slot, if this fails see if
6181 * we can continue the assimilation of a spare that was
6182 * partially assimilated, finally try to activate a new
6183 * spare.
272906ef
DW
6184 */
6185 dl = imsm_readd(super, i, a);
6186 if (!dl)
8ba77d32 6187 dl = imsm_add_spare(super, i, a, 0, NULL);
a20d2ba5 6188 if (!dl)
8ba77d32 6189 dl = imsm_add_spare(super, i, a, 1, NULL);
272906ef
DW
6190 if (!dl)
6191 continue;
6192
6193 /* found a usable disk with enough space */
6194 di = malloc(sizeof(*di));
79244939
DW
6195 if (!di)
6196 continue;
272906ef
DW
6197 memset(di, 0, sizeof(*di));
6198
6199 /* dl->index will be -1 in the case we are activating a
6200 * pristine spare. imsm_process_update() will create a
6201 * new index in this case. Once a disk is found to be
6202 * failed in all member arrays it is kicked from the
6203 * metadata
6204 */
6205 di->disk.number = dl->index;
d23fe947 6206
272906ef
DW
6207 /* (ab)use di->devs to store a pointer to the device
6208 * we chose
6209 */
6210 di->devs = (struct mdinfo *) dl;
6211
6212 di->disk.raid_disk = i;
6213 di->disk.major = dl->major;
6214 di->disk.minor = dl->minor;
6215 di->disk.state = 0;
d23534e4 6216 di->recovery_start = 0;
272906ef
DW
6217 di->data_offset = __le32_to_cpu(map->pba_of_lba0);
6218 di->component_size = a->info.component_size;
6219 di->container_member = inst;
148acb7b 6220 super->random = random32();
272906ef
DW
6221 di->next = rv;
6222 rv = di;
6223 num_spares++;
6224 dprintf("%x:%x to be %d at %llu\n", dl->major, dl->minor,
6225 i, di->data_offset);
88758e9d 6226
272906ef 6227 break;
88758e9d
DW
6228 }
6229
6230 if (!rv)
6231 /* No spares found */
6232 return rv;
6233 /* Now 'rv' has a list of devices to return.
6234 * Create a metadata_update record to update the
6235 * disk_ord_tbl for the array
6236 */
6237 mu = malloc(sizeof(*mu));
79244939
DW
6238 if (mu) {
6239 mu->buf = malloc(sizeof(struct imsm_update_activate_spare) * num_spares);
6240 if (mu->buf == NULL) {
6241 free(mu);
6242 mu = NULL;
6243 }
6244 }
6245 if (!mu) {
6246 while (rv) {
6247 struct mdinfo *n = rv->next;
6248
6249 free(rv);
6250 rv = n;
6251 }
6252 return NULL;
6253 }
6254
88758e9d 6255 mu->space = NULL;
cb23f1f4 6256 mu->space_list = NULL;
88758e9d
DW
6257 mu->len = sizeof(struct imsm_update_activate_spare) * num_spares;
6258 mu->next = *updates;
6259 u = (struct imsm_update_activate_spare *) mu->buf;
6260
6261 for (di = rv ; di ; di = di->next) {
6262 u->type = update_activate_spare;
d23fe947
DW
6263 u->dl = (struct dl *) di->devs;
6264 di->devs = NULL;
88758e9d
DW
6265 u->slot = di->disk.raid_disk;
6266 u->array = inst;
6267 u->next = u + 1;
6268 u++;
6269 }
6270 (u-1)->next = NULL;
6271 *updates = mu;
6272
6273 return rv;
6274}
6275
54c2c1ea 6276static int disks_overlap(struct intel_super *super, int idx, struct imsm_update_create_array *u)
8273f55e 6277{
54c2c1ea
DW
6278 struct imsm_dev *dev = get_imsm_dev(super, idx);
6279 struct imsm_map *map = get_imsm_map(dev, 0);
6280 struct imsm_map *new_map = get_imsm_map(&u->dev, 0);
6281 struct disk_info *inf = get_disk_info(u);
6282 struct imsm_disk *disk;
8273f55e
DW
6283 int i;
6284 int j;
8273f55e 6285
54c2c1ea 6286 for (i = 0; i < map->num_members; i++) {
98130f40 6287 disk = get_imsm_disk(super, get_imsm_disk_idx(dev, i, -1));
54c2c1ea
DW
6288 for (j = 0; j < new_map->num_members; j++)
6289 if (serialcmp(disk->serial, inf[j].serial) == 0)
8273f55e
DW
6290 return 1;
6291 }
6292
6293 return 0;
6294}
6295
1a64be56
LM
6296
6297static struct dl *get_disk_super(struct intel_super *super, int major, int minor)
6298{
6299 struct dl *dl = NULL;
6300 for (dl = super->disks; dl; dl = dl->next)
6301 if ((dl->major == major) && (dl->minor == minor))
6302 return dl;
6303 return NULL;
6304}
6305
6306static int remove_disk_super(struct intel_super *super, int major, int minor)
6307{
6308 struct dl *prev = NULL;
6309 struct dl *dl;
6310
6311 prev = NULL;
6312 for (dl = super->disks; dl; dl = dl->next) {
6313 if ((dl->major == major) && (dl->minor == minor)) {
6314 /* remove */
6315 if (prev)
6316 prev->next = dl->next;
6317 else
6318 super->disks = dl->next;
6319 dl->next = NULL;
6320 __free_imsm_disk(dl);
6321 dprintf("%s: removed %x:%x\n",
6322 __func__, major, minor);
6323 break;
6324 }
6325 prev = dl;
6326 }
6327 return 0;
6328}
6329
f21e18ca 6330static void imsm_delete(struct intel_super *super, struct dl **dlp, unsigned index);
ae6aad82 6331
1a64be56
LM
6332static int add_remove_disk_update(struct intel_super *super)
6333{
6334 int check_degraded = 0;
6335 struct dl *disk = NULL;
6336 /* add/remove some spares to/from the metadata/contrainer */
6337 while (super->disk_mgmt_list) {
6338 struct dl *disk_cfg;
6339
6340 disk_cfg = super->disk_mgmt_list;
6341 super->disk_mgmt_list = disk_cfg->next;
6342 disk_cfg->next = NULL;
6343
6344 if (disk_cfg->action == DISK_ADD) {
6345 disk_cfg->next = super->disks;
6346 super->disks = disk_cfg;
6347 check_degraded = 1;
6348 dprintf("%s: added %x:%x\n",
6349 __func__, disk_cfg->major,
6350 disk_cfg->minor);
6351 } else if (disk_cfg->action == DISK_REMOVE) {
6352 dprintf("Disk remove action processed: %x.%x\n",
6353 disk_cfg->major, disk_cfg->minor);
6354 disk = get_disk_super(super,
6355 disk_cfg->major,
6356 disk_cfg->minor);
6357 if (disk) {
6358 /* store action status */
6359 disk->action = DISK_REMOVE;
6360 /* remove spare disks only */
6361 if (disk->index == -1) {
6362 remove_disk_super(super,
6363 disk_cfg->major,
6364 disk_cfg->minor);
6365 }
6366 }
6367 /* release allocate disk structure */
6368 __free_imsm_disk(disk_cfg);
6369 }
6370 }
6371 return check_degraded;
6372}
6373
a29911da
PC
6374
6375static int apply_reshape_migration_update(struct imsm_update_reshape_migration *u,
6376 struct intel_super *super,
6377 void ***space_list)
6378{
6379 struct intel_dev *id;
6380 void **tofree = NULL;
6381 int ret_val = 0;
6382
6383 dprintf("apply_reshape_migration_update()\n");
6384 if ((u->subdev < 0) ||
6385 (u->subdev > 1)) {
6386 dprintf("imsm: Error: Wrong subdev: %i\n", u->subdev);
6387 return ret_val;
6388 }
6389 if ((space_list == NULL) || (*space_list == NULL)) {
6390 dprintf("imsm: Error: Memory is not allocated\n");
6391 return ret_val;
6392 }
6393
6394 for (id = super->devlist ; id; id = id->next) {
6395 if (id->index == (unsigned)u->subdev) {
6396 struct imsm_dev *dev = get_imsm_dev(super, u->subdev);
6397 struct imsm_map *map;
6398 struct imsm_dev *new_dev =
6399 (struct imsm_dev *)*space_list;
6400 struct imsm_map *migr_map = get_imsm_map(dev, 1);
6401 int to_state;
6402 struct dl *new_disk;
6403
6404 if (new_dev == NULL)
6405 return ret_val;
6406 *space_list = **space_list;
6407 memcpy(new_dev, dev, sizeof_imsm_dev(dev, 0));
6408 map = get_imsm_map(new_dev, 0);
6409 if (migr_map) {
6410 dprintf("imsm: Error: migration in progress");
6411 return ret_val;
6412 }
6413
6414 to_state = map->map_state;
6415 if ((u->new_level == 5) && (map->raid_level == 0)) {
6416 map->num_members++;
6417 /* this should not happen */
6418 if (u->new_disks[0] < 0) {
6419 map->failed_disk_num =
6420 map->num_members - 1;
6421 to_state = IMSM_T_STATE_DEGRADED;
6422 } else
6423 to_state = IMSM_T_STATE_NORMAL;
6424 }
8e59f3d8 6425 migrate(new_dev, super, to_state, MIGR_GEN_MIGR);
a29911da
PC
6426 if (u->new_level > -1)
6427 map->raid_level = u->new_level;
6428 migr_map = get_imsm_map(new_dev, 1);
6429 if ((u->new_level == 5) &&
6430 (migr_map->raid_level == 0)) {
6431 int ord = map->num_members - 1;
6432 migr_map->num_members--;
6433 if (u->new_disks[0] < 0)
6434 ord |= IMSM_ORD_REBUILD;
6435 set_imsm_ord_tbl_ent(map,
6436 map->num_members - 1,
6437 ord);
6438 }
6439 id->dev = new_dev;
6440 tofree = (void **)dev;
6441
4bba0439
PC
6442 /* update chunk size
6443 */
6444 if (u->new_chunksize > 0)
6445 map->blocks_per_strip =
6446 __cpu_to_le16(u->new_chunksize * 2);
6447
a29911da
PC
6448 /* add disk
6449 */
6450 if ((u->new_level != 5) ||
6451 (migr_map->raid_level != 0) ||
6452 (migr_map->raid_level == map->raid_level))
6453 goto skip_disk_add;
6454
6455 if (u->new_disks[0] >= 0) {
6456 /* use passes spare
6457 */
6458 new_disk = get_disk_super(super,
6459 major(u->new_disks[0]),
6460 minor(u->new_disks[0]));
6461 dprintf("imsm: new disk for reshape is: %i:%i "
6462 "(%p, index = %i)\n",
6463 major(u->new_disks[0]),
6464 minor(u->new_disks[0]),
6465 new_disk, new_disk->index);
6466 if (new_disk == NULL)
6467 goto error_disk_add;
6468
6469 new_disk->index = map->num_members - 1;
6470 /* slot to fill in autolayout
6471 */
6472 new_disk->raiddisk = new_disk->index;
6473 new_disk->disk.status |= CONFIGURED_DISK;
6474 new_disk->disk.status &= ~SPARE_DISK;
6475 } else
6476 goto error_disk_add;
6477
6478skip_disk_add:
6479 *tofree = *space_list;
6480 /* calculate new size
6481 */
6482 imsm_set_array_size(new_dev);
6483
6484 ret_val = 1;
6485 }
6486 }
6487
6488 if (tofree)
6489 *space_list = tofree;
6490 return ret_val;
6491
6492error_disk_add:
6493 dprintf("Error: imsm: Cannot find disk.\n");
6494 return ret_val;
6495}
6496
6497
2e5dc010
N
6498static int apply_reshape_container_disks_update(struct imsm_update_reshape *u,
6499 struct intel_super *super,
6500 void ***space_list)
6501{
6502 struct dl *new_disk;
6503 struct intel_dev *id;
6504 int i;
6505 int delta_disks = u->new_raid_disks - u->old_raid_disks;
ee4beede 6506 int disk_count = u->old_raid_disks;
2e5dc010
N
6507 void **tofree = NULL;
6508 int devices_to_reshape = 1;
6509 struct imsm_super *mpb = super->anchor;
6510 int ret_val = 0;
d098291a 6511 unsigned int dev_id;
2e5dc010 6512
ed7333bd 6513 dprintf("imsm: apply_reshape_container_disks_update()\n");
2e5dc010
N
6514
6515 /* enable spares to use in array */
6516 for (i = 0; i < delta_disks; i++) {
6517 new_disk = get_disk_super(super,
6518 major(u->new_disks[i]),
6519 minor(u->new_disks[i]));
ed7333bd
AK
6520 dprintf("imsm: new disk for reshape is: %i:%i "
6521 "(%p, index = %i)\n",
2e5dc010
N
6522 major(u->new_disks[i]), minor(u->new_disks[i]),
6523 new_disk, new_disk->index);
6524 if ((new_disk == NULL) ||
6525 ((new_disk->index >= 0) &&
6526 (new_disk->index < u->old_raid_disks)))
6527 goto update_reshape_exit;
ee4beede 6528 new_disk->index = disk_count++;
2e5dc010
N
6529 /* slot to fill in autolayout
6530 */
6531 new_disk->raiddisk = new_disk->index;
6532 new_disk->disk.status |=
6533 CONFIGURED_DISK;
6534 new_disk->disk.status &= ~SPARE_DISK;
6535 }
6536
ed7333bd
AK
6537 dprintf("imsm: volume set mpb->num_raid_devs = %i\n",
6538 mpb->num_raid_devs);
2e5dc010
N
6539 /* manage changes in volume
6540 */
d098291a 6541 for (dev_id = 0; dev_id < mpb->num_raid_devs; dev_id++) {
2e5dc010
N
6542 void **sp = *space_list;
6543 struct imsm_dev *newdev;
6544 struct imsm_map *newmap, *oldmap;
6545
d098291a
AK
6546 for (id = super->devlist ; id; id = id->next) {
6547 if (id->index == dev_id)
6548 break;
6549 }
6550 if (id == NULL)
6551 break;
2e5dc010
N
6552 if (!sp)
6553 continue;
6554 *space_list = *sp;
6555 newdev = (void*)sp;
6556 /* Copy the dev, but not (all of) the map */
6557 memcpy(newdev, id->dev, sizeof(*newdev));
6558 oldmap = get_imsm_map(id->dev, 0);
6559 newmap = get_imsm_map(newdev, 0);
6560 /* Copy the current map */
6561 memcpy(newmap, oldmap, sizeof_imsm_map(oldmap));
6562 /* update one device only
6563 */
6564 if (devices_to_reshape) {
ed7333bd
AK
6565 dprintf("imsm: modifying subdev: %i\n",
6566 id->index);
2e5dc010
N
6567 devices_to_reshape--;
6568 newdev->vol.migr_state = 1;
6569 newdev->vol.curr_migr_unit = 0;
6570 newdev->vol.migr_type = MIGR_GEN_MIGR;
6571 newmap->num_members = u->new_raid_disks;
6572 for (i = 0; i < delta_disks; i++) {
6573 set_imsm_ord_tbl_ent(newmap,
6574 u->old_raid_disks + i,
6575 u->old_raid_disks + i);
6576 }
6577 /* New map is correct, now need to save old map
6578 */
6579 newmap = get_imsm_map(newdev, 1);
6580 memcpy(newmap, oldmap, sizeof_imsm_map(oldmap));
6581
70bdf0dc 6582 imsm_set_array_size(newdev);
2e5dc010
N
6583 }
6584
6585 sp = (void **)id->dev;
6586 id->dev = newdev;
6587 *sp = tofree;
6588 tofree = sp;
8e59f3d8
AK
6589
6590 /* Clear migration record */
6591 memset(super->migr_rec, 0, sizeof(struct migr_record));
2e5dc010 6592 }
819bc634
AK
6593 if (tofree)
6594 *space_list = tofree;
2e5dc010
N
6595 ret_val = 1;
6596
6597update_reshape_exit:
6598
6599 return ret_val;
6600}
6601
bb025c2f 6602static int apply_takeover_update(struct imsm_update_takeover *u,
8ca6df95
KW
6603 struct intel_super *super,
6604 void ***space_list)
bb025c2f
KW
6605{
6606 struct imsm_dev *dev = NULL;
8ca6df95
KW
6607 struct intel_dev *dv;
6608 struct imsm_dev *dev_new;
bb025c2f
KW
6609 struct imsm_map *map;
6610 struct dl *dm, *du;
8ca6df95 6611 int i;
bb025c2f
KW
6612
6613 for (dv = super->devlist; dv; dv = dv->next)
6614 if (dv->index == (unsigned int)u->subarray) {
6615 dev = dv->dev;
6616 break;
6617 }
6618
6619 if (dev == NULL)
6620 return 0;
6621
6622 map = get_imsm_map(dev, 0);
6623
6624 if (u->direction == R10_TO_R0) {
43d5ec18
KW
6625 /* Number of failed disks must be half of initial disk number */
6626 if (imsm_count_failed(super, dev) != (map->num_members / 2))
6627 return 0;
6628
bb025c2f
KW
6629 /* iterate through devices to mark removed disks as spare */
6630 for (dm = super->disks; dm; dm = dm->next) {
6631 if (dm->disk.status & FAILED_DISK) {
6632 int idx = dm->index;
6633 /* update indexes on the disk list */
6634/* FIXME this loop-with-the-loop looks wrong, I'm not convinced
6635 the index values will end up being correct.... NB */
6636 for (du = super->disks; du; du = du->next)
6637 if (du->index > idx)
6638 du->index--;
6639 /* mark as spare disk */
6640 dm->disk.status = SPARE_DISK;
6641 dm->index = -1;
6642 }
6643 }
bb025c2f
KW
6644 /* update map */
6645 map->num_members = map->num_members / 2;
6646 map->map_state = IMSM_T_STATE_NORMAL;
6647 map->num_domains = 1;
6648 map->raid_level = 0;
6649 map->failed_disk_num = -1;
6650 }
6651
8ca6df95
KW
6652 if (u->direction == R0_TO_R10) {
6653 void **space;
6654 /* update slots in current disk list */
6655 for (dm = super->disks; dm; dm = dm->next) {
6656 if (dm->index >= 0)
6657 dm->index *= 2;
6658 }
6659 /* create new *missing* disks */
6660 for (i = 0; i < map->num_members; i++) {
6661 space = *space_list;
6662 if (!space)
6663 continue;
6664 *space_list = *space;
6665 du = (void *)space;
6666 memcpy(du, super->disks, sizeof(*du));
8ca6df95
KW
6667 du->fd = -1;
6668 du->minor = 0;
6669 du->major = 0;
6670 du->index = (i * 2) + 1;
6671 sprintf((char *)du->disk.serial,
6672 " MISSING_%d", du->index);
6673 sprintf((char *)du->serial,
6674 "MISSING_%d", du->index);
6675 du->next = super->missing;
6676 super->missing = du;
6677 }
6678 /* create new dev and map */
6679 space = *space_list;
6680 if (!space)
6681 return 0;
6682 *space_list = *space;
6683 dev_new = (void *)space;
6684 memcpy(dev_new, dev, sizeof(*dev));
6685 /* update new map */
6686 map = get_imsm_map(dev_new, 0);
8ca6df95 6687 map->num_members = map->num_members * 2;
1a2487c2 6688 map->map_state = IMSM_T_STATE_DEGRADED;
8ca6df95
KW
6689 map->num_domains = 2;
6690 map->raid_level = 1;
6691 /* replace dev<->dev_new */
6692 dv->dev = dev_new;
6693 }
bb025c2f
KW
6694 /* update disk order table */
6695 for (du = super->disks; du; du = du->next)
6696 if (du->index >= 0)
6697 set_imsm_ord_tbl_ent(map, du->index, du->index);
8ca6df95 6698 for (du = super->missing; du; du = du->next)
1a2487c2
KW
6699 if (du->index >= 0) {
6700 set_imsm_ord_tbl_ent(map, du->index, du->index);
6701 mark_missing(dev_new, &du->disk, du->index);
6702 }
bb025c2f
KW
6703
6704 return 1;
6705}
6706
e8319a19
DW
6707static void imsm_process_update(struct supertype *st,
6708 struct metadata_update *update)
6709{
6710 /**
6711 * crack open the metadata_update envelope to find the update record
6712 * update can be one of:
d195167d
AK
6713 * update_reshape_container_disks - all the arrays in the container
6714 * are being reshaped to have more devices. We need to mark
6715 * the arrays for general migration and convert selected spares
6716 * into active devices.
6717 * update_activate_spare - a spare device has replaced a failed
e8319a19
DW
6718 * device in an array, update the disk_ord_tbl. If this disk is
6719 * present in all member arrays then also clear the SPARE_DISK
6720 * flag
d195167d
AK
6721 * update_create_array
6722 * update_kill_array
6723 * update_rename_array
6724 * update_add_remove_disk
e8319a19
DW
6725 */
6726 struct intel_super *super = st->sb;
4d7b1503 6727 struct imsm_super *mpb;
e8319a19
DW
6728 enum imsm_update_type type = *(enum imsm_update_type *) update->buf;
6729
4d7b1503
DW
6730 /* update requires a larger buf but the allocation failed */
6731 if (super->next_len && !super->next_buf) {
6732 super->next_len = 0;
6733 return;
6734 }
6735
6736 if (super->next_buf) {
6737 memcpy(super->next_buf, super->buf, super->len);
6738 free(super->buf);
6739 super->len = super->next_len;
6740 super->buf = super->next_buf;
6741
6742 super->next_len = 0;
6743 super->next_buf = NULL;
6744 }
6745
6746 mpb = super->anchor;
6747
e8319a19 6748 switch (type) {
bb025c2f
KW
6749 case update_takeover: {
6750 struct imsm_update_takeover *u = (void *)update->buf;
1a2487c2
KW
6751 if (apply_takeover_update(u, super, &update->space_list)) {
6752 imsm_update_version_info(super);
bb025c2f 6753 super->updates_pending++;
1a2487c2 6754 }
bb025c2f
KW
6755 break;
6756 }
6757
78b10e66 6758 case update_reshape_container_disks: {
d195167d 6759 struct imsm_update_reshape *u = (void *)update->buf;
2e5dc010
N
6760 if (apply_reshape_container_disks_update(
6761 u, super, &update->space_list))
6762 super->updates_pending++;
78b10e66
N
6763 break;
6764 }
48c5303a 6765 case update_reshape_migration: {
a29911da
PC
6766 struct imsm_update_reshape_migration *u = (void *)update->buf;
6767 if (apply_reshape_migration_update(
6768 u, super, &update->space_list))
6769 super->updates_pending++;
48c5303a
PC
6770 break;
6771 }
e8319a19
DW
6772 case update_activate_spare: {
6773 struct imsm_update_activate_spare *u = (void *) update->buf;
949c47a0 6774 struct imsm_dev *dev = get_imsm_dev(super, u->array);
a965f303 6775 struct imsm_map *map = get_imsm_map(dev, 0);
0c046afd 6776 struct imsm_map *migr_map;
e8319a19
DW
6777 struct active_array *a;
6778 struct imsm_disk *disk;
0c046afd 6779 __u8 to_state;
e8319a19 6780 struct dl *dl;
e8319a19 6781 unsigned int found;
0c046afd 6782 int failed;
98130f40 6783 int victim = get_imsm_disk_idx(dev, u->slot, -1);
e8319a19
DW
6784 int i;
6785
6786 for (dl = super->disks; dl; dl = dl->next)
d23fe947 6787 if (dl == u->dl)
e8319a19
DW
6788 break;
6789
6790 if (!dl) {
6791 fprintf(stderr, "error: imsm_activate_spare passed "
1f24f035
DW
6792 "an unknown disk (index: %d)\n",
6793 u->dl->index);
e8319a19
DW
6794 return;
6795 }
6796
6797 super->updates_pending++;
0c046afd
DW
6798 /* count failures (excluding rebuilds and the victim)
6799 * to determine map[0] state
6800 */
6801 failed = 0;
6802 for (i = 0; i < map->num_members; i++) {
6803 if (i == u->slot)
6804 continue;
98130f40
AK
6805 disk = get_imsm_disk(super,
6806 get_imsm_disk_idx(dev, i, -1));
25ed7e59 6807 if (!disk || is_failed(disk))
0c046afd
DW
6808 failed++;
6809 }
6810
d23fe947
DW
6811 /* adding a pristine spare, assign a new index */
6812 if (dl->index < 0) {
6813 dl->index = super->anchor->num_disks;
6814 super->anchor->num_disks++;
6815 }
d23fe947 6816 disk = &dl->disk;
f2f27e63
DW
6817 disk->status |= CONFIGURED_DISK;
6818 disk->status &= ~SPARE_DISK;
e8319a19 6819
0c046afd
DW
6820 /* mark rebuild */
6821 to_state = imsm_check_degraded(super, dev, failed);
6822 map->map_state = IMSM_T_STATE_DEGRADED;
8e59f3d8 6823 migrate(dev, super, to_state, MIGR_REBUILD);
0c046afd
DW
6824 migr_map = get_imsm_map(dev, 1);
6825 set_imsm_ord_tbl_ent(map, u->slot, dl->index);
6826 set_imsm_ord_tbl_ent(migr_map, u->slot, dl->index | IMSM_ORD_REBUILD);
6827
148acb7b
DW
6828 /* update the family_num to mark a new container
6829 * generation, being careful to record the existing
6830 * family_num in orig_family_num to clean up after
6831 * earlier mdadm versions that neglected to set it.
6832 */
6833 if (mpb->orig_family_num == 0)
6834 mpb->orig_family_num = mpb->family_num;
6835 mpb->family_num += super->random;
6836
e8319a19
DW
6837 /* count arrays using the victim in the metadata */
6838 found = 0;
6839 for (a = st->arrays; a ; a = a->next) {
949c47a0 6840 dev = get_imsm_dev(super, a->info.container_member);
620b1713
DW
6841 map = get_imsm_map(dev, 0);
6842
6843 if (get_imsm_disk_slot(map, victim) >= 0)
6844 found++;
e8319a19
DW
6845 }
6846
24565c9a 6847 /* delete the victim if it is no longer being
e8319a19
DW
6848 * utilized anywhere
6849 */
e8319a19 6850 if (!found) {
ae6aad82 6851 struct dl **dlp;
24565c9a 6852
47ee5a45
DW
6853 /* We know that 'manager' isn't touching anything,
6854 * so it is safe to delete
6855 */
24565c9a 6856 for (dlp = &super->disks; *dlp; dlp = &(*dlp)->next)
ae6aad82
DW
6857 if ((*dlp)->index == victim)
6858 break;
47ee5a45
DW
6859
6860 /* victim may be on the missing list */
6861 if (!*dlp)
6862 for (dlp = &super->missing; *dlp; dlp = &(*dlp)->next)
6863 if ((*dlp)->index == victim)
6864 break;
24565c9a 6865 imsm_delete(super, dlp, victim);
e8319a19 6866 }
8273f55e
DW
6867 break;
6868 }
6869 case update_create_array: {
6870 /* someone wants to create a new array, we need to be aware of
6871 * a few races/collisions:
6872 * 1/ 'Create' called by two separate instances of mdadm
6873 * 2/ 'Create' versus 'activate_spare': mdadm has chosen
6874 * devices that have since been assimilated via
6875 * activate_spare.
6876 * In the event this update can not be carried out mdadm will
6877 * (FIX ME) notice that its update did not take hold.
6878 */
6879 struct imsm_update_create_array *u = (void *) update->buf;
ba2de7ba 6880 struct intel_dev *dv;
8273f55e
DW
6881 struct imsm_dev *dev;
6882 struct imsm_map *map, *new_map;
6883 unsigned long long start, end;
6884 unsigned long long new_start, new_end;
6885 int i;
54c2c1ea
DW
6886 struct disk_info *inf;
6887 struct dl *dl;
8273f55e
DW
6888
6889 /* handle racing creates: first come first serve */
6890 if (u->dev_idx < mpb->num_raid_devs) {
6891 dprintf("%s: subarray %d already defined\n",
6892 __func__, u->dev_idx);
ba2de7ba 6893 goto create_error;
8273f55e
DW
6894 }
6895
6896 /* check update is next in sequence */
6897 if (u->dev_idx != mpb->num_raid_devs) {
6a3e913e
DW
6898 dprintf("%s: can not create array %d expected index %d\n",
6899 __func__, u->dev_idx, mpb->num_raid_devs);
ba2de7ba 6900 goto create_error;
8273f55e
DW
6901 }
6902
a965f303 6903 new_map = get_imsm_map(&u->dev, 0);
8273f55e
DW
6904 new_start = __le32_to_cpu(new_map->pba_of_lba0);
6905 new_end = new_start + __le32_to_cpu(new_map->blocks_per_member);
54c2c1ea 6906 inf = get_disk_info(u);
8273f55e
DW
6907
6908 /* handle activate_spare versus create race:
6909 * check to make sure that overlapping arrays do not include
6910 * overalpping disks
6911 */
6912 for (i = 0; i < mpb->num_raid_devs; i++) {
949c47a0 6913 dev = get_imsm_dev(super, i);
a965f303 6914 map = get_imsm_map(dev, 0);
8273f55e
DW
6915 start = __le32_to_cpu(map->pba_of_lba0);
6916 end = start + __le32_to_cpu(map->blocks_per_member);
6917 if ((new_start >= start && new_start <= end) ||
6918 (start >= new_start && start <= new_end))
54c2c1ea
DW
6919 /* overlap */;
6920 else
6921 continue;
6922
6923 if (disks_overlap(super, i, u)) {
8273f55e 6924 dprintf("%s: arrays overlap\n", __func__);
ba2de7ba 6925 goto create_error;
8273f55e
DW
6926 }
6927 }
8273f55e 6928
949c47a0
DW
6929 /* check that prepare update was successful */
6930 if (!update->space) {
6931 dprintf("%s: prepare update failed\n", __func__);
ba2de7ba 6932 goto create_error;
949c47a0
DW
6933 }
6934
54c2c1ea
DW
6935 /* check that all disks are still active before committing
6936 * changes. FIXME: could we instead handle this by creating a
6937 * degraded array? That's probably not what the user expects,
6938 * so better to drop this update on the floor.
6939 */
6940 for (i = 0; i < new_map->num_members; i++) {
6941 dl = serial_to_dl(inf[i].serial, super);
6942 if (!dl) {
6943 dprintf("%s: disk disappeared\n", __func__);
ba2de7ba 6944 goto create_error;
54c2c1ea 6945 }
949c47a0
DW
6946 }
6947
8273f55e 6948 super->updates_pending++;
54c2c1ea
DW
6949
6950 /* convert spares to members and fixup ord_tbl */
6951 for (i = 0; i < new_map->num_members; i++) {
6952 dl = serial_to_dl(inf[i].serial, super);
6953 if (dl->index == -1) {
6954 dl->index = mpb->num_disks;
6955 mpb->num_disks++;
6956 dl->disk.status |= CONFIGURED_DISK;
6957 dl->disk.status &= ~SPARE_DISK;
6958 }
6959 set_imsm_ord_tbl_ent(new_map, i, dl->index);
6960 }
6961
ba2de7ba
DW
6962 dv = update->space;
6963 dev = dv->dev;
949c47a0
DW
6964 update->space = NULL;
6965 imsm_copy_dev(dev, &u->dev);
ba2de7ba
DW
6966 dv->index = u->dev_idx;
6967 dv->next = super->devlist;
6968 super->devlist = dv;
8273f55e 6969 mpb->num_raid_devs++;
8273f55e 6970
4d1313e9 6971 imsm_update_version_info(super);
8273f55e 6972 break;
ba2de7ba
DW
6973 create_error:
6974 /* mdmon knows how to release update->space, but not
6975 * ((struct intel_dev *) update->space)->dev
6976 */
6977 if (update->space) {
6978 dv = update->space;
6979 free(dv->dev);
6980 }
8273f55e 6981 break;
e8319a19 6982 }
33414a01
DW
6983 case update_kill_array: {
6984 struct imsm_update_kill_array *u = (void *) update->buf;
6985 int victim = u->dev_idx;
6986 struct active_array *a;
6987 struct intel_dev **dp;
6988 struct imsm_dev *dev;
6989
6990 /* sanity check that we are not affecting the uuid of
6991 * active arrays, or deleting an active array
6992 *
6993 * FIXME when immutable ids are available, but note that
6994 * we'll also need to fixup the invalidated/active
6995 * subarray indexes in mdstat
6996 */
6997 for (a = st->arrays; a; a = a->next)
6998 if (a->info.container_member >= victim)
6999 break;
7000 /* by definition if mdmon is running at least one array
7001 * is active in the container, so checking
7002 * mpb->num_raid_devs is just extra paranoia
7003 */
7004 dev = get_imsm_dev(super, victim);
7005 if (a || !dev || mpb->num_raid_devs == 1) {
7006 dprintf("failed to delete subarray-%d\n", victim);
7007 break;
7008 }
7009
7010 for (dp = &super->devlist; *dp;)
f21e18ca 7011 if ((*dp)->index == (unsigned)super->current_vol) {
33414a01
DW
7012 *dp = (*dp)->next;
7013 } else {
f21e18ca 7014 if ((*dp)->index > (unsigned)victim)
33414a01
DW
7015 (*dp)->index--;
7016 dp = &(*dp)->next;
7017 }
7018 mpb->num_raid_devs--;
7019 super->updates_pending++;
7020 break;
7021 }
aa534678
DW
7022 case update_rename_array: {
7023 struct imsm_update_rename_array *u = (void *) update->buf;
7024 char name[MAX_RAID_SERIAL_LEN+1];
7025 int target = u->dev_idx;
7026 struct active_array *a;
7027 struct imsm_dev *dev;
7028
7029 /* sanity check that we are not affecting the uuid of
7030 * an active array
7031 */
7032 snprintf(name, MAX_RAID_SERIAL_LEN, "%s", (char *) u->name);
7033 name[MAX_RAID_SERIAL_LEN] = '\0';
7034 for (a = st->arrays; a; a = a->next)
7035 if (a->info.container_member == target)
7036 break;
7037 dev = get_imsm_dev(super, u->dev_idx);
7038 if (a || !dev || !check_name(super, name, 1)) {
7039 dprintf("failed to rename subarray-%d\n", target);
7040 break;
7041 }
7042
cdbe98cd 7043 snprintf((char *) dev->volume, MAX_RAID_SERIAL_LEN, "%s", name);
aa534678
DW
7044 super->updates_pending++;
7045 break;
7046 }
1a64be56 7047 case update_add_remove_disk: {
43dad3d6 7048 /* we may be able to repair some arrays if disks are
1a64be56
LM
7049 * being added, check teh status of add_remove_disk
7050 * if discs has been added.
7051 */
7052 if (add_remove_disk_update(super)) {
43dad3d6 7053 struct active_array *a;
072b727f
DW
7054
7055 super->updates_pending++;
1a64be56 7056 for (a = st->arrays; a; a = a->next)
43dad3d6
DW
7057 a->check_degraded = 1;
7058 }
43dad3d6 7059 break;
e8319a19 7060 }
1a64be56
LM
7061 default:
7062 fprintf(stderr, "error: unsuported process update type:"
7063 "(type: %d)\n", type);
7064 }
e8319a19 7065}
88758e9d 7066
bc0b9d34
PC
7067static struct mdinfo *get_spares_for_grow(struct supertype *st);
7068
8273f55e
DW
7069static void imsm_prepare_update(struct supertype *st,
7070 struct metadata_update *update)
7071{
949c47a0 7072 /**
4d7b1503
DW
7073 * Allocate space to hold new disk entries, raid-device entries or a new
7074 * mpb if necessary. The manager synchronously waits for updates to
7075 * complete in the monitor, so new mpb buffers allocated here can be
7076 * integrated by the monitor thread without worrying about live pointers
7077 * in the manager thread.
8273f55e 7078 */
949c47a0 7079 enum imsm_update_type type = *(enum imsm_update_type *) update->buf;
4d7b1503
DW
7080 struct intel_super *super = st->sb;
7081 struct imsm_super *mpb = super->anchor;
7082 size_t buf_len;
7083 size_t len = 0;
949c47a0
DW
7084
7085 switch (type) {
abedf5fc
KW
7086 case update_takeover: {
7087 struct imsm_update_takeover *u = (void *)update->buf;
7088 if (u->direction == R0_TO_R10) {
7089 void **tail = (void **)&update->space_list;
7090 struct imsm_dev *dev = get_imsm_dev(super, u->subarray);
7091 struct imsm_map *map = get_imsm_map(dev, 0);
7092 int num_members = map->num_members;
7093 void *space;
7094 int size, i;
7095 int err = 0;
7096 /* allocate memory for added disks */
7097 for (i = 0; i < num_members; i++) {
7098 size = sizeof(struct dl);
7099 space = malloc(size);
7100 if (!space) {
7101 err++;
7102 break;
7103 }
7104 *tail = space;
7105 tail = space;
7106 *tail = NULL;
7107 }
7108 /* allocate memory for new device */
7109 size = sizeof_imsm_dev(super->devlist->dev, 0) +
7110 (num_members * sizeof(__u32));
7111 space = malloc(size);
7112 if (!space)
7113 err++;
7114 else {
7115 *tail = space;
7116 tail = space;
7117 *tail = NULL;
7118 }
7119 if (!err) {
7120 len = disks_to_mpb_size(num_members * 2);
7121 } else {
7122 /* if allocation didn't success, free buffer */
7123 while (update->space_list) {
7124 void **sp = update->space_list;
7125 update->space_list = *sp;
7126 free(sp);
7127 }
7128 }
7129 }
7130
7131 break;
7132 }
78b10e66 7133 case update_reshape_container_disks: {
d195167d
AK
7134 /* Every raid device in the container is about to
7135 * gain some more devices, and we will enter a
7136 * reconfiguration.
7137 * So each 'imsm_map' will be bigger, and the imsm_vol
7138 * will now hold 2 of them.
7139 * Thus we need new 'struct imsm_dev' allocations sized
7140 * as sizeof_imsm_dev but with more devices in both maps.
7141 */
7142 struct imsm_update_reshape *u = (void *)update->buf;
7143 struct intel_dev *dl;
7144 void **space_tail = (void**)&update->space_list;
7145
7146 dprintf("imsm: imsm_prepare_update() for update_reshape\n");
7147
7148 for (dl = super->devlist; dl; dl = dl->next) {
7149 int size = sizeof_imsm_dev(dl->dev, 1);
7150 void *s;
d677e0b8
AK
7151 if (u->new_raid_disks > u->old_raid_disks)
7152 size += sizeof(__u32)*2*
7153 (u->new_raid_disks - u->old_raid_disks);
d195167d
AK
7154 s = malloc(size);
7155 if (!s)
7156 break;
7157 *space_tail = s;
7158 space_tail = s;
7159 *space_tail = NULL;
7160 }
7161
7162 len = disks_to_mpb_size(u->new_raid_disks);
7163 dprintf("New anchor length is %llu\n", (unsigned long long)len);
78b10e66
N
7164 break;
7165 }
48c5303a 7166 case update_reshape_migration: {
bc0b9d34
PC
7167 /* for migration level 0->5 we need to add disks
7168 * so the same as for container operation we will copy
7169 * device to the bigger location.
7170 * in memory prepared device and new disk area are prepared
7171 * for usage in process update
7172 */
7173 struct imsm_update_reshape_migration *u = (void *)update->buf;
7174 struct intel_dev *id;
7175 void **space_tail = (void **)&update->space_list;
7176 int size;
7177 void *s;
7178 int current_level = -1;
7179
7180 dprintf("imsm: imsm_prepare_update() for update_reshape\n");
7181
7182 /* add space for bigger array in update
7183 */
7184 for (id = super->devlist; id; id = id->next) {
7185 if (id->index == (unsigned)u->subdev) {
7186 size = sizeof_imsm_dev(id->dev, 1);
7187 if (u->new_raid_disks > u->old_raid_disks)
7188 size += sizeof(__u32)*2*
7189 (u->new_raid_disks - u->old_raid_disks);
7190 s = malloc(size);
7191 if (!s)
7192 break;
7193 *space_tail = s;
7194 space_tail = s;
7195 *space_tail = NULL;
7196 break;
7197 }
7198 }
7199 if (update->space_list == NULL)
7200 break;
7201
7202 /* add space for disk in update
7203 */
7204 size = sizeof(struct dl);
7205 s = malloc(size);
7206 if (!s) {
7207 free(update->space_list);
7208 update->space_list = NULL;
7209 break;
7210 }
7211 *space_tail = s;
7212 space_tail = s;
7213 *space_tail = NULL;
7214
7215 /* add spare device to update
7216 */
7217 for (id = super->devlist ; id; id = id->next)
7218 if (id->index == (unsigned)u->subdev) {
7219 struct imsm_dev *dev;
7220 struct imsm_map *map;
7221
7222 dev = get_imsm_dev(super, u->subdev);
7223 map = get_imsm_map(dev, 0);
7224 current_level = map->raid_level;
7225 break;
7226 }
7227 if ((u->new_level == 5) && (u->new_level != current_level)) {
7228 struct mdinfo *spares;
7229
7230 spares = get_spares_for_grow(st);
7231 if (spares) {
7232 struct dl *dl;
7233 struct mdinfo *dev;
7234
7235 dev = spares->devs;
7236 if (dev) {
7237 u->new_disks[0] =
7238 makedev(dev->disk.major,
7239 dev->disk.minor);
7240 dl = get_disk_super(super,
7241 dev->disk.major,
7242 dev->disk.minor);
7243 dl->index = u->old_raid_disks;
7244 dev = dev->next;
7245 }
7246 sysfs_free(spares);
7247 }
7248 }
7249 len = disks_to_mpb_size(u->new_raid_disks);
7250 dprintf("New anchor length is %llu\n", (unsigned long long)len);
48c5303a
PC
7251 break;
7252 }
949c47a0
DW
7253 case update_create_array: {
7254 struct imsm_update_create_array *u = (void *) update->buf;
ba2de7ba 7255 struct intel_dev *dv;
54c2c1ea
DW
7256 struct imsm_dev *dev = &u->dev;
7257 struct imsm_map *map = get_imsm_map(dev, 0);
7258 struct dl *dl;
7259 struct disk_info *inf;
7260 int i;
7261 int activate = 0;
949c47a0 7262
54c2c1ea
DW
7263 inf = get_disk_info(u);
7264 len = sizeof_imsm_dev(dev, 1);
ba2de7ba
DW
7265 /* allocate a new super->devlist entry */
7266 dv = malloc(sizeof(*dv));
7267 if (dv) {
7268 dv->dev = malloc(len);
7269 if (dv->dev)
7270 update->space = dv;
7271 else {
7272 free(dv);
7273 update->space = NULL;
7274 }
7275 }
949c47a0 7276
54c2c1ea
DW
7277 /* count how many spares will be converted to members */
7278 for (i = 0; i < map->num_members; i++) {
7279 dl = serial_to_dl(inf[i].serial, super);
7280 if (!dl) {
7281 /* hmm maybe it failed?, nothing we can do about
7282 * it here
7283 */
7284 continue;
7285 }
7286 if (count_memberships(dl, super) == 0)
7287 activate++;
7288 }
7289 len += activate * sizeof(struct imsm_disk);
949c47a0
DW
7290 break;
7291 default:
7292 break;
7293 }
7294 }
8273f55e 7295
4d7b1503
DW
7296 /* check if we need a larger metadata buffer */
7297 if (super->next_buf)
7298 buf_len = super->next_len;
7299 else
7300 buf_len = super->len;
7301
7302 if (__le32_to_cpu(mpb->mpb_size) + len > buf_len) {
7303 /* ok we need a larger buf than what is currently allocated
7304 * if this allocation fails process_update will notice that
7305 * ->next_len is set and ->next_buf is NULL
7306 */
7307 buf_len = ROUND_UP(__le32_to_cpu(mpb->mpb_size) + len, 512);
7308 if (super->next_buf)
7309 free(super->next_buf);
7310
7311 super->next_len = buf_len;
1f45a8ad
DW
7312 if (posix_memalign(&super->next_buf, 512, buf_len) == 0)
7313 memset(super->next_buf, 0, buf_len);
7314 else
4d7b1503
DW
7315 super->next_buf = NULL;
7316 }
8273f55e
DW
7317}
7318
ae6aad82 7319/* must be called while manager is quiesced */
f21e18ca 7320static void imsm_delete(struct intel_super *super, struct dl **dlp, unsigned index)
ae6aad82
DW
7321{
7322 struct imsm_super *mpb = super->anchor;
ae6aad82
DW
7323 struct dl *iter;
7324 struct imsm_dev *dev;
7325 struct imsm_map *map;
24565c9a
DW
7326 int i, j, num_members;
7327 __u32 ord;
ae6aad82 7328
24565c9a
DW
7329 dprintf("%s: deleting device[%d] from imsm_super\n",
7330 __func__, index);
ae6aad82
DW
7331
7332 /* shift all indexes down one */
7333 for (iter = super->disks; iter; iter = iter->next)
f21e18ca 7334 if (iter->index > (int)index)
ae6aad82 7335 iter->index--;
47ee5a45 7336 for (iter = super->missing; iter; iter = iter->next)
f21e18ca 7337 if (iter->index > (int)index)
47ee5a45 7338 iter->index--;
ae6aad82
DW
7339
7340 for (i = 0; i < mpb->num_raid_devs; i++) {
7341 dev = get_imsm_dev(super, i);
7342 map = get_imsm_map(dev, 0);
24565c9a
DW
7343 num_members = map->num_members;
7344 for (j = 0; j < num_members; j++) {
7345 /* update ord entries being careful not to propagate
7346 * ord-flags to the first map
7347 */
98130f40 7348 ord = get_imsm_ord_tbl_ent(dev, j, -1);
ae6aad82 7349
24565c9a
DW
7350 if (ord_to_idx(ord) <= index)
7351 continue;
ae6aad82 7352
24565c9a
DW
7353 map = get_imsm_map(dev, 0);
7354 set_imsm_ord_tbl_ent(map, j, ord_to_idx(ord - 1));
7355 map = get_imsm_map(dev, 1);
7356 if (map)
7357 set_imsm_ord_tbl_ent(map, j, ord - 1);
ae6aad82
DW
7358 }
7359 }
7360
7361 mpb->num_disks--;
7362 super->updates_pending++;
24565c9a
DW
7363 if (*dlp) {
7364 struct dl *dl = *dlp;
7365
7366 *dlp = (*dlp)->next;
7367 __free_imsm_disk(dl);
7368 }
ae6aad82
DW
7369}
7370
687629c2
AK
7371/*******************************************************************************
7372 * Function: open_backup_targets
7373 * Description: Function opens file descriptors for all devices given in
7374 * info->devs
7375 * Parameters:
7376 * info : general array info
7377 * raid_disks : number of disks
7378 * raid_fds : table of device's file descriptors
7379 * Returns:
7380 * 0 : success
7381 * -1 : fail
7382 ******************************************************************************/
7383int open_backup_targets(struct mdinfo *info, int raid_disks, int *raid_fds)
7384{
7385 struct mdinfo *sd;
7386
7387 for (sd = info->devs ; sd ; sd = sd->next) {
7388 char *dn;
7389
7390 if (sd->disk.state & (1<<MD_DISK_FAULTY)) {
7391 dprintf("disk is faulty!!\n");
7392 continue;
7393 }
7394
7395 if ((sd->disk.raid_disk >= raid_disks) ||
7396 (sd->disk.raid_disk < 0))
7397 continue;
7398
7399 dn = map_dev(sd->disk.major,
7400 sd->disk.minor, 1);
7401 raid_fds[sd->disk.raid_disk] = dev_open(dn, O_RDWR);
7402 if (raid_fds[sd->disk.raid_disk] < 0) {
7403 fprintf(stderr, "cannot open component\n");
7404 return -1;
7405 }
7406 }
7407 return 0;
7408}
7409
7410/*******************************************************************************
7411 * Function: init_migr_record_imsm
7412 * Description: Function inits imsm migration record
7413 * Parameters:
7414 * super : imsm internal array info
7415 * dev : device under migration
7416 * info : general array info to find the smallest device
7417 * Returns:
7418 * none
7419 ******************************************************************************/
7420void init_migr_record_imsm(struct supertype *st, struct imsm_dev *dev,
7421 struct mdinfo *info)
7422{
7423 struct intel_super *super = st->sb;
7424 struct migr_record *migr_rec = super->migr_rec;
7425 int new_data_disks;
7426 unsigned long long dsize, dev_sectors;
7427 long long unsigned min_dev_sectors = -1LLU;
7428 struct mdinfo *sd;
7429 char nm[30];
7430 int fd;
7431 struct imsm_map *map_dest = get_imsm_map(dev, 0);
7432 struct imsm_map *map_src = get_imsm_map(dev, 1);
7433 unsigned long long num_migr_units;
7434
7435 unsigned long long array_blocks =
7436 (((unsigned long long)__le32_to_cpu(dev->size_high)) << 32) +
7437 __le32_to_cpu(dev->size_low);
7438
7439 memset(migr_rec, 0, sizeof(struct migr_record));
7440 migr_rec->family_num = __cpu_to_le32(super->anchor->family_num);
7441
7442 /* only ascending reshape supported now */
7443 migr_rec->ascending_migr = __cpu_to_le32(1);
7444
7445 migr_rec->dest_depth_per_unit = GEN_MIGR_AREA_SIZE /
7446 max(map_dest->blocks_per_strip, map_src->blocks_per_strip);
7447 migr_rec->dest_depth_per_unit *= map_dest->blocks_per_strip;
7448 new_data_disks = imsm_num_data_members(dev, 0);
7449 migr_rec->blocks_per_unit =
7450 __cpu_to_le32(migr_rec->dest_depth_per_unit * new_data_disks);
7451 migr_rec->dest_depth_per_unit =
7452 __cpu_to_le32(migr_rec->dest_depth_per_unit);
7453
7454 num_migr_units =
7455 array_blocks / __le32_to_cpu(migr_rec->blocks_per_unit);
7456
7457 if (array_blocks % __le32_to_cpu(migr_rec->blocks_per_unit))
7458 num_migr_units++;
7459 migr_rec->num_migr_units = __cpu_to_le32(num_migr_units);
7460
7461 migr_rec->post_migr_vol_cap = dev->size_low;
7462 migr_rec->post_migr_vol_cap_hi = dev->size_high;
7463
7464
7465 /* Find the smallest dev */
7466 for (sd = info->devs ; sd ; sd = sd->next) {
7467 sprintf(nm, "%d:%d", sd->disk.major, sd->disk.minor);
7468 fd = dev_open(nm, O_RDONLY);
7469 if (fd < 0)
7470 continue;
7471 get_dev_size(fd, NULL, &dsize);
7472 dev_sectors = dsize / 512;
7473 if (dev_sectors < min_dev_sectors)
7474 min_dev_sectors = dev_sectors;
7475 close(fd);
7476 }
7477 migr_rec->ckpt_area_pba = __cpu_to_le32(min_dev_sectors -
7478 RAID_DISK_RESERVED_BLOCKS_IMSM_HI);
7479
7480 write_imsm_migr_rec(st);
7481
7482 return;
7483}
7484
7485/*******************************************************************************
7486 * Function: save_backup_imsm
7487 * Description: Function saves critical data stripes to Migration Copy Area
7488 * and updates the current migration unit status.
7489 * Use restore_stripes() to form a destination stripe,
7490 * and to write it to the Copy Area.
7491 * Parameters:
7492 * st : supertype information
7493 * info : general array info
7494 * buf : input buffer
7495 * write_offset : address of data to backup
7496 * length : length of data to backup (blocks_per_unit)
7497 * Returns:
7498 * 0 : success
7499 *, -1 : fail
7500 ******************************************************************************/
7501int save_backup_imsm(struct supertype *st,
7502 struct imsm_dev *dev,
7503 struct mdinfo *info,
7504 void *buf,
7505 int new_data,
7506 int length)
7507{
7508 int rv = -1;
7509 struct intel_super *super = st->sb;
7510 unsigned long long *target_offsets = NULL;
7511 int *targets = NULL;
7512 int i;
7513 struct imsm_map *map_dest = get_imsm_map(dev, 0);
7514 int new_disks = map_dest->num_members;
7515
7516 targets = malloc(new_disks * sizeof(int));
7517 if (!targets)
7518 goto abort;
7519
7520 target_offsets = malloc(new_disks * sizeof(unsigned long long));
7521 if (!target_offsets)
7522 goto abort;
7523
7524 for (i = 0; i < new_disks; i++) {
7525 targets[i] = -1;
7526 target_offsets[i] = (unsigned long long)
7527 __le32_to_cpu(super->migr_rec->ckpt_area_pba) * 512;
7528 }
7529
7530 if (open_backup_targets(info, new_disks, targets))
7531 goto abort;
7532
7533 if (restore_stripes(targets, /* list of dest devices */
7534 target_offsets, /* migration record offsets */
7535 new_disks,
7536 info->new_chunk,
7537 info->new_level,
7538 info->new_layout,
7539 -1, /* source backup file descriptor */
7540 0, /* input buf offset
7541 * always 0 buf is already offset */
7542 0,
7543 length,
7544 buf) != 0) {
7545 fprintf(stderr, Name ": Error restoring stripes\n");
7546 goto abort;
7547 }
7548
7549 rv = 0;
7550
7551abort:
7552 if (targets) {
7553 for (i = 0; i < new_disks; i++)
7554 if (targets[i] >= 0)
7555 close(targets[i]);
7556 free(targets);
7557 }
7558 free(target_offsets);
7559
7560 return rv;
7561}
7562
7563/*******************************************************************************
7564 * Function: save_checkpoint_imsm
7565 * Description: Function called for current unit status update
7566 * in the migration record. It writes it to disk.
7567 * Parameters:
7568 * super : imsm internal array info
7569 * info : general array info
7570 * Returns:
7571 * 0: success
7572 * 1: failure
7573 ******************************************************************************/
7574int save_checkpoint_imsm(struct supertype *st, struct mdinfo *info, int state)
7575{
7576 struct intel_super *super = st->sb;
7577 load_imsm_migr_rec(super, info);
7578 if (__le32_to_cpu(super->migr_rec->blocks_per_unit) == 0) {
7579 dprintf("ERROR: blocks_per_unit = 0!!!\n");
7580 return 1;
7581 }
7582
7583 super->migr_rec->curr_migr_unit =
7584 __cpu_to_le32(info->reshape_progress /
7585 __le32_to_cpu(super->migr_rec->blocks_per_unit));
7586 super->migr_rec->rec_status = __cpu_to_le32(state);
7587 super->migr_rec->dest_1st_member_lba =
7588 __cpu_to_le32((__le32_to_cpu(super->migr_rec->curr_migr_unit))
7589 * __le32_to_cpu(super->migr_rec->dest_depth_per_unit));
7590 if (write_imsm_migr_rec(st) < 0) {
7591 dprintf("imsm: Cannot write migration record "
7592 "outside backup area\n");
7593 return 1;
7594 }
7595
7596 return 0;
7597}
7598
2cda7640
ML
7599static char disk_by_path[] = "/dev/disk/by-path/";
7600
7601static const char *imsm_get_disk_controller_domain(const char *path)
7602{
2cda7640 7603 char disk_path[PATH_MAX];
96234762
LM
7604 char *drv=NULL;
7605 struct stat st;
2cda7640 7606
96234762
LM
7607 strncpy(disk_path, disk_by_path, PATH_MAX - 1);
7608 strncat(disk_path, path, PATH_MAX - strlen(disk_path) - 1);
7609 if (stat(disk_path, &st) == 0) {
7610 struct sys_dev* hba;
7611 char *path=NULL;
7612
7613 path = devt_to_devpath(st.st_rdev);
7614 if (path == NULL)
7615 return "unknown";
7616 hba = find_disk_attached_hba(-1, path);
7617 if (hba && hba->type == SYS_DEV_SAS)
7618 drv = "isci";
7619 else if (hba && hba->type == SYS_DEV_SATA)
7620 drv = "ahci";
7621 else
7622 drv = "unknown";
7623 dprintf("path: %s hba: %s attached: %s\n",
7624 path, (hba) ? hba->path : "NULL", drv);
7625 free(path);
7626 if (hba)
7627 free_sys_dev(&hba);
2cda7640 7628 }
96234762 7629 return drv;
2cda7640
ML
7630}
7631
78b10e66
N
7632static int imsm_find_array_minor_by_subdev(int subdev, int container, int *minor)
7633{
7634 char subdev_name[20];
7635 struct mdstat_ent *mdstat;
7636
7637 sprintf(subdev_name, "%d", subdev);
7638 mdstat = mdstat_by_subdev(subdev_name, container);
7639 if (!mdstat)
7640 return -1;
7641
7642 *minor = mdstat->devnum;
7643 free_mdstat(mdstat);
7644 return 0;
7645}
7646
7647static int imsm_reshape_is_allowed_on_container(struct supertype *st,
7648 struct geo_params *geo,
7649 int *old_raid_disks)
7650{
694575e7
KW
7651 /* currently we only support increasing the number of devices
7652 * for a container. This increases the number of device for each
7653 * member array. They must all be RAID0 or RAID5.
7654 */
78b10e66
N
7655 int ret_val = 0;
7656 struct mdinfo *info, *member;
7657 int devices_that_can_grow = 0;
7658
7659 dprintf("imsm: imsm_reshape_is_allowed_on_container(ENTER): "
7660 "st->devnum = (%i)\n",
7661 st->devnum);
7662
7663 if (geo->size != -1 ||
7664 geo->level != UnSet ||
7665 geo->layout != UnSet ||
7666 geo->chunksize != 0 ||
7667 geo->raid_disks == UnSet) {
7668 dprintf("imsm: Container operation is allowed for "
7669 "raid disks number change only.\n");
7670 return ret_val;
7671 }
7672
7673 info = container_content_imsm(st, NULL);
7674 for (member = info; member; member = member->next) {
7675 int result;
7676 int minor;
7677
7678 dprintf("imsm: checking device_num: %i\n",
7679 member->container_member);
7680
d7d205bd 7681 if (geo->raid_disks <= member->array.raid_disks) {
78b10e66
N
7682 /* we work on container for Online Capacity Expansion
7683 * only so raid_disks has to grow
7684 */
7685 dprintf("imsm: for container operation raid disks "
7686 "increase is required\n");
7687 break;
7688 }
7689
7690 if ((info->array.level != 0) &&
7691 (info->array.level != 5)) {
7692 /* we cannot use this container with other raid level
7693 */
690aae1a 7694 dprintf("imsm: for container operation wrong"
78b10e66
N
7695 " raid level (%i) detected\n",
7696 info->array.level);
7697 break;
7698 } else {
7699 /* check for platform support
7700 * for this raid level configuration
7701 */
7702 struct intel_super *super = st->sb;
7703 if (!is_raid_level_supported(super->orom,
7704 member->array.level,
7705 geo->raid_disks)) {
690aae1a 7706 dprintf("platform does not support raid%d with"
78b10e66
N
7707 " %d disk%s\n",
7708 info->array.level,
7709 geo->raid_disks,
7710 geo->raid_disks > 1 ? "s" : "");
7711 break;
7712 }
2a4a08e7
AK
7713 /* check if component size is aligned to chunk size
7714 */
7715 if (info->component_size %
7716 (info->array.chunk_size/512)) {
7717 dprintf("Component size is not aligned to "
7718 "chunk size\n");
7719 break;
7720 }
78b10e66
N
7721 }
7722
7723 if (*old_raid_disks &&
7724 info->array.raid_disks != *old_raid_disks)
7725 break;
7726 *old_raid_disks = info->array.raid_disks;
7727
7728 /* All raid5 and raid0 volumes in container
7729 * have to be ready for Online Capacity Expansion
7730 * so they need to be assembled. We have already
7731 * checked that no recovery etc is happening.
7732 */
7733 result = imsm_find_array_minor_by_subdev(member->container_member,
7734 st->container_dev,
7735 &minor);
7736 if (result < 0) {
7737 dprintf("imsm: cannot find array\n");
7738 break;
7739 }
7740 devices_that_can_grow++;
7741 }
7742 sysfs_free(info);
7743 if (!member && devices_that_can_grow)
7744 ret_val = 1;
7745
7746 if (ret_val)
7747 dprintf("\tContainer operation allowed\n");
7748 else
7749 dprintf("\tError: %i\n", ret_val);
7750
7751 return ret_val;
7752}
7753
7754/* Function: get_spares_for_grow
7755 * Description: Allocates memory and creates list of spare devices
7756 * avaliable in container. Checks if spare drive size is acceptable.
7757 * Parameters: Pointer to the supertype structure
7758 * Returns: Pointer to the list of spare devices (mdinfo structure) on success,
7759 * NULL if fail
7760 */
7761static struct mdinfo *get_spares_for_grow(struct supertype *st)
7762{
78b10e66 7763 unsigned long long min_size = min_acceptable_spare_size_imsm(st);
326727d9 7764 return container_choose_spares(st, min_size, NULL, NULL, NULL, 0);
78b10e66
N
7765}
7766
7767/******************************************************************************
7768 * function: imsm_create_metadata_update_for_reshape
7769 * Function creates update for whole IMSM container.
7770 *
7771 ******************************************************************************/
7772static int imsm_create_metadata_update_for_reshape(
7773 struct supertype *st,
7774 struct geo_params *geo,
7775 int old_raid_disks,
7776 struct imsm_update_reshape **updatep)
7777{
7778 struct intel_super *super = st->sb;
7779 struct imsm_super *mpb = super->anchor;
7780 int update_memory_size = 0;
7781 struct imsm_update_reshape *u = NULL;
7782 struct mdinfo *spares = NULL;
7783 int i;
7784 int delta_disks = 0;
bbd24d86 7785 struct mdinfo *dev;
78b10e66
N
7786
7787 dprintf("imsm_update_metadata_for_reshape(enter) raid_disks = %i\n",
7788 geo->raid_disks);
7789
7790 delta_disks = geo->raid_disks - old_raid_disks;
7791
7792 /* size of all update data without anchor */
7793 update_memory_size = sizeof(struct imsm_update_reshape);
7794
7795 /* now add space for spare disks that we need to add. */
7796 update_memory_size += sizeof(u->new_disks[0]) * (delta_disks - 1);
7797
7798 u = calloc(1, update_memory_size);
7799 if (u == NULL) {
7800 dprintf("error: "
7801 "cannot get memory for imsm_update_reshape update\n");
7802 return 0;
7803 }
7804 u->type = update_reshape_container_disks;
7805 u->old_raid_disks = old_raid_disks;
7806 u->new_raid_disks = geo->raid_disks;
7807
7808 /* now get spare disks list
7809 */
7810 spares = get_spares_for_grow(st);
7811
7812 if (spares == NULL
7813 || delta_disks > spares->array.spare_disks) {
e14e5960
KW
7814 fprintf(stderr, Name ": imsm: ERROR: Cannot get spare devices "
7815 "for %s.\n", geo->dev_name);
78b10e66
N
7816 goto abort;
7817 }
7818
7819 /* we have got spares
7820 * update disk list in imsm_disk list table in anchor
7821 */
7822 dprintf("imsm: %i spares are available.\n\n",
7823 spares->array.spare_disks);
7824
bbd24d86 7825 dev = spares->devs;
78b10e66 7826 for (i = 0; i < delta_disks; i++) {
78b10e66
N
7827 struct dl *dl;
7828
bbd24d86
AK
7829 if (dev == NULL)
7830 break;
78b10e66
N
7831 u->new_disks[i] = makedev(dev->disk.major,
7832 dev->disk.minor);
7833 dl = get_disk_super(super, dev->disk.major, dev->disk.minor);
ee4beede
AK
7834 dl->index = mpb->num_disks;
7835 mpb->num_disks++;
bbd24d86 7836 dev = dev->next;
78b10e66 7837 }
78b10e66
N
7838
7839abort:
7840 /* free spares
7841 */
7842 sysfs_free(spares);
7843
d677e0b8 7844 dprintf("imsm: reshape update preparation :");
78b10e66 7845 if (i == delta_disks) {
d677e0b8 7846 dprintf(" OK\n");
78b10e66
N
7847 *updatep = u;
7848 return update_memory_size;
7849 }
7850 free(u);
d677e0b8 7851 dprintf(" Error\n");
78b10e66
N
7852
7853 return 0;
7854}
7855
48c5303a
PC
7856/******************************************************************************
7857 * function: imsm_create_metadata_update_for_migration()
7858 * Creates update for IMSM array.
7859 *
7860 ******************************************************************************/
7861static int imsm_create_metadata_update_for_migration(
7862 struct supertype *st,
7863 struct geo_params *geo,
7864 struct imsm_update_reshape_migration **updatep)
7865{
7866 struct intel_super *super = st->sb;
7867 int update_memory_size = 0;
7868 struct imsm_update_reshape_migration *u = NULL;
7869 struct imsm_dev *dev;
7870 int previous_level = -1;
7871
7872 dprintf("imsm_create_metadata_update_for_migration(enter)"
7873 " New Level = %i\n", geo->level);
7874
7875 /* size of all update data without anchor */
7876 update_memory_size = sizeof(struct imsm_update_reshape_migration);
7877
7878 u = calloc(1, update_memory_size);
7879 if (u == NULL) {
7880 dprintf("error: cannot get memory for "
7881 "imsm_create_metadata_update_for_migration\n");
7882 return 0;
7883 }
7884 u->type = update_reshape_migration;
7885 u->subdev = super->current_vol;
7886 u->new_level = geo->level;
7887 u->new_layout = geo->layout;
7888 u->new_raid_disks = u->old_raid_disks = geo->raid_disks;
7889 u->new_disks[0] = -1;
4bba0439 7890 u->new_chunksize = -1;
48c5303a
PC
7891
7892 dev = get_imsm_dev(super, u->subdev);
7893 if (dev) {
7894 struct imsm_map *map;
7895
7896 map = get_imsm_map(dev, 0);
4bba0439
PC
7897 if (map) {
7898 int current_chunk_size =
7899 __le16_to_cpu(map->blocks_per_strip) / 2;
7900
7901 if (geo->chunksize != current_chunk_size) {
7902 u->new_chunksize = geo->chunksize / 1024;
7903 dprintf("imsm: "
7904 "chunk size change from %i to %i\n",
7905 current_chunk_size, u->new_chunksize);
7906 }
48c5303a 7907 previous_level = map->raid_level;
4bba0439 7908 }
48c5303a
PC
7909 }
7910 if ((geo->level == 5) && (previous_level == 0)) {
7911 struct mdinfo *spares = NULL;
7912
7913 u->new_raid_disks++;
7914 spares = get_spares_for_grow(st);
7915 if ((spares == NULL) || (spares->array.spare_disks < 1)) {
7916 free(u);
7917 sysfs_free(spares);
7918 update_memory_size = 0;
7919 dprintf("error: cannot get spare device "
7920 "for requested migration");
7921 return 0;
7922 }
7923 sysfs_free(spares);
7924 }
7925 dprintf("imsm: reshape update preparation : OK\n");
7926 *updatep = u;
7927
7928 return update_memory_size;
7929}
7930
8dd70bce
AK
7931static void imsm_update_metadata_locally(struct supertype *st,
7932 void *buf, int len)
7933{
7934 struct metadata_update mu;
7935
7936 mu.buf = buf;
7937 mu.len = len;
7938 mu.space = NULL;
7939 mu.space_list = NULL;
7940 mu.next = NULL;
7941 imsm_prepare_update(st, &mu);
7942 imsm_process_update(st, &mu);
7943
7944 while (mu.space_list) {
7945 void **space = mu.space_list;
7946 mu.space_list = *space;
7947 free(space);
7948 }
7949}
78b10e66 7950
471bceb6 7951/***************************************************************************
694575e7 7952* Function: imsm_analyze_change
471bceb6
KW
7953* Description: Function analyze change for single volume
7954* and validate if transition is supported
694575e7
KW
7955* Parameters: Geometry parameters, supertype structure
7956* Returns: Operation type code on success, -1 if fail
471bceb6
KW
7957****************************************************************************/
7958enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
7959 struct geo_params *geo)
694575e7 7960{
471bceb6
KW
7961 struct mdinfo info;
7962 int change = -1;
7963 int check_devs = 0;
c21e737b 7964 int chunk;
471bceb6
KW
7965
7966 getinfo_super_imsm_volume(st, &info, NULL);
7967
7968 if ((geo->level != info.array.level) &&
7969 (geo->level >= 0) &&
7970 (geo->level != UnSet)) {
7971 switch (info.array.level) {
7972 case 0:
7973 if (geo->level == 5) {
b5347799 7974 change = CH_MIGRATION;
471bceb6
KW
7975 check_devs = 1;
7976 }
7977 if (geo->level == 10) {
7978 change = CH_TAKEOVER;
7979 check_devs = 1;
7980 }
dfe77a9e
KW
7981 break;
7982 case 1:
7983 if (geo->level == 0) {
7984 change = CH_TAKEOVER;
7985 check_devs = 1;
7986 }
471bceb6 7987 break;
471bceb6
KW
7988 case 10:
7989 if (geo->level == 0) {
7990 change = CH_TAKEOVER;
7991 check_devs = 1;
7992 }
7993 break;
7994 }
7995 if (change == -1) {
7996 fprintf(stderr,
7997 Name " Error. Level Migration from %d to %d "
7998 "not supported!\n",
7999 info.array.level, geo->level);
8000 goto analyse_change_exit;
8001 }
8002 } else
8003 geo->level = info.array.level;
8004
8005 if ((geo->layout != info.array.layout)
8006 && ((geo->layout != UnSet) && (geo->layout != -1))) {
b5347799 8007 change = CH_MIGRATION;
471bceb6
KW
8008 if ((info.array.layout == 0)
8009 && (info.array.level == 5)
8010 && (geo->layout == 5)) {
8011 /* reshape 5 -> 4 */
8012 } else if ((info.array.layout == 5)
8013 && (info.array.level == 5)
8014 && (geo->layout == 0)) {
8015 /* reshape 4 -> 5 */
8016 geo->layout = 0;
8017 geo->level = 5;
8018 } else {
8019 fprintf(stderr,
8020 Name " Error. Layout Migration from %d to %d "
8021 "not supported!\n",
8022 info.array.layout, geo->layout);
8023 change = -1;
8024 goto analyse_change_exit;
8025 }
8026 } else
8027 geo->layout = info.array.layout;
8028
8029 if ((geo->chunksize > 0) && (geo->chunksize != UnSet)
8030 && (geo->chunksize != info.array.chunk_size))
b5347799 8031 change = CH_MIGRATION;
471bceb6
KW
8032 else
8033 geo->chunksize = info.array.chunk_size;
8034
c21e737b 8035 chunk = geo->chunksize / 1024;
471bceb6
KW
8036 if (!validate_geometry_imsm(st,
8037 geo->level,
8038 geo->layout,
8039 geo->raid_disks,
c21e737b 8040 &chunk,
471bceb6
KW
8041 geo->size,
8042 0, 0, 1))
8043 change = -1;
8044
8045 if (check_devs) {
8046 struct intel_super *super = st->sb;
8047 struct imsm_super *mpb = super->anchor;
8048
8049 if (mpb->num_raid_devs > 1) {
8050 fprintf(stderr,
8051 Name " Error. Cannot perform operation on %s"
8052 "- for this operation it MUST be single "
8053 "array in container\n",
8054 geo->dev_name);
8055 change = -1;
8056 }
8057 }
8058
8059analyse_change_exit:
8060
8061 return change;
694575e7
KW
8062}
8063
bb025c2f
KW
8064int imsm_takeover(struct supertype *st, struct geo_params *geo)
8065{
8066 struct intel_super *super = st->sb;
8067 struct imsm_update_takeover *u;
8068
8069 u = malloc(sizeof(struct imsm_update_takeover));
8070 if (u == NULL)
8071 return 1;
8072
8073 u->type = update_takeover;
8074 u->subarray = super->current_vol;
8075
8076 /* 10->0 transition */
8077 if (geo->level == 0)
8078 u->direction = R10_TO_R0;
8079
0529c688
KW
8080 /* 0->10 transition */
8081 if (geo->level == 10)
8082 u->direction = R0_TO_R10;
8083
bb025c2f
KW
8084 /* update metadata locally */
8085 imsm_update_metadata_locally(st, u,
8086 sizeof(struct imsm_update_takeover));
8087 /* and possibly remotely */
8088 if (st->update_tail)
8089 append_metadata_update(st, u,
8090 sizeof(struct imsm_update_takeover));
8091 else
8092 free(u);
8093
8094 return 0;
8095}
8096
6dc0be30
AK
8097static int warn_user_about_risk(void)
8098{
8099 int rv = 0;
8100
8101 fprintf(stderr,
8102 "\nThis is an experimental feature. Data on the RAID volume(s) "
8103 "can be lost!!!\n\n"
8104 "To continue command execution please make sure that\n"
8105 "the grow process will not be interrupted. Use safe power\n"
8106 "supply to avoid unexpected system reboot. Make sure that\n"
8107 "reshaped container is not assembled automatically during\n"
8108 "system boot.\n"
8109 "If reshape is interrupted, assemble array manually\n"
8110 "using e.g. '-Ac' option and up to date mdadm.conf file.\n"
8111 "Assembly in scan mode is not possible in such case.\n"
8112 "Growing container with boot array is not possible.\n"
8113 "If boot array reshape is interrupted, whole file system\n"
8114 "can be lost.\n\n");
8115 rv = ask("Do you want to continue? ");
8116 fprintf(stderr, "\n");
8117
8118 return rv;
8119}
8120
78b10e66
N
8121static int imsm_reshape_super(struct supertype *st, long long size, int level,
8122 int layout, int chunksize, int raid_disks,
41784c88
AK
8123 int delta_disks, char *backup, char *dev,
8124 int verbose)
78b10e66 8125{
78b10e66
N
8126 int ret_val = 1;
8127 struct geo_params geo;
8128
8129 dprintf("imsm: reshape_super called.\n");
8130
71204a50 8131 memset(&geo, 0, sizeof(struct geo_params));
78b10e66
N
8132
8133 geo.dev_name = dev;
694575e7 8134 geo.dev_id = st->devnum;
78b10e66
N
8135 geo.size = size;
8136 geo.level = level;
8137 geo.layout = layout;
8138 geo.chunksize = chunksize;
8139 geo.raid_disks = raid_disks;
41784c88
AK
8140 if (delta_disks != UnSet)
8141 geo.raid_disks += delta_disks;
78b10e66
N
8142
8143 dprintf("\tfor level : %i\n", geo.level);
8144 dprintf("\tfor raid_disks : %i\n", geo.raid_disks);
8145
8146 if (experimental() == 0)
8147 return ret_val;
8148
78b10e66 8149 if (st->container_dev == st->devnum) {
694575e7
KW
8150 /* On container level we can only increase number of devices. */
8151 dprintf("imsm: info: Container operation\n");
78b10e66 8152 int old_raid_disks = 0;
6dc0be30
AK
8153
8154 /* this warning will be removed when imsm checkpointing
8155 * will be implemented, and restoring from check-point
8156 * operation will be transparent for reboot process
8157 */
8158 if (warn_user_about_risk() == 0)
8159 return ret_val;
8160
78b10e66
N
8161 if (imsm_reshape_is_allowed_on_container(
8162 st, &geo, &old_raid_disks)) {
8163 struct imsm_update_reshape *u = NULL;
8164 int len;
8165
8166 len = imsm_create_metadata_update_for_reshape(
8167 st, &geo, old_raid_disks, &u);
8168
ed08d51c
AK
8169 if (len <= 0) {
8170 dprintf("imsm: Cannot prepare update\n");
8171 goto exit_imsm_reshape_super;
8172 }
8173
8dd70bce
AK
8174 ret_val = 0;
8175 /* update metadata locally */
8176 imsm_update_metadata_locally(st, u, len);
8177 /* and possibly remotely */
8178 if (st->update_tail)
8179 append_metadata_update(st, u, len);
8180 else
ed08d51c 8181 free(u);
8dd70bce 8182
694575e7 8183 } else {
e7ff7e40
AK
8184 fprintf(stderr, Name ": (imsm) Operation "
8185 "is not allowed on this container\n");
694575e7
KW
8186 }
8187 } else {
8188 /* On volume level we support following operations
471bceb6
KW
8189 * - takeover: raid10 -> raid0; raid0 -> raid10
8190 * - chunk size migration
8191 * - migration: raid5 -> raid0; raid0 -> raid5
8192 */
8193 struct intel_super *super = st->sb;
8194 struct intel_dev *dev = super->devlist;
8195 int change, devnum;
694575e7 8196 dprintf("imsm: info: Volume operation\n");
471bceb6
KW
8197 /* find requested device */
8198 while (dev) {
8199 imsm_find_array_minor_by_subdev(dev->index, st->container_dev, &devnum);
8200 if (devnum == geo.dev_id)
8201 break;
8202 dev = dev->next;
8203 }
8204 if (dev == NULL) {
8205 fprintf(stderr, Name " Cannot find %s (%i) subarray\n",
8206 geo.dev_name, geo.dev_id);
8207 goto exit_imsm_reshape_super;
8208 }
8209 super->current_vol = dev->index;
694575e7
KW
8210 change = imsm_analyze_change(st, &geo);
8211 switch (change) {
471bceb6 8212 case CH_TAKEOVER:
bb025c2f 8213 ret_val = imsm_takeover(st, &geo);
694575e7 8214 break;
48c5303a
PC
8215 case CH_MIGRATION: {
8216 struct imsm_update_reshape_migration *u = NULL;
8217 int len =
8218 imsm_create_metadata_update_for_migration(
8219 st, &geo, &u);
8220 if (len < 1) {
8221 dprintf("imsm: "
8222 "Cannot prepare update\n");
8223 break;
8224 }
471bceb6 8225 ret_val = 0;
48c5303a
PC
8226 /* update metadata locally */
8227 imsm_update_metadata_locally(st, u, len);
8228 /* and possibly remotely */
8229 if (st->update_tail)
8230 append_metadata_update(st, u, len);
8231 else
8232 free(u);
8233 }
8234 break;
471bceb6
KW
8235 default:
8236 ret_val = 1;
694575e7 8237 }
694575e7 8238 }
78b10e66 8239
ed08d51c 8240exit_imsm_reshape_super:
78b10e66
N
8241 dprintf("imsm: reshape_super Exit code = %i\n", ret_val);
8242 return ret_val;
8243}
2cda7640 8244
999b4972
N
8245static int imsm_manage_reshape(
8246 int afd, struct mdinfo *sra, struct reshape *reshape,
8247 struct supertype *st, unsigned long stripes,
8248 int *fds, unsigned long long *offsets,
8249 int dests, int *destfd, unsigned long long *destoffsets)
8250{
8251 /* Just use child_monitor for now */
8252 return child_monitor(
8253 afd, sra, reshape, st, stripes,
8254 fds, offsets, dests, destfd, destoffsets);
8255}
71204a50 8256#endif /* MDASSEMBLE */
999b4972 8257
cdddbdbc
DW
8258struct superswitch super_imsm = {
8259#ifndef MDASSEMBLE
8260 .examine_super = examine_super_imsm,
8261 .brief_examine_super = brief_examine_super_imsm,
4737ae25 8262 .brief_examine_subarrays = brief_examine_subarrays_imsm,
9d84c8ea 8263 .export_examine_super = export_examine_super_imsm,
cdddbdbc
DW
8264 .detail_super = detail_super_imsm,
8265 .brief_detail_super = brief_detail_super_imsm,
bf5a934a 8266 .write_init_super = write_init_super_imsm,
0e600426
N
8267 .validate_geometry = validate_geometry_imsm,
8268 .add_to_super = add_to_super_imsm,
1a64be56 8269 .remove_from_super = remove_from_super_imsm,
d665cc31 8270 .detail_platform = detail_platform_imsm,
33414a01 8271 .kill_subarray = kill_subarray_imsm,
aa534678 8272 .update_subarray = update_subarray_imsm,
2b959fbf 8273 .load_container = load_container_imsm,
71204a50
N
8274 .default_geometry = default_geometry_imsm,
8275 .get_disk_controller_domain = imsm_get_disk_controller_domain,
8276 .reshape_super = imsm_reshape_super,
8277 .manage_reshape = imsm_manage_reshape,
cdddbdbc
DW
8278#endif
8279 .match_home = match_home_imsm,
8280 .uuid_from_super= uuid_from_super_imsm,
8281 .getinfo_super = getinfo_super_imsm,
5c4cd5da 8282 .getinfo_super_disks = getinfo_super_disks_imsm,
cdddbdbc
DW
8283 .update_super = update_super_imsm,
8284
8285 .avail_size = avail_size_imsm,
80e7f8c3 8286 .min_acceptable_spare_size = min_acceptable_spare_size_imsm,
cdddbdbc
DW
8287
8288 .compare_super = compare_super_imsm,
8289
8290 .load_super = load_super_imsm,
bf5a934a 8291 .init_super = init_super_imsm,
e683ca88 8292 .store_super = store_super_imsm,
cdddbdbc
DW
8293 .free_super = free_super_imsm,
8294 .match_metadata_desc = match_metadata_desc_imsm,
bf5a934a 8295 .container_content = container_content_imsm,
cdddbdbc 8296
cdddbdbc 8297 .external = 1,
4cce4069 8298 .name = "imsm",
845dea95 8299
0e600426 8300#ifndef MDASSEMBLE
845dea95
NB
8301/* for mdmon */
8302 .open_new = imsm_open_new,
ed9d66aa 8303 .set_array_state= imsm_set_array_state,
845dea95
NB
8304 .set_disk = imsm_set_disk,
8305 .sync_metadata = imsm_sync_metadata,
88758e9d 8306 .activate_spare = imsm_activate_spare,
e8319a19 8307 .process_update = imsm_process_update,
8273f55e 8308 .prepare_update = imsm_prepare_update,
0e600426 8309#endif /* MDASSEMBLE */
cdddbdbc 8310};