~ubuntu-branches/ubuntu/precise/mdadm/precise-updates

« back to all changes in this revision

Viewing changes to super-intel.c

  • Committer: Package Import Robot
  • Author(s): Clint Byrum
  • Date: 2012-02-09 16:53:02 UTC
  • mfrom: (1.1.27 sid)
  • Revision ID: package-import@ubuntu.com-20120209165302-bs4cfosmhoga2rpt
Tags: 3.2.3-2ubuntu1
* Merge from Debian testing. (LP: #920324)  Remaining changes:
  - Call checks in local-premount to avoid race condition with udev
    and opening a degraded array.
  - d/initramfs/mdadm-functions: Record in /run when boot-degraded 
    question has been asked so that it is only asked once
  - pass --test to mdadm to enable result codes for degraded arrays. 
  - Build udeb with -O2 on ppc64, working around a link error.
  - debian/control: we need udev and util-linux in the right version. We
    also remove the build dependency from quilt and docbook-to-man as both
    are not used in Ubuntus mdadm.
  - debian/initramfs/hook: kept the Ubuntus version for handling the absence
    of active raid arrays in <initramfs>/etc/mdadm/mdadm.conf
  - debian/initramfs/script.local-top.DEBIAN, debian/mdadm-startall,
    debian/mdadm.raid.DEBIAN: removed. udev does its job now instead.
  - debian/mdadm-startall.sgml, debian/mdadm-startall.8: documentation of
    unused startall script
  - debian/mdadm.config, debian/mdadm.postinst - let udev do the handling
    instead. Resolved merge conflict by keeping Ubuntu's version.
  - debian/mdadm.postinst, debian/mdadm.config, initramfs/init-premount:
    boot-degraded enablement; maintain udev starting of RAID devices;
    init-premount hook script for the initramfs, to provide information at
    boot
  - debian/mkconf.in is the older mkconf. Kept the Ubuntu version.
  - debian/rules: Kept Ubuntus version for installing apport hooks, not
    installing un-used startall script and for adding a udev rule
    corresponding to mdadm.
  - debian/install-rc, check.d/_numbers, check.d/root_on_raid: Ubuntu partman
    installer changes
  - debian/presubj: Dropped this unused bug reporting file. Instead use
    source_mdadm.py act as an apport hook for bug handling.
  - rename debian/mdadm.vol_id.udev to debian/mdadm.mdadm-blkid.udev so that
    the rules file ends up with a more reasonable name
  - d/p/debian-changes-3.1.4-1+8efb9d1ubuntu4: mdadm udev rule
    incrementally adds mdadm member when detected. Starting such an
    array in degraded mode is possible by mdadm -IRs. Using mdadm
    -ARs without stopping the array first does nothing when no
    mdarray-unassociated device is available. Using mdadm -IRs to
    start a previously partially assembled array through incremental
    mode. Keeping the mdadm -ARs for assembling arrays which were for
    some reason not assembled through incremental mode (i.e through
    mdadm's udev rule).

Show diffs side-by-side

added added

removed removed

Lines of Context:
74
74
 
75
75
/* Define all supported attributes that have to be accepted by mdadm
76
76
 */
77
 
#define MPB_ATTRIB_SUPPORTED            MPB_ATTRIB_CHECKSUM_VERIFY | \
 
77
#define MPB_ATTRIB_SUPPORTED           (MPB_ATTRIB_CHECKSUM_VERIFY | \
78
78
                                        MPB_ATTRIB_2TB             | \
79
79
                                        MPB_ATTRIB_2TB_DISK        | \
80
80
                                        MPB_ATTRIB_RAID0           | \
81
81
                                        MPB_ATTRIB_RAID1           | \
82
82
                                        MPB_ATTRIB_RAID10          | \
83
83
                                        MPB_ATTRIB_RAID5           | \
84
 
                                        MPB_ATTRIB_EXP_STRIPE_SIZE
 
84
                                        MPB_ATTRIB_EXP_STRIPE_SIZE)
 
85
 
 
86
/* Define attributes that are unused but not harmful */
 
87
#define MPB_ATTRIB_IGNORED              (MPB_ATTRIB_NEVER_USE)
85
88
 
86
89
#define MPB_SECTOR_CNT 2210
87
90
#define IMSM_RESERVED_SECTORS 4096
 
91
#define NUM_BLOCKS_DIRTY_STRIPE_REGION 2056
88
92
#define SECT_PER_MB_SHIFT 11
89
93
 
90
94
/* Disk configuration info. */
102
106
        __u32 filler[IMSM_DISK_FILLERS]; /* 0xF4 - 0x107 MPB_DISK_FILLERS for future expansion */
103
107
};
104
108
 
 
109
/* map selector for map managment
 
110
 */
 
111
#define MAP_0           0
 
112
#define MAP_1           1
 
113
#define MAP_X           -1
 
114
 
105
115
/* RAID map configuration infos. */
106
116
struct imsm_map {
107
117
        __u32 pba_of_lba0;      /* start address of partition */
230
240
 
231
241
#define GEN_MIGR_AREA_SIZE 2048 /* General Migration Copy Area size in blocks */
232
242
 
 
243
#define MIGR_REC_BUF_SIZE 512 /* size of migr_record i/o buffer */
 
244
#define MIGR_REC_POSITION 512 /* migr_record position offset on disk,
 
245
                               * MIGR_REC_BUF_SIZE <= MIGR_REC_POSITION
 
246
                               */
 
247
 
 
248
 
233
249
#define UNIT_SRC_NORMAL     0   /* Source data for curr_migr_unit must
234
250
                                 *  be recovered using srcMap */
235
251
#define UNIT_SRC_IN_CP_AREA 1   /* Source data for curr_migr_unit has
341
357
                struct extent *e; /* for determining freespace @ create */
342
358
                int raiddisk; /* slot to fill in autolayout */
343
359
                enum action action;
344
 
        } *disks;
 
360
        } *disks, *current_disk;
345
361
        struct dl *disk_mgmt_list; /* list of disks to add/remove while mdmon
346
362
                                      active */
347
363
        struct dl *missing; /* disks removed while we weren't looking */
658
674
{
659
675
        /* A device can have 2 maps if it is in the middle of a migration.
660
676
         * If second_map is:
661
 
         *    0   - we return the first map
662
 
         *    1   - we return the second map if it exists, else NULL
663
 
         *   -1   - we return the second map if it exists, else the first
 
677
         *    MAP_0 - we return the first map
 
678
         *    MAP_1 - we return the second map if it exists, else NULL
 
679
         *    MAP_X - we return the second map if it exists, else the first
664
680
         */
665
681
        struct imsm_map *map = &dev->vol.map[0];
666
 
 
667
 
        if (second_map == 1 && !dev->vol.migr_state)
668
 
                return NULL;
669
 
        else if (second_map == 1 ||
670
 
                 (second_map < 0 && dev->vol.migr_state)) {
671
 
                void *ptr = map;
672
 
 
673
 
                return ptr + sizeof_imsm_map(map);
674
 
        } else
675
 
                return map;
 
682
        struct imsm_map *map2 = NULL;
 
683
 
 
684
        if (dev->vol.migr_state)
 
685
                map2 = (void *)map + sizeof_imsm_map(map);
 
686
 
 
687
        switch (second_map) {
 
688
        case MAP_0:
 
689
                break;
 
690
        case MAP_1:
 
691
                map = map2;
 
692
                break;
 
693
        case MAP_X:
 
694
                if (map2)
 
695
                        map = map2;
 
696
                break;
 
697
        default:
 
698
                map = NULL;
 
699
        }
 
700
        return map;
676
701
 
677
702
}
678
703
 
682
707
static size_t sizeof_imsm_dev(struct imsm_dev *dev, int migr_state)
683
708
{
684
709
        size_t size = sizeof(*dev) - sizeof(struct imsm_map) +
685
 
                      sizeof_imsm_map(get_imsm_map(dev, 0));
 
710
                      sizeof_imsm_map(get_imsm_map(dev, MAP_0));
686
711
 
687
712
        /* migrating means an additional map */
688
713
        if (dev->vol.migr_state)
689
 
                size += sizeof_imsm_map(get_imsm_map(dev, 1));
 
714
                size += sizeof_imsm_map(get_imsm_map(dev, MAP_1));
690
715
        else if (migr_state)
691
 
                size += sizeof_imsm_map(get_imsm_map(dev, 0));
 
716
                size += sizeof_imsm_map(get_imsm_map(dev, MAP_0));
692
717
 
693
718
        return size;
694
719
}
742
767
 
743
768
/*
744
769
 * for second_map:
745
 
 *  == 0 get first map
746
 
 *  == 1 get second map
747
 
 *  == -1 than get map according to the current migr_state
 
770
 *  == MAP_0 get first map
 
771
 *  == MAP_1 get second map
 
772
 *  == MAP_X than get map according to the current migr_state
748
773
 */
749
774
static __u32 get_imsm_ord_tbl_ent(struct imsm_dev *dev,
750
775
                                  int slot,
815
840
 
816
841
        for (i = 0; i < super->anchor->num_raid_devs; i++) {
817
842
                struct imsm_dev *dev = get_imsm_dev(super, i);
818
 
                struct imsm_map *map = get_imsm_map(dev, 0);
 
843
                struct imsm_map *map = get_imsm_map(dev, MAP_0);
819
844
 
820
845
                if (get_imsm_disk_slot(map, dl->index) >= 0)
821
846
                        memberships++;
824
849
        return memberships;
825
850
}
826
851
 
 
852
static __u32 imsm_min_reserved_sectors(struct intel_super *super);
 
853
 
827
854
static struct extent *get_extents(struct intel_super *super, struct dl *dl)
828
855
{
829
856
        /* find a list of used extents on the given physical device */
830
857
        struct extent *rv, *e;
831
858
        int i;
832
859
        int memberships = count_memberships(dl, super);
833
 
        __u32 reservation = MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS;
 
860
        __u32 reservation;
 
861
 
 
862
        /* trim the reserved area for spares, so they can join any array
 
863
         * regardless of whether the OROM has assigned sectors from the
 
864
         * IMSM_RESERVED_SECTORS region
 
865
         */
 
866
        if (dl->index == -1)
 
867
                reservation = imsm_min_reserved_sectors(super);
 
868
        else
 
869
                reservation = MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS;
834
870
 
835
871
        rv = malloc(sizeof(struct extent) * (memberships + 1));
836
872
        if (!rv)
839
875
 
840
876
        for (i = 0; i < super->anchor->num_raid_devs; i++) {
841
877
                struct imsm_dev *dev = get_imsm_dev(super, i);
842
 
                struct imsm_map *map = get_imsm_map(dev, 0);
 
878
                struct imsm_map *map = get_imsm_map(dev, MAP_0);
843
879
 
844
880
                if (get_imsm_disk_slot(map, dl->index) >= 0) {
845
881
                        e->start = __le32_to_cpu(map->pba_of_lba0);
921
957
        return (disk->status & FAILED_DISK) == FAILED_DISK;
922
958
}
923
959
 
 
960
/* try to determine how much space is reserved for metadata from
 
961
 * the last get_extents() entry on the smallest active disk,
 
962
 * otherwise fallback to the default
 
963
 */
 
964
static __u32 imsm_min_reserved_sectors(struct intel_super *super)
 
965
{
 
966
        struct extent *e;
 
967
        int i;
 
968
        __u32 min_active, remainder;
 
969
        __u32 rv = MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS;
 
970
        struct dl *dl, *dl_min = NULL;
 
971
 
 
972
        if (!super)
 
973
                return rv;
 
974
 
 
975
        min_active = 0;
 
976
        for (dl = super->disks; dl; dl = dl->next) {
 
977
                if (dl->index < 0)
 
978
                        continue;
 
979
                if (dl->disk.total_blocks < min_active || min_active == 0) {
 
980
                        dl_min = dl;
 
981
                        min_active = dl->disk.total_blocks;
 
982
                }
 
983
        }
 
984
        if (!dl_min)
 
985
                return rv;
 
986
 
 
987
        /* find last lba used by subarrays on the smallest active disk */
 
988
        e = get_extents(super, dl_min);
 
989
        if (!e)
 
990
                return rv;
 
991
        for (i = 0; e[i].size; i++)
 
992
                continue;
 
993
 
 
994
        remainder = min_active - e[i].start;
 
995
        free(e);
 
996
 
 
997
        /* to give priority to recovery we should not require full
 
998
           IMSM_RESERVED_SECTORS from the spare */
 
999
        rv = MPB_SECTOR_CNT + NUM_BLOCKS_DIRTY_STRIPE_REGION;
 
1000
 
 
1001
        /* if real reservation is smaller use that value */
 
1002
        return  (remainder < rv) ? remainder : rv;
 
1003
}
 
1004
 
924
1005
/* Return minimum size of a spare that can be used in this array*/
925
1006
static unsigned long long min_acceptable_spare_size_imsm(struct supertype *st)
926
1007
{
947
1028
        if (i > 0)
948
1029
                rv = e[i-1].start + e[i-1].size;
949
1030
        free(e);
 
1031
 
950
1032
        /* add the amount of space needed for metadata */
951
 
        rv = rv + MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS;
 
1033
        rv = rv + imsm_min_reserved_sectors(super);
 
1034
 
952
1035
        return rv * 512;
953
1036
}
954
1037
 
 
1038
static int is_gen_migration(struct imsm_dev *dev);
 
1039
 
955
1040
#ifndef MDASSEMBLE
956
1041
static __u64 blocks_per_migr_unit(struct intel_super *super,
957
1042
                                  struct imsm_dev *dev);
963
1048
{
964
1049
        __u64 sz;
965
1050
        int slot, i;
966
 
        struct imsm_map *map = get_imsm_map(dev, 0);
967
 
        struct imsm_map *map2 = get_imsm_map(dev, 1);
 
1051
        struct imsm_map *map = get_imsm_map(dev, MAP_0);
 
1052
        struct imsm_map *map2 = get_imsm_map(dev, MAP_1);
968
1053
        __u32 ord;
969
1054
 
970
1055
        printf("\n");
980
1065
        printf("\n");
981
1066
        printf("          Slots : [");
982
1067
        for (i = 0; i < map->num_members; i++) {
983
 
                ord = get_imsm_ord_tbl_ent(dev, i, 0);
 
1068
                ord = get_imsm_ord_tbl_ent(dev, i, MAP_0);
984
1069
                printf("%s", ord & IMSM_ORD_REBUILD ? "_" : "U");
985
1070
        }
986
1071
        printf("]");
987
1072
        if (map2) {
988
1073
                printf(" <-- [");
989
1074
                for (i = 0; i < map2->num_members; i++) {
990
 
                        ord = get_imsm_ord_tbl_ent(dev, i, 1);
 
1075
                        ord = get_imsm_ord_tbl_ent(dev, i, MAP_1);
991
1076
                        printf("%s", ord & IMSM_ORD_REBUILD ? "_" : "U");
992
1077
                }
993
1078
                printf("]");
1001
1086
        printf("\n");
1002
1087
        slot = get_imsm_disk_slot(map, disk_idx);
1003
1088
        if (slot >= 0) {
1004
 
                ord = get_imsm_ord_tbl_ent(dev, slot, -1);
 
1089
                ord = get_imsm_ord_tbl_ent(dev, slot, MAP_X);
1005
1090
                printf("      This Slot : %d%s\n", slot,
1006
1091
                       ord & IMSM_ORD_REBUILD ? " (out-of-sync)" : "");
1007
1092
        } else
1045
1130
                printf("idle\n");
1046
1131
        printf("      Map State : %s", map_state_str[map->map_state]);
1047
1132
        if (dev->vol.migr_state) {
1048
 
                struct imsm_map *map = get_imsm_map(dev, 1);
 
1133
                struct imsm_map *map = get_imsm_map(dev, MAP_1);
1049
1134
 
1050
1135
                printf(" <-- %s", map_state_str[map->map_state]);
1051
 
                printf("\n     Checkpoint : %u (%llu)",
1052
 
                       __le32_to_cpu(dev->vol.curr_migr_unit),
1053
 
                       (unsigned long long)blocks_per_migr_unit(super, dev));
 
1136
                printf("\n     Checkpoint : %u ",
 
1137
                           __le32_to_cpu(dev->vol.curr_migr_unit));
 
1138
                if ((is_gen_migration(dev)) && ((slot > 1) || (slot < 0)))
 
1139
                        printf("(N/A)");
 
1140
                else
 
1141
                        printf("(%llu)", (unsigned long long)
 
1142
                                   blocks_per_migr_unit(super, dev));
1054
1143
        }
1055
1144
        printf("\n");
1056
1145
        printf("    Dirty State : %s\n", dev->vol.dirty ? "dirty" : "clean");
1057
1146
}
1058
1147
 
1059
 
static void print_imsm_disk(struct imsm_super *mpb, int index, __u32 reserved)
 
1148
static void print_imsm_disk(struct imsm_disk *disk, int index, __u32 reserved)
1060
1149
{
1061
 
        struct imsm_disk *disk = __get_imsm_disk(mpb, index);
1062
1150
        char str[MAX_RAID_SERIAL_LEN + 1];
1063
1151
        __u64 sz;
1064
1152
 
1065
 
        if (index < 0 || !disk)
 
1153
        if (index < -1 || !disk)
1066
1154
                return;
1067
1155
 
1068
1156
        printf("\n");
1069
1157
        snprintf(str, MAX_RAID_SERIAL_LEN + 1, "%s", disk->serial);
1070
 
        printf("  Disk%02d Serial : %s\n", index, str);
 
1158
        if (index >= 0)
 
1159
                printf("  Disk%02d Serial : %s\n", index, str);
 
1160
        else
 
1161
                printf("    Disk Serial : %s\n", str);
1071
1162
        printf("          State :%s%s%s\n", is_spare(disk) ? " spare" : "",
1072
1163
                                            is_configured(disk) ? " active" : "",
1073
1164
                                            is_failed(disk) ? " failed" : "");
1077
1168
               human_size(sz * 512));
1078
1169
}
1079
1170
 
1080
 
static int is_gen_migration(struct imsm_dev *dev);
1081
 
 
1082
1171
void examine_migr_rec_imsm(struct intel_super *super)
1083
1172
{
1084
1173
        struct migr_record *migr_rec = super->migr_rec;
1087
1176
 
1088
1177
        for (i = 0; i < mpb->num_raid_devs; i++) {
1089
1178
                struct imsm_dev *dev = __get_imsm_dev(mpb, i);
 
1179
                struct imsm_map *map;
 
1180
                int slot = -1;
 
1181
 
1090
1182
                if (is_gen_migration(dev) == 0)
1091
1183
                                continue;
1092
1184
 
1093
1185
                printf("\nMigration Record Information:");
1094
 
                if (super->disks->index > 1) {
 
1186
 
 
1187
                /* first map under migration */
 
1188
                map = get_imsm_map(dev, MAP_0);
 
1189
                if (map)
 
1190
                        slot = get_imsm_disk_slot(map, super->disks->index);
 
1191
                if ((map == NULL) || (slot > 1) || (slot < 0)) {
1095
1192
                        printf(" Empty\n                              ");
1096
1193
                        printf("Examine one of first two disks in array\n");
1097
1194
                        break;
1141
1238
static int imsm_check_attributes(__u32 attributes)
1142
1239
{
1143
1240
        int ret_val = 1;
1144
 
        __u32 not_supported = (MPB_ATTRIB_SUPPORTED)^0xffffffff;
 
1241
        __u32 not_supported = MPB_ATTRIB_SUPPORTED^0xffffffff;
 
1242
 
 
1243
        not_supported &= ~MPB_ATTRIB_IGNORED;
1145
1244
 
1146
1245
        not_supported &= attributes;
1147
1246
        if (not_supported) {
1148
 
                fprintf(stderr, Name "(IMSM): Unsupported attributes : %x\n", not_supported);
 
1247
                fprintf(stderr, Name "(IMSM): Unsupported attributes : %x\n",
 
1248
                        (unsigned)__le32_to_cpu(not_supported));
1149
1249
                if (not_supported & MPB_ATTRIB_CHECKSUM_VERIFY) {
1150
1250
                        dprintf("\t\tMPB_ATTRIB_CHECKSUM_VERIFY \n");
1151
1251
                        not_supported ^= MPB_ATTRIB_CHECKSUM_VERIFY;
1248
1348
        printf("    MPB Sectors : %d\n", mpb_sectors(mpb));
1249
1349
        printf("          Disks : %d\n", mpb->num_disks);
1250
1350
        printf("   RAID Devices : %d\n", mpb->num_raid_devs);
1251
 
        print_imsm_disk(mpb, super->disks->index, reserved);
 
1351
        print_imsm_disk(__get_imsm_disk(mpb, super->disks->index), super->disks->index, reserved);
1252
1352
        if (super->bbm_log) {
1253
1353
                struct bbm_log *log = super->bbm_log;
1254
1354
 
1273
1373
        for (i = 0; i < mpb->num_disks; i++) {
1274
1374
                if (i == super->disks->index)
1275
1375
                        continue;
1276
 
                print_imsm_disk(mpb, i, reserved);
1277
 
        }
1278
 
        for (dl = super->disks ; dl; dl = dl->next) {
1279
 
                struct imsm_disk *disk;
1280
 
                char str[MAX_RAID_SERIAL_LEN + 1];
1281
 
                __u64 sz;
1282
 
 
1283
 
                if (dl->index >= 0)
1284
 
                        continue;
1285
 
 
1286
 
                disk = &dl->disk;
1287
 
                printf("\n");
1288
 
                snprintf(str, MAX_RAID_SERIAL_LEN + 1, "%s", disk->serial);
1289
 
                printf("    Disk Serial : %s\n", str);
1290
 
                printf("          State :%s%s%s\n", is_spare(disk) ? " spare" : "",
1291
 
                       is_configured(disk) ? " active" : "",
1292
 
                       is_failed(disk) ? " failed" : "");
1293
 
                printf("             Id : %08x\n", __le32_to_cpu(disk->scsi_id));
1294
 
                sz = __le32_to_cpu(disk->total_blocks) - reserved;
1295
 
                printf("    Usable Size : %llu%s\n", (unsigned long long)sz,
1296
 
                       human_size(sz * 512));
1297
 
        }
 
1376
                print_imsm_disk(__get_imsm_disk(mpb, i), i, reserved);
 
1377
        }
 
1378
 
 
1379
        for (dl = super->disks; dl; dl = dl->next)
 
1380
                if (dl->index == -1)
 
1381
                        print_imsm_disk(&dl->disk, -1, reserved);
1298
1382
 
1299
1383
        examine_migr_rec_imsm(super);
1300
1384
}
1518
1602
                        fd2devname(fd, buf);
1519
1603
                        printf("          Port%d : %s", port, buf);
1520
1604
                        if (imsm_read_serial(fd, NULL, (__u8 *) buf) == 0)
1521
 
                                printf(" (%s)\n", buf);
 
1605
                                printf(" (%.*s)\n", MAX_RAID_SERIAL_LEN, buf);
1522
1606
                        else
1523
 
                                printf("()\n");
 
1607
                                printf(" ()\n");
 
1608
                        close(fd);
1524
1609
                }
1525
 
                close(fd);
1526
1610
                free(path);
1527
1611
                path = NULL;
1528
1612
        }
1789
1873
static __u32 migr_strip_blocks_resync(struct imsm_dev *dev)
1790
1874
{
1791
1875
        /* migr_strip_size when repairing or initializing parity */
1792
 
        struct imsm_map *map = get_imsm_map(dev, 0);
 
1876
        struct imsm_map *map = get_imsm_map(dev, MAP_0);
1793
1877
        __u32 chunk = __le32_to_cpu(map->blocks_per_strip);
1794
1878
 
1795
1879
        switch (get_imsm_raid_level(map)) {
1807
1891
         * this is different than migr_strip_size_resync(), but it's good
1808
1892
         * to be compatible
1809
1893
         */
1810
 
        struct imsm_map *map = get_imsm_map(dev, 1);
 
1894
        struct imsm_map *map = get_imsm_map(dev, MAP_1);
1811
1895
        __u32 chunk = __le32_to_cpu(map->blocks_per_strip);
1812
1896
 
1813
1897
        switch (get_imsm_raid_level(map)) {
1826
1910
 
1827
1911
static __u32 num_stripes_per_unit_resync(struct imsm_dev *dev)
1828
1912
{
1829
 
        struct imsm_map *lo = get_imsm_map(dev, 0);
1830
 
        struct imsm_map *hi = get_imsm_map(dev, 1);
 
1913
        struct imsm_map *lo = get_imsm_map(dev, MAP_0);
 
1914
        struct imsm_map *hi = get_imsm_map(dev, MAP_1);
1831
1915
        __u32 lo_chunk = __le32_to_cpu(lo->blocks_per_strip);
1832
1916
        __u32 hi_chunk = __le32_to_cpu(hi->blocks_per_strip);
1833
1917
 
1836
1920
 
1837
1921
static __u32 num_stripes_per_unit_rebuild(struct imsm_dev *dev)
1838
1922
{
1839
 
        struct imsm_map *lo = get_imsm_map(dev, 0);
 
1923
        struct imsm_map *lo = get_imsm_map(dev, MAP_0);
1840
1924
        int level = get_imsm_raid_level(lo);
1841
1925
 
1842
1926
        if (level == 1 || level == 10) {
1843
 
                struct imsm_map *hi = get_imsm_map(dev, 1);
 
1927
                struct imsm_map *hi = get_imsm_map(dev, MAP_1);
1844
1928
 
1845
1929
                return hi->num_domains;
1846
1930
        } else
1869
1953
 
1870
1954
static __u32 parity_segment_depth(struct imsm_dev *dev)
1871
1955
{
1872
 
        struct imsm_map *map = get_imsm_map(dev, 0);
 
1956
        struct imsm_map *map = get_imsm_map(dev, MAP_0);
1873
1957
        __u32 chunk =  __le32_to_cpu(map->blocks_per_strip);
1874
1958
 
1875
1959
        switch(get_imsm_raid_level(map)) {
1885
1969
 
1886
1970
static __u32 map_migr_block(struct imsm_dev *dev, __u32 block)
1887
1971
{
1888
 
        struct imsm_map *map = get_imsm_map(dev, 1);
 
1972
        struct imsm_map *map = get_imsm_map(dev, MAP_1);
1889
1973
        __u32 chunk = __le32_to_cpu(map->blocks_per_strip);
1890
1974
        __u32 strip = block / chunk;
1891
1975
 
1924
2008
        case MIGR_VERIFY:
1925
2009
        case MIGR_REPAIR:
1926
2010
        case MIGR_INIT: {
1927
 
                struct imsm_map *map = get_imsm_map(dev, 0);
 
2011
                struct imsm_map *map = get_imsm_map(dev, MAP_0);
1928
2012
                __u32 stripes_per_unit;
1929
2013
                __u32 blocks_per_unit;
1930
2014
                __u32 parity_depth;
1940
2024
                 */
1941
2025
                stripes_per_unit = num_stripes_per_unit_resync(dev);
1942
2026
                migr_chunk = migr_strip_blocks_resync(dev);
1943
 
                disks = imsm_num_data_members(dev, 0);
 
2027
                disks = imsm_num_data_members(dev, MAP_0);
1944
2028
                blocks_per_unit = stripes_per_unit * migr_chunk * disks;
1945
2029
                stripe = __le16_to_cpu(map->blocks_per_strip) * disks;
1946
2030
                segment = blocks_per_unit / stripe;
1994
2078
        unsigned long long dsize;
1995
2079
 
1996
2080
        get_dev_size(fd, NULL, &dsize);
1997
 
        if (lseek64(fd, dsize - 512, SEEK_SET) < 0) {
 
2081
        if (lseek64(fd, dsize - MIGR_REC_POSITION, SEEK_SET) < 0) {
1998
2082
                fprintf(stderr,
1999
2083
                        Name ": Cannot seek to anchor block: %s\n",
2000
2084
                        strerror(errno));
2001
2085
                goto out;
2002
2086
        }
2003
 
        if (read(fd, super->migr_rec_buf, 512) != 512) {
 
2087
        if (read(fd, super->migr_rec_buf, MIGR_REC_BUF_SIZE) !=
 
2088
                                                            MIGR_REC_BUF_SIZE) {
2004
2089
                fprintf(stderr,
2005
2090
                        Name ": Cannot read migr record block: %s\n",
2006
2091
                        strerror(errno));
2012
2097
        return ret_val;
2013
2098
}
2014
2099
 
 
2100
static struct imsm_dev *imsm_get_device_during_migration(
 
2101
        struct intel_super *super)
 
2102
{
 
2103
 
 
2104
        struct intel_dev *dv;
 
2105
 
 
2106
        for (dv = super->devlist; dv; dv = dv->next) {
 
2107
                if (is_gen_migration(dv->dev))
 
2108
                        return dv->dev;
 
2109
        }
 
2110
        return NULL;
 
2111
}
 
2112
 
2015
2113
/*******************************************************************************
2016
2114
 * Function:    load_imsm_migr_rec
2017
2115
 * Description: Function reads imsm migration record (it is stored at the last
2022
2120
 * Returns:
2023
2121
 *       0 : success
2024
2122
 *      -1 : fail
 
2123
 *      -2 : no migration in progress
2025
2124
 ******************************************************************************/
2026
2125
static int load_imsm_migr_rec(struct intel_super *super, struct mdinfo *info)
2027
2126
{
2030
2129
        char nm[30];
2031
2130
        int retval = -1;
2032
2131
        int fd = -1;
 
2132
        struct imsm_dev *dev;
 
2133
        struct imsm_map *map = NULL;
 
2134
        int slot = -1;
 
2135
 
 
2136
        /* find map under migration */
 
2137
        dev = imsm_get_device_during_migration(super);
 
2138
        /* nothing to load,no migration in progress?
 
2139
        */
 
2140
        if (dev == NULL)
 
2141
                return -2;
 
2142
        map = get_imsm_map(dev, MAP_0);
2033
2143
 
2034
2144
        if (info) {
2035
2145
                for (sd = info->devs ; sd ; sd = sd->next) {
 
2146
                        /* skip spare and failed disks
 
2147
                         */
 
2148
                        if (sd->disk.raid_disk < 0)
 
2149
                                continue;
2036
2150
                        /* read only from one of the first two slots */
2037
 
                        if ((sd->disk.raid_disk > 1) ||
2038
 
                            (sd->disk.raid_disk < 0))
 
2151
                        if (map)
 
2152
                                slot = get_imsm_disk_slot(map,
 
2153
                                                          sd->disk.raid_disk);
 
2154
                        if ((map == NULL) || (slot > 1) || (slot < 0))
2039
2155
                                continue;
 
2156
 
2040
2157
                        sprintf(nm, "%d:%d", sd->disk.major, sd->disk.minor);
2041
2158
                        fd = dev_open(nm, O_RDONLY);
2042
2159
                        if (fd >= 0)
2045
2162
        }
2046
2163
        if (fd < 0) {
2047
2164
                for (dl = super->disks; dl; dl = dl->next) {
 
2165
                        /* skip spare and failed disks
 
2166
                        */
 
2167
                        if (dl->index < 0)
 
2168
                                continue;
2048
2169
                        /* read only from one of the first two slots */
2049
 
                        if (dl->index > 1)
 
2170
                        if (map)
 
2171
                                slot = get_imsm_disk_slot(map, dl->index);
 
2172
                        if ((map == NULL) || (slot > 1) || (slot < 0))
2050
2173
                                continue;
2051
2174
                        sprintf(nm, "%d:%d", dl->major, dl->minor);
2052
2175
                        fd = dev_open(nm, O_RDONLY);
2130
2253
        struct dl *sd;
2131
2254
        int len;
2132
2255
        struct imsm_update_general_migration_checkpoint *u;
 
2256
        struct imsm_dev *dev;
 
2257
        struct imsm_map *map = NULL;
 
2258
 
 
2259
        /* find map under migration */
 
2260
        dev = imsm_get_device_during_migration(super);
 
2261
        /* if no migration, write buffer anyway to clear migr_record
 
2262
         * on disk based on first available device
 
2263
        */
 
2264
        if (dev == NULL)
 
2265
                dev = get_imsm_dev(super, super->current_vol < 0 ? 0 :
 
2266
                                          super->current_vol);
 
2267
 
 
2268
        map = get_imsm_map(dev, MAP_0);
2133
2269
 
2134
2270
        for (sd = super->disks ; sd ; sd = sd->next) {
 
2271
                int slot = -1;
 
2272
 
 
2273
                /* skip failed and spare devices */
 
2274
                if (sd->index < 0)
 
2275
                        continue;
2135
2276
                /* write to 2 first slots only */
2136
 
                if ((sd->index < 0) || (sd->index > 1))
 
2277
                if (map)
 
2278
                        slot = get_imsm_disk_slot(map, sd->index);
 
2279
                if ((map == NULL) || (slot > 1) || (slot < 0))
2137
2280
                        continue;
 
2281
 
2138
2282
                sprintf(nm, "%d:%d", sd->major, sd->minor);
2139
2283
                fd = dev_open(nm, O_RDWR);
2140
2284
                if (fd < 0)
2141
2285
                        continue;
2142
2286
                get_dev_size(fd, NULL, &dsize);
2143
 
                if (lseek64(fd, dsize - 512, SEEK_SET) < 0) {
 
2287
                if (lseek64(fd, dsize - MIGR_REC_POSITION, SEEK_SET) < 0) {
2144
2288
                        fprintf(stderr,
2145
2289
                                Name ": Cannot seek to anchor block: %s\n",
2146
2290
                                strerror(errno));
2147
2291
                        goto out;
2148
2292
                }
2149
 
                if (write(fd, super->migr_rec_buf, 512) != 512) {
 
2293
                if (write(fd, super->migr_rec_buf, MIGR_REC_BUF_SIZE) !=
 
2294
                                                            MIGR_REC_BUF_SIZE) {
2150
2295
                        fprintf(stderr,
2151
2296
                                Name ": Cannot write migr record block: %s\n",
2152
2297
                                strerror(errno));
2184
2329
}
2185
2330
#endif /* MDASSEMBLE */
2186
2331
 
 
2332
/* spare/missing disks activations are not allowe when
 
2333
 * array/container performs reshape operation, because
 
2334
 * all arrays in container works on the same disks set
 
2335
 */
 
2336
int imsm_reshape_blocks_arrays_changes(struct intel_super *super)
 
2337
{
 
2338
        int rv = 0;
 
2339
        struct intel_dev *i_dev;
 
2340
        struct imsm_dev *dev;
 
2341
 
 
2342
        /* check whole container
 
2343
         */
 
2344
        for (i_dev = super->devlist; i_dev; i_dev = i_dev->next) {
 
2345
                dev = i_dev->dev;
 
2346
                if (is_gen_migration(dev)) {
 
2347
                        /* No repair during any migration in container
 
2348
                         */
 
2349
                        rv = 1;
 
2350
                        break;
 
2351
                }
 
2352
        }
 
2353
        return rv;
 
2354
}
 
2355
 
2187
2356
static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info, char *dmap)
2188
2357
{
2189
2358
        struct intel_super *super = st->sb;
2190
2359
        struct migr_record *migr_rec = super->migr_rec;
2191
2360
        struct imsm_dev *dev = get_imsm_dev(super, super->current_vol);
2192
 
        struct imsm_map *map = get_imsm_map(dev, 0);
2193
 
        struct imsm_map *prev_map = get_imsm_map(dev, 1);
 
2361
        struct imsm_map *map = get_imsm_map(dev, MAP_0);
 
2362
        struct imsm_map *prev_map = get_imsm_map(dev, MAP_1);
2194
2363
        struct imsm_map *map_to_analyse = map;
2195
2364
        struct dl *dl;
2196
2365
        char *devname;
2201
2370
        if (prev_map)
2202
2371
                map_to_analyse = prev_map;
2203
2372
 
2204
 
        dl = super->disks;
 
2373
        dl = super->current_disk;
2205
2374
 
2206
2375
        info->container_member    = super->current_vol;
2207
2376
        info->array.raid_disks    = map->num_members;
2216
2385
        info->custom_array_size   = __le32_to_cpu(dev->size_high);
2217
2386
        info->custom_array_size   <<= 32;
2218
2387
        info->custom_array_size   |= __le32_to_cpu(dev->size_low);
2219
 
        if (prev_map && map->map_state == prev_map->map_state) {
 
2388
        info->recovery_blocked = imsm_reshape_blocks_arrays_changes(st->sb);
 
2389
 
 
2390
        if (is_gen_migration(dev)) {
2220
2391
                info->reshape_active = 1;
2221
2392
                info->new_level = get_imsm_raid_level(map);
2222
2393
                info->new_layout = imsm_level_to_layout(info->new_level);
2226
2397
                        /* this needs to be applied to every array
2227
2398
                         * in the container.
2228
2399
                         */
2229
 
                        info->reshape_active = 2;
 
2400
                        info->reshape_active = CONTAINER_RESHAPE;
2230
2401
                }
2231
2402
                /* We shape information that we give to md might have to be
2232
2403
                 * modify to cope with md's requirement for reshaping arrays.
2263
2434
                info->new_chunk = info->array.chunk_size;
2264
2435
                info->delta_disks = 0;
2265
2436
        }
2266
 
        info->disk.major = 0;
2267
 
        info->disk.minor = 0;
 
2437
 
2268
2438
        if (dl) {
2269
2439
                info->disk.major = dl->major;
2270
2440
                info->disk.minor = dl->minor;
 
2441
                info->disk.number = dl->index;
 
2442
                info->disk.raid_disk = get_imsm_disk_slot(map_to_analyse,
 
2443
                                                          dl->index);
2271
2444
        }
2272
2445
 
2273
2446
        info->data_offset         = __le32_to_cpu(map_to_analyse->pba_of_lba0);
2293
2466
 
2294
2467
        info->reshape_progress = 0;
2295
2468
        info->resync_start = MaxSector;
2296
 
        if (map_to_analyse->map_state == IMSM_T_STATE_UNINITIALIZED ||
2297
 
            dev->vol.dirty) {
 
2469
        if ((map_to_analyse->map_state == IMSM_T_STATE_UNINITIALIZED ||
 
2470
            dev->vol.dirty) &&
 
2471
            imsm_reshape_blocks_arrays_changes(super) == 0) {
2298
2472
                info->resync_start = 0;
2299
2473
        }
2300
2474
        if (dev->vol.migr_state) {
2326
2500
 
2327
2501
                        dprintf("IMSM: General Migration checkpoint : %llu "
2328
2502
                               "(%llu) -> read reshape progress : %llu\n",
2329
 
                                units, blocks_per_unit, info->reshape_progress);
 
2503
                                (unsigned long long)units,
 
2504
                                (unsigned long long)blocks_per_unit,
 
2505
                                info->reshape_progress);
2330
2506
 
2331
 
                        used_disks = imsm_num_data_members(dev, 1);
 
2507
                        used_disks = imsm_num_data_members(dev, MAP_1);
2332
2508
                        if (used_disks > 0) {
2333
2509
                                array_blocks = map->blocks_per_member *
2334
2510
                                        used_disks;
2373
2549
                        dmap[i] = 0;
2374
2550
                        if (i < info->array.raid_disks) {
2375
2551
                                struct imsm_disk *dsk;
2376
 
                                j = get_imsm_disk_idx(dev, i, -1);
 
2552
                                j = get_imsm_disk_idx(dev, i, MAP_X);
2377
2553
                                dsk = get_imsm_disk(super, j);
2378
2554
                                if (dsk && (dsk->status & CONFIGURED_DISK))
2379
2555
                                        dmap[i] = 1;
2382
2558
        }
2383
2559
}
2384
2560
 
2385
 
static __u8 imsm_check_degraded(struct intel_super *super, struct imsm_dev *dev, int failed);
2386
 
static int imsm_count_failed(struct intel_super *super, struct imsm_dev *dev);
 
2561
static __u8 imsm_check_degraded(struct intel_super *super, struct imsm_dev *dev,
 
2562
                                int failed, int look_in_map);
 
2563
 
 
2564
static int imsm_count_failed(struct intel_super *super, struct imsm_dev *dev,
 
2565
                             int look_in_map);
 
2566
 
 
2567
 
 
2568
#ifndef MDASSEMBLE
 
2569
static void manage_second_map(struct intel_super *super, struct imsm_dev *dev)
 
2570
{
 
2571
        if (is_gen_migration(dev)) {
 
2572
                int failed;
 
2573
                __u8 map_state;
 
2574
                struct imsm_map *map2 = get_imsm_map(dev, MAP_1);
 
2575
 
 
2576
                failed = imsm_count_failed(super, dev, MAP_1);
 
2577
                map_state = imsm_check_degraded(super, dev, failed, MAP_1);
 
2578
                if (map2->map_state != map_state) {
 
2579
                        map2->map_state = map_state;
 
2580
                        super->updates_pending++;
 
2581
                }
 
2582
        }
 
2583
}
 
2584
#endif
2387
2585
 
2388
2586
static struct imsm_disk *get_imsm_missing(struct intel_super *super, __u8 index)
2389
2587
{
2433
2631
        info->disk.state = 0;
2434
2632
        info->name[0] = 0;
2435
2633
        info->recovery_start = MaxSector;
 
2634
        info->recovery_blocked = imsm_reshape_blocks_arrays_changes(st->sb);
2436
2635
 
2437
2636
        /* do we have the all the insync disks that we expect? */
2438
2637
        mpb = super->anchor;
2443
2642
                struct imsm_map *map;
2444
2643
                __u8 state;
2445
2644
 
2446
 
                failed = imsm_count_failed(super, dev);
2447
 
                state = imsm_check_degraded(super, dev, failed);
2448
 
                map = get_imsm_map(dev, dev->vol.migr_state);
 
2645
                failed = imsm_count_failed(super, dev, MAP_0);
 
2646
                state = imsm_check_degraded(super, dev, failed, MAP_0);
 
2647
                map = get_imsm_map(dev, MAP_0);
2449
2648
 
2450
2649
                /* any newly missing disks?
2451
2650
                 * (catches single-degraded vs double-degraded)
2452
2651
                 */
2453
2652
                for (j = 0; j < map->num_members; j++) {
2454
 
                        __u32 ord = get_imsm_ord_tbl_ent(dev, i, -1);
 
2653
                        __u32 ord = get_imsm_ord_tbl_ent(dev, j, MAP_0);
2455
2654
                        __u32 idx = ord_to_idx(ord);
2456
2655
 
2457
2656
                        if (!(ord & IMSM_ORD_REBUILD) &&
2592
2791
 
2593
2792
        mpb = super->anchor;
2594
2793
 
2595
 
        if (strcmp(update, "uuid") == 0 && uuid_set && !info->update_private)
2596
 
                rv = -1;
2597
 
        else if (strcmp(update, "uuid") == 0 && uuid_set && info->update_private) {
2598
 
                mpb->orig_family_num = *((__u32 *) info->update_private);
2599
 
                rv = 0;
2600
 
        } else if (strcmp(update, "uuid") == 0) {
2601
 
                __u32 *new_family = malloc(sizeof(*new_family));
2602
 
 
2603
 
                /* update orig_family_number with the incoming random
2604
 
                 * data, report the new effective uuid, and store the
2605
 
                 * new orig_family_num for future updates.
 
2794
        if (strcmp(update, "uuid") == 0) {
 
2795
                /* We take this to mean that the family_num should be updated.
 
2796
                 * However that is much smaller than the uuid so we cannot really
 
2797
                 * allow an explicit uuid to be given.  And it is hard to reliably
 
2798
                 * know if one was.
 
2799
                 * So if !uuid_set we know the current uuid is random and just used
 
2800
                 * the first 'int' and copy it to the other 3 positions.
 
2801
                 * Otherwise we require the 4 'int's to be the same as would be the
 
2802
                 * case if we are using a random uuid.  So an explicit uuid will be
 
2803
                 * accepted as long as all for ints are the same... which shouldn't hurt
2606
2804
                 */
2607
 
                if (new_family) {
2608
 
                        memcpy(&mpb->orig_family_num, info->uuid, sizeof(__u32));
2609
 
                        uuid_from_super_imsm(st, info->uuid);
2610
 
                        *new_family = mpb->orig_family_num;
2611
 
                        info->update_private = new_family;
 
2805
                if (!uuid_set) {
 
2806
                        info->uuid[1] = info->uuid[2] = info->uuid[3] = info->uuid[0];
2612
2807
                        rv = 0;
 
2808
                } else {
 
2809
                        if (info->uuid[0] != info->uuid[1] ||
 
2810
                            info->uuid[1] != info->uuid[2] ||
 
2811
                            info->uuid[2] != info->uuid[3])
 
2812
                                rv = -1;
 
2813
                        else
 
2814
                                rv = 0;
2613
2815
                }
 
2816
                if (rv == 0)
 
2817
                        mpb->orig_family_num = info->uuid[0];
2614
2818
        } else if (strcmp(update, "assemble") == 0)
2615
2819
                rv = 0;
2616
2820
        else
2778
2982
        sprintf(path, "/sys/dev/block/%d:%d",
2779
2983
                major(st.st_rdev), minor(st.st_rdev));
2780
2984
 
2781
 
        rv = readlink(path, dname, sizeof(dname));
 
2985
        rv = readlink(path, dname, sizeof(dname)-1);
2782
2986
        if (rv <= 0)
2783
2987
                return;
2784
2988
        
2785
2989
        dname[rv] = '\0';
2786
2990
        nm = strrchr(dname, '/');
2787
 
        nm++;
2788
 
        snprintf(name, MAX_RAID_SERIAL_LEN, "/dev/%s", nm);
 
2991
        if (nm) {
 
2992
                nm++;
 
2993
                snprintf(name, MAX_RAID_SERIAL_LEN, "/dev/%s", nm);
 
2994
        }
2789
2995
}
2790
2996
 
2791
2997
extern int scsi_get_serial(int fd, void *buf, size_t buf_len);
2870
3076
        strncpy((char *) dest, (char *) src, MAX_RAID_SERIAL_LEN);
2871
3077
}
2872
3078
 
2873
 
#ifndef MDASSEMBLE
2874
3079
static struct dl *serial_to_dl(__u8 *serial, struct intel_super *super)
2875
3080
{
2876
3081
        struct dl *dl;
2881
3086
 
2882
3087
        return dl;
2883
3088
}
2884
 
#endif
2885
3089
 
2886
3090
static struct imsm_disk *
2887
3091
__serial_to_disk(__u8 *serial, struct imsm_super *mpb, int *idx)
2978
3182
                    __u8 to_state, int migr_type)
2979
3183
{
2980
3184
        struct imsm_map *dest;
2981
 
        struct imsm_map *src = get_imsm_map(dev, 0);
 
3185
        struct imsm_map *src = get_imsm_map(dev, MAP_0);
2982
3186
 
2983
3187
        dev->vol.migr_state = 1;
2984
3188
        set_migr_type(dev, migr_type);
2985
3189
        dev->vol.curr_migr_unit = 0;
2986
 
        dest = get_imsm_map(dev, 1);
 
3190
        dest = get_imsm_map(dev, MAP_1);
2987
3191
 
2988
3192
        /* duplicate and then set the target end state in map[0] */
2989
3193
        memcpy(dest, src, sizeof_imsm_map(src));
3005
3209
        src->map_state = to_state;
3006
3210
}
3007
3211
 
3008
 
static void end_migration(struct imsm_dev *dev, __u8 map_state)
 
3212
static void end_migration(struct imsm_dev *dev, struct intel_super *super,
 
3213
                          __u8 map_state)
3009
3214
{
3010
 
        struct imsm_map *map = get_imsm_map(dev, 0);
3011
 
        struct imsm_map *prev = get_imsm_map(dev, dev->vol.migr_state);
 
3215
        struct imsm_map *map = get_imsm_map(dev, MAP_0);
 
3216
        struct imsm_map *prev = get_imsm_map(dev, dev->vol.migr_state == 0 ?
 
3217
                                                    MAP_0 : MAP_1);
3012
3218
        int i, j;
3013
3219
 
3014
3220
        /* merge any IMSM_ORD_REBUILD bits that were not successfully
3016
3222
         *
3017
3223
         * FIXME add support for raid-level-migration
3018
3224
         */
3019
 
        for (i = 0; i < prev->num_members; i++)
3020
 
                for (j = 0; j < map->num_members; j++)
3021
 
                        /* during online capacity expansion
3022
 
                         * disks position can be changed if takeover is used
3023
 
                         */
3024
 
                        if (ord_to_idx(map->disk_ord_tbl[j]) ==
3025
 
                            ord_to_idx(prev->disk_ord_tbl[i])) {
3026
 
                                map->disk_ord_tbl[j] |= prev->disk_ord_tbl[i];
3027
 
                                break;
3028
 
                        }
 
3225
        if ((map_state != map->map_state) && (is_gen_migration(dev) == 0) &&
 
3226
                (prev->map_state != IMSM_T_STATE_UNINITIALIZED)) {
 
3227
                /* when final map state is other than expected
 
3228
                 * merge maps (not for migration)
 
3229
                 */
 
3230
                int failed;
 
3231
 
 
3232
                for (i = 0; i < prev->num_members; i++)
 
3233
                        for (j = 0; j < map->num_members; j++)
 
3234
                                /* during online capacity expansion
 
3235
                                 * disks position can be changed
 
3236
                                 * if takeover is used
 
3237
                                 */
 
3238
                                if (ord_to_idx(map->disk_ord_tbl[j]) ==
 
3239
                                    ord_to_idx(prev->disk_ord_tbl[i])) {
 
3240
                                        map->disk_ord_tbl[j] |=
 
3241
                                                prev->disk_ord_tbl[i];
 
3242
                                        break;
 
3243
                                }
 
3244
                failed = imsm_count_failed(super, dev, MAP_0);
 
3245
                map_state = imsm_check_degraded(super, dev, failed, MAP_0);
 
3246
        }
3029
3247
 
3030
3248
        dev->vol.migr_state = 0;
3031
 
        dev->vol.migr_type = 0;
 
3249
        set_migr_type(dev, 0);
3032
3250
        dev->vol.curr_migr_unit = 0;
3033
3251
        map->map_state = map_state;
3034
3252
}
3128
3346
                    dev_iter->vol.migr_state == 1 &&
3129
3347
                    dev_iter->vol.migr_type == MIGR_GEN_MIGR) {
3130
3348
                        /* This device is migrating */
3131
 
                        map0 = get_imsm_map(dev_iter, 0);
3132
 
                        map1 = get_imsm_map(dev_iter, 1);
 
3349
                        map0 = get_imsm_map(dev_iter, MAP_0);
 
3350
                        map1 = get_imsm_map(dev_iter, MAP_1);
3133
3351
                        if (map0->pba_of_lba0 != map1->pba_of_lba0)
3134
3352
                                /* migration optimization area was used */
3135
3353
                                return -1;
3215
3433
        sectors = mpb_sectors(anchor) - 1;
3216
3434
        free(anchor);
3217
3435
 
3218
 
        if (posix_memalign(&super->migr_rec_buf, 512, 512) != 0) {
 
3436
        if (posix_memalign(&super->migr_rec_buf, 512, MIGR_REC_BUF_SIZE) != 0) {
3219
3437
                fprintf(stderr, Name
3220
3438
                        ": %s could not allocate migr_rec buffer\n", __func__);
3221
3439
                free(super->buf);
3439
3657
        return 0;
3440
3658
}
3441
3659
 
3442
 
#ifndef MDASSEMBLE
3443
3660
/* find_missing - helper routine for load_super_imsm_all that identifies
3444
3661
 * disks that have disappeared from the system.  This routine relies on
3445
3662
 * the mpb being uptodate, which it is at load time.
3475
3692
        return 0;
3476
3693
}
3477
3694
 
 
3695
#ifndef MDASSEMBLE
3478
3696
static struct intel_disk *disk_list_get(__u8 *serial, struct intel_disk *disk_list)
3479
3697
{
3480
3698
        struct intel_disk *idisk = disk_list;
3867
4085
 
3868
4086
        /* load migration record */
3869
4087
        err = load_imsm_migr_rec(super, NULL);
3870
 
        if (err) {
 
4088
        if (err == -1) {
 
4089
                /* migration is in progress,
 
4090
                 * but migr_rec cannot be loaded,
 
4091
                 */
3871
4092
                err = 4;
3872
4093
                goto error;
3873
4094
        }
3874
4095
 
3875
4096
        /* Check migration compatibility */
3876
 
        if (check_mpb_migr_compatibility(super) != 0) {
 
4097
        if ((err == 0) && (check_mpb_migr_compatibility(super) != 0)) {
3877
4098
                fprintf(stderr, Name ": Unsupported migration detected");
3878
4099
                if (devname)
3879
4100
                        fprintf(stderr, " on %s\n", devname);
4016
4237
 
4017
4238
        for (i = 0; i < mpb->num_raid_devs; i++) {
4018
4239
                dev = get_imsm_dev(super, i);
4019
 
                map = get_imsm_map(dev, 0);
 
4240
                map = get_imsm_map(dev, MAP_0);
4020
4241
                if (__le32_to_cpu(dev->size_high) > 0)
4021
4242
                        mpb->attributes |= MPB_ATTRIB_2TB;
4022
4243
 
4112
4333
                        fprintf(stderr, Name": could not allocate new mpb\n");
4113
4334
                        return 0;
4114
4335
                }
4115
 
                if (posix_memalign(&super->migr_rec_buf, 512, 512) != 0) {
 
4336
                if (posix_memalign(&super->migr_rec_buf, 512,
 
4337
                                   MIGR_REC_BUF_SIZE) != 0) {
4116
4338
                        fprintf(stderr, Name
4117
4339
                                ": %s could not allocate migr_rec buffer\n",
4118
4340
                                __func__);
4119
4341
                        free(super->buf);
4120
4342
                        free(super);
 
4343
                        free(mpb_new);
4121
4344
                        return 0;
4122
4345
                }
4123
4346
                memcpy(mpb_new, mpb, size_old);
4128
4351
                memset(mpb_new + size_old, 0, size_round - size_old);
4129
4352
        }
4130
4353
        super->current_vol = idx;
4131
 
        /* when creating the first raid device in this container set num_disks
4132
 
         * to zero, i.e. delete this spare and add raid member devices in
4133
 
         * add_to_super_imsm_volume()
 
4354
 
 
4355
        /* handle 'failed_disks' by either:
 
4356
         * a) create dummy disk entries in the table if this the first
 
4357
         *    volume in the array.  We add them here as this is the only
 
4358
         *    opportunity to add them. add_to_super_imsm_volume()
 
4359
         *    handles the non-failed disks and continues incrementing
 
4360
         *    mpb->num_disks.
 
4361
         * b) validate that 'failed_disks' matches the current number
 
4362
         *    of missing disks if the container is populated
4134
4363
         */
4135
 
        if (super->current_vol == 0)
 
4364
        if (super->current_vol == 0) {
4136
4365
                mpb->num_disks = 0;
 
4366
                for (i = 0; i < info->failed_disks; i++) {
 
4367
                        struct imsm_disk *disk;
 
4368
 
 
4369
                        mpb->num_disks++;
 
4370
                        disk = __get_imsm_disk(mpb, i);
 
4371
                        disk->status = CONFIGURED_DISK | FAILED_DISK;
 
4372
                        disk->scsi_id = __cpu_to_le32(~(__u32)0);
 
4373
                        snprintf((char *) disk->serial, MAX_RAID_SERIAL_LEN,
 
4374
                                 "missing:%d", i);
 
4375
                }
 
4376
                find_missing(super);
 
4377
        } else {
 
4378
                int missing = 0;
 
4379
                struct dl *d;
 
4380
 
 
4381
                for (d = super->missing; d; d = d->next)
 
4382
                        missing++;
 
4383
                if (info->failed_disks > missing) {
 
4384
                        fprintf(stderr, Name": unable to add 'missing' disk to container\n");
 
4385
                        return 0;
 
4386
                }
 
4387
        }
4137
4388
 
4138
4389
        if (!check_name(super, name, 0))
4139
4390
                return 0;
4165
4416
        vol = &dev->vol;
4166
4417
        vol->migr_state = 0;
4167
4418
        set_migr_type(dev, MIGR_INIT);
4168
 
        vol->dirty = 0;
 
4419
        vol->dirty = !info->state;
4169
4420
        vol->curr_migr_unit = 0;
4170
 
        map = get_imsm_map(dev, 0);
 
4421
        map = get_imsm_map(dev, MAP_0);
4171
4422
        map->pba_of_lba0 = __cpu_to_le32(super->create_offset);
4172
4423
        map->blocks_per_member = __cpu_to_le32(info_to_blocks_per_member(info));
4173
4424
        map->blocks_per_strip = __cpu_to_le16(info_to_blocks_per_strip(info));
4174
4425
        map->failed_disk_num = ~0;
4175
 
        map->map_state = info->level ? IMSM_T_STATE_UNINITIALIZED :
4176
 
                                       IMSM_T_STATE_NORMAL;
 
4426
        if (info->level > 0)
 
4427
                map->map_state = IMSM_T_STATE_UNINITIALIZED;
 
4428
        else
 
4429
                map->map_state = info->failed_disks ? IMSM_T_STATE_FAILED :
 
4430
                                                      IMSM_T_STATE_NORMAL;
4177
4431
        map->ddf = 1;
4178
4432
 
4179
4433
        if (info->level == 1 && info->raid_disks > 2) {
4248
4502
                        ": %s could not allocate superblock\n", __func__);
4249
4503
                return 0;
4250
4504
        }
4251
 
        if (posix_memalign(&super->migr_rec_buf, 512, 512) != 0) {
 
4505
        if (posix_memalign(&super->migr_rec_buf, 512, MIGR_REC_BUF_SIZE) != 0) {
4252
4506
                fprintf(stderr, Name
4253
4507
                        ": %s could not allocate migr_rec buffer\n", __func__);
4254
4508
                free(super->buf);
4281
4535
{
4282
4536
        struct intel_super *super = st->sb;
4283
4537
        struct imsm_super *mpb = super->anchor;
4284
 
        struct dl *dl;
 
4538
        struct imsm_disk *_disk;
4285
4539
        struct imsm_dev *dev;
4286
4540
        struct imsm_map *map;
 
4541
        struct dl *dl, *df;
4287
4542
        int slot;
4288
4543
 
4289
4544
        dev = get_imsm_dev(super, super->current_vol);
4290
 
        map = get_imsm_map(dev, 0);
 
4545
        map = get_imsm_map(dev, MAP_0);
4291
4546
 
4292
4547
        if (! (dk->state & (1<<MD_DISK_SYNC))) {
4293
4548
                fprintf(stderr, Name ": %s: Cannot add spare devices to IMSM volume\n",
4322
4577
        /* Check the device has not already been added */
4323
4578
        slot = get_imsm_disk_slot(map, dl->index);
4324
4579
        if (slot >= 0 &&
4325
 
            (get_imsm_ord_tbl_ent(dev, slot, -1) & IMSM_ORD_REBUILD) == 0) {
 
4580
            (get_imsm_ord_tbl_ent(dev, slot, MAP_X) & IMSM_ORD_REBUILD) == 0) {
4326
4581
                fprintf(stderr, Name ": %s has been included in this array twice\n",
4327
4582
                        devname);
4328
4583
                return 1;
4329
4584
        }
4330
 
        set_imsm_ord_tbl_ent(map, dk->number, dl->index);
 
4585
        set_imsm_ord_tbl_ent(map, dk->raid_disk, dl->index);
4331
4586
        dl->disk.status = CONFIGURED_DISK;
4332
4587
 
 
4588
        /* update size of 'missing' disks to be at least as large as the
 
4589
         * largest acitve member (we only have dummy missing disks when
 
4590
         * creating the first volume)
 
4591
         */
 
4592
        if (super->current_vol == 0) {
 
4593
                for (df = super->missing; df; df = df->next) {
 
4594
                        if (dl->disk.total_blocks > df->disk.total_blocks)
 
4595
                                df->disk.total_blocks = dl->disk.total_blocks;
 
4596
                        _disk = __get_imsm_disk(mpb, df->index);
 
4597
                        *_disk = df->disk;
 
4598
                }
 
4599
        }
 
4600
 
 
4601
        /* refresh unset/failed slots to point to valid 'missing' entries */
 
4602
        for (df = super->missing; df; df = df->next)
 
4603
                for (slot = 0; slot < mpb->num_disks; slot++) {
 
4604
                        __u32 ord = get_imsm_ord_tbl_ent(dev, slot, MAP_X);
 
4605
 
 
4606
                        if ((ord & IMSM_ORD_REBUILD) == 0)
 
4607
                                continue;
 
4608
                        set_imsm_ord_tbl_ent(map, slot, df->index | IMSM_ORD_REBUILD);
 
4609
                        if (is_gen_migration(dev)) {
 
4610
                                struct imsm_map *map2 = get_imsm_map(dev,
 
4611
                                                                     MAP_1);
 
4612
                                int slot2 = get_imsm_disk_slot(map2, df->index);
 
4613
                                if ((slot2 < map2->num_members) &&
 
4614
                                    (slot2 >= 0)) {
 
4615
                                        __u32 ord2 = get_imsm_ord_tbl_ent(dev,
 
4616
                                                                         slot2,
 
4617
                                                                         MAP_1);
 
4618
                                        if ((unsigned)df->index ==
 
4619
                                                               ord_to_idx(ord2))
 
4620
                                                set_imsm_ord_tbl_ent(map2,
 
4621
                                                        slot2,
 
4622
                                                        df->index |
 
4623
                                                        IMSM_ORD_REBUILD);
 
4624
                                }
 
4625
                        }
 
4626
                        dprintf("set slot:%d to missing disk:%d\n", slot, df->index);
 
4627
                        break;
 
4628
                }
 
4629
 
4333
4630
        /* if we are creating the first raid device update the family number */
4334
4631
        if (super->current_vol == 0) {
4335
4632
                __u32 sum;
4336
4633
                struct imsm_dev *_dev = __get_imsm_dev(mpb, 0);
4337
 
                struct imsm_disk *_disk = __get_imsm_disk(mpb, dl->index);
4338
4634
 
 
4635
                _disk = __get_imsm_disk(mpb, dl->index);
4339
4636
                if (!_dev || !_disk) {
4340
4637
                        fprintf(stderr, Name ": BUG mpb setup error\n");
4341
4638
                        return 1;
4347
4644
                mpb->family_num = __cpu_to_le32(sum);
4348
4645
                mpb->orig_family_num = mpb->family_num;
4349
4646
        }
4350
 
 
 
4647
        super->current_disk = dl;
4351
4648
        return 0;
4352
4649
}
4353
4650
 
 
4651
/* mark_spare()
 
4652
 *   Function marks disk as spare and restores disk serial
 
4653
 *   in case it was previously marked as failed by takeover operation
 
4654
 * reruns:
 
4655
 *   -1 : critical error
 
4656
 *    0 : disk is marked as spare but serial is not set
 
4657
 *    1 : success
 
4658
 */
 
4659
int mark_spare(struct dl *disk)
 
4660
{
 
4661
        __u8 serial[MAX_RAID_SERIAL_LEN];
 
4662
        int ret_val = -1;
 
4663
 
 
4664
        if (!disk)
 
4665
                return ret_val;
 
4666
 
 
4667
        ret_val = 0;
 
4668
        if (!imsm_read_serial(disk->fd, NULL, serial)) {
 
4669
                /* Restore disk serial number, because takeover marks disk
 
4670
                 * as failed and adds to serial ':0' before it becomes
 
4671
                 * a spare disk.
 
4672
                 */
 
4673
                serialcpy(disk->serial, serial);
 
4674
                serialcpy(disk->disk.serial, serial);
 
4675
                ret_val = 1;
 
4676
        }
 
4677
        disk->disk.status = SPARE_DISK;
 
4678
        disk->index = -1;
 
4679
 
 
4680
        return ret_val;
 
4681
}
4354
4682
 
4355
4683
static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
4356
4684
                             int fd, char *devname)
4388
4716
        memset(dd, 0, sizeof(*dd));
4389
4717
        dd->major = major(stb.st_rdev);
4390
4718
        dd->minor = minor(stb.st_rdev);
4391
 
        dd->index = -1;
4392
4719
        dd->devname = devname ? strdup(devname) : NULL;
4393
4720
        dd->fd = fd;
4394
4721
        dd->e = NULL;
4405
4732
        size /= 512;
4406
4733
        serialcpy(dd->disk.serial, dd->serial);
4407
4734
        dd->disk.total_blocks = __cpu_to_le32(size);
4408
 
        dd->disk.status = SPARE_DISK;
 
4735
        mark_spare(dd);
4409
4736
        if (sysfs_disk_to_scsi_id(fd, &id) == 0)
4410
4737
                dd->disk.scsi_id = __cpu_to_le32(id);
4411
4738
        else
4448
4775
        memset(dd, 0, sizeof(*dd));
4449
4776
        dd->major = dk->major;
4450
4777
        dd->minor = dk->minor;
4451
 
        dd->index = -1;
4452
4778
        dd->fd = -1;
4453
 
        dd->disk.status = SPARE_DISK;
 
4779
        mark_spare(dd);
4454
4780
        dd->action = DISK_REMOVE;
4455
4781
 
4456
4782
        dd->next = super->disk_mgmt_list;
4570
4896
        mpb->check_sum = __cpu_to_le32(sum);
4571
4897
 
4572
4898
        if (clear_migration_record)
4573
 
                memset(super->migr_rec_buf, 0, 512);
 
4899
                memset(super->migr_rec_buf, 0, MIGR_REC_BUF_SIZE);
4574
4900
 
4575
4901
        /* write the mpb for disks that compose raid devices */
4576
4902
        for (d = super->disks; d ; d = d->next) {
4577
 
                if (d->index < 0)
 
4903
                if (d->index < 0 || is_failed(&d->disk))
4578
4904
                        continue;
4579
4905
                if (store_imsm_mpb(d->fd, mpb))
4580
4906
                        fprintf(stderr, "%s: failed for device %d:%d %s\n",
4584
4910
 
4585
4911
                        get_dev_size(d->fd, NULL, &dsize);
4586
4912
                        if (lseek64(d->fd, dsize - 512, SEEK_SET) >= 0) {
4587
 
                                if (write(d->fd, super->migr_rec_buf, 512) != 512)
 
4913
                                if (write(d->fd, super->migr_rec_buf,
 
4914
                                        MIGR_REC_BUF_SIZE) != MIGR_REC_BUF_SIZE)
4588
4915
                                        perror("Write migr_rec failed");
4589
4916
                        }
4590
4917
                }
4607
4934
        struct imsm_update_create_array *u;
4608
4935
        struct intel_super *super = st->sb;
4609
4936
        struct imsm_dev *dev = get_imsm_dev(super, dev_idx);
4610
 
        struct imsm_map *map = get_imsm_map(dev, 0);
 
4937
        struct imsm_map *map = get_imsm_map(dev, MAP_0);
4611
4938
        struct disk_info *inf;
4612
4939
        struct imsm_disk *disk;
4613
4940
        int i;
4626
4953
        imsm_copy_dev(&u->dev, dev);
4627
4954
        inf = get_disk_info(u);
4628
4955
        for (i = 0; i < map->num_members; i++) {
4629
 
                int idx = get_imsm_disk_idx(dev, i, -1);
 
4956
                int idx = get_imsm_disk_idx(dev, i, MAP_X);
4630
4957
 
4631
4958
                disk = get_imsm_disk(super, idx);
4632
4959
                serialcpy(inf[i].serial, disk->serial);
4912
5239
        return 0;
4913
5240
}
4914
5241
 
 
5242
static int imsm_default_chunk(const struct imsm_orom *orom)
 
5243
{
 
5244
        /* up to 512 if the plaform supports it, otherwise the platform max.
 
5245
         * 128 if no platform detected
 
5246
         */
 
5247
        int fs = max(7, orom ? fls(orom->sss) : 0);
 
5248
 
 
5249
        return min(512, (1 << fs));
 
5250
}
4915
5251
 
4916
5252
#define pr_vrb(fmt, arg...) (void) (verbose && fprintf(stderr, Name fmt, ##arg))
4917
 
/*
4918
 
 * validate volume parameters with OROM/EFI capabilities
4919
 
 */
4920
5253
static int
4921
5254
validate_geometry_imsm_orom(struct intel_super *super, int level, int layout,
4922
5255
                            int raiddisks, int *chunk, int verbose)
4923
5256
{
4924
 
#if DEBUG
4925
 
        verbose = 1;
4926
 
#endif
4927
 
        /* validate container capabilities */
4928
 
        if (super->orom && raiddisks > super->orom->tds) {
4929
 
                if (verbose)
4930
 
                        fprintf(stderr, Name ": %d exceeds maximum number of"
4931
 
                                " platform supported disks: %d\n",
4932
 
                                raiddisks, super->orom->tds);
 
5257
        /* check/set platform and metadata limits/defaults */
 
5258
        if (super->orom && raiddisks > super->orom->dpa) {
 
5259
                pr_vrb(": platform supports a maximum of %d disks per array\n",
 
5260
                       super->orom->dpa);
4933
5261
                return 0;
4934
5262
        }
4935
5263
 
4936
5264
        /* capabilities of OROM tested - copied from validate_geometry_imsm_volume */
4937
 
        if (super->orom && (!is_raid_level_supported(super->orom, level,
4938
 
                                                     raiddisks))) {
 
5265
        if (!is_raid_level_supported(super->orom, level, raiddisks)) {
4939
5266
                pr_vrb(": platform does not support raid%d with %d disk%s\n",
4940
5267
                        level, raiddisks, raiddisks > 1 ? "s" : "");
4941
5268
                return 0;
4942
5269
        }
4943
 
        if (super->orom && level != 1) {
4944
 
                if (chunk && (*chunk == 0 || *chunk == UnSet))
4945
 
                        *chunk = imsm_orom_default_chunk(super->orom);
4946
 
                else if (chunk && !imsm_orom_has_chunk(super->orom, *chunk)) {
4947
 
                        pr_vrb(": platform does not support a chunk size of: "
4948
 
                               "%d\n", *chunk);
4949
 
                        return 0;
4950
 
                }
 
5270
 
 
5271
        if (chunk && (*chunk == 0 || *chunk == UnSet))
 
5272
                *chunk = imsm_default_chunk(super->orom);
 
5273
 
 
5274
        if (super->orom && chunk && !imsm_orom_has_chunk(super->orom, *chunk)) {
 
5275
                pr_vrb(": platform does not support a chunk size of: "
 
5276
                       "%d\n", *chunk);
 
5277
                return 0;
4951
5278
        }
 
5279
 
4952
5280
        if (layout != imsm_level_to_layout(level)) {
4953
5281
                if (level == 5)
4954
5282
                        pr_vrb(": imsm raid 5 only supports the left-asymmetric layout\n");
4973
5301
{
4974
5302
        struct stat stb;
4975
5303
        struct intel_super *super = st->sb;
4976
 
        struct imsm_super *mpb = super->anchor;
 
5304
        struct imsm_super *mpb;
4977
5305
        struct dl *dl;
4978
5306
        unsigned long long pos = 0;
4979
5307
        unsigned long long maxsize;
4984
5312
        if (!super)
4985
5313
                return 0;
4986
5314
 
 
5315
        mpb = super->anchor;
 
5316
 
4987
5317
        if (!validate_geometry_imsm_orom(super, level, layout, raiddisks, chunk, verbose)) {
4988
5318
                fprintf(stderr, Name ": RAID gemetry validation failed. "
4989
5319
                        "Cannot proceed with the action(s).\n");
5062
5392
                fprintf(stderr, Name ": The option-rom requires all member"
5063
5393
                        " disks to be a member of all volumes\n");
5064
5394
                return 0;
 
5395
        } else if (super->orom && mpb->num_raid_devs > 0 &&
 
5396
                   mpb->num_disks != raiddisks) {
 
5397
                fprintf(stderr, Name ": The option-rom requires all member"
 
5398
                        " disks to be a member of all volumes\n");
 
5399
                return 0;
5065
5400
        }
5066
5401
 
5067
5402
        /* retrieve the largest free space block */
5100
5435
                        i += dl->extent_cnt;
5101
5436
 
5102
5437
        maxsize = merge_extents(super, i);
 
5438
 
 
5439
        if (!check_env("IMSM_NO_PLATFORM") &&
 
5440
            mpb->num_raid_devs > 0 && size && size != maxsize) {
 
5441
                fprintf(stderr, Name ": attempting to create a second "
 
5442
                        "volume with size less then remaining space. "
 
5443
                        "Aborting...\n");
 
5444
                return 0;
 
5445
        }
 
5446
 
5103
5447
        if (maxsize < size || maxsize == 0) {
5104
 
                if (verbose)
5105
 
                        fprintf(stderr, Name ": not enough space after merge (%llu < %llu)\n",
5106
 
                                maxsize, size);
 
5448
                if (verbose) {
 
5449
                        if (maxsize == 0)
 
5450
                                fprintf(stderr, Name ": no free space"
 
5451
                                                " left on device. Aborting...\n");
 
5452
                        else
 
5453
                                fprintf(stderr, Name ": not enough space"
 
5454
                                                " to create volume of given size"
 
5455
                                                " (%llu < %llu). Aborting...\n",
 
5456
                                                maxsize, size);
 
5457
                }
5107
5458
                return 0;
5108
5459
        }
5109
5460
 
5209
5560
        }
5210
5561
        
5211
5562
        if (!dev) {
5212
 
                if (st->sb && freesize) {
 
5563
                if (st->sb) {
 
5564
                        if (!validate_geometry_imsm_orom(st->sb, level, layout,
 
5565
                                                         raiddisks, chunk,
 
5566
                                                         verbose))
 
5567
                                return 0;
5213
5568
                        /* we are being asked to automatically layout a
5214
5569
                         * new volume based on the current contents of
5215
5570
                         * the container.  If the the parameters can be
5218
5573
                         * created.  add_to_super and getinfo_super
5219
5574
                         * detect when autolayout is in progress.
5220
5575
                         */
5221
 
                        if (!validate_geometry_imsm_orom(st->sb, level, layout,
5222
 
                                                         raiddisks, chunk,
5223
 
                                                         verbose))
5224
 
                                return 0;
5225
 
                        return reserve_space(st, raiddisks, size,
5226
 
                                             chunk?*chunk:0, freesize);
 
5576
                        if (freesize)
 
5577
                                return reserve_space(st, raiddisks, size,
 
5578
                                                     chunk?*chunk:0, freesize);
5227
5579
                }
5228
5580
                return 1;
5229
5581
        }
5277
5629
                        return validate_geometry_imsm_volume(st, level, layout,
5278
5630
                                                             raiddisks, chunk,
5279
5631
                                                             size, dev,
5280
 
                                                             freesize, verbose);
 
5632
                                                             freesize, 1)
 
5633
                                ? 1 : -1;
5281
5634
                }
5282
5635
        }
5283
5636
 
5298
5651
        if (level && layout && *layout == UnSet)
5299
5652
                *layout = imsm_level_to_layout(*level);
5300
5653
 
5301
 
        if (chunk && (*chunk == UnSet || *chunk == 0) && 
5302
 
            super && super->orom)
5303
 
                *chunk = imsm_orom_default_chunk(super->orom);
 
5654
        if (chunk && (*chunk == UnSet || *chunk == 0))
 
5655
                *chunk = imsm_default_chunk(super->orom);
5304
5656
}
5305
5657
 
5306
5658
static void handle_missing(struct intel_super *super, struct imsm_dev *dev);
5368
5720
                struct dl *d;
5369
5721
 
5370
5722
                for (d = super->disks; d; d = d->next)
5371
 
                        if (d->index > -2) {
5372
 
                                d->index = -1;
5373
 
                                d->disk.status = SPARE_DISK;
5374
 
                        }
 
5723
                        if (d->index > -2)
 
5724
                                mark_spare(d);
5375
5725
        }
5376
5726
 
5377
5727
        super->updates_pending++;
5430
5780
 
5431
5781
        return 0;
5432
5782
}
 
5783
#endif /* MDASSEMBLE */
5433
5784
 
5434
5785
static int is_gen_migration(struct imsm_dev *dev)
5435
5786
{
5444
5795
 
5445
5796
        return 0;
5446
5797
}
5447
 
#endif /* MDASSEMBLE */
5448
5798
 
5449
5799
static int is_rebuilding(struct imsm_dev *dev)
5450
5800
{
5456
5806
        if (migr_type(dev) != MIGR_REBUILD)
5457
5807
                return 0;
5458
5808
 
5459
 
        migr_map = get_imsm_map(dev, 1);
 
5809
        migr_map = get_imsm_map(dev, MAP_1);
5460
5810
 
5461
5811
        if (migr_map->map_state == IMSM_T_STATE_DEGRADED)
5462
5812
                return 1;
5464
5814
                return 0;
5465
5815
}
5466
5816
 
 
5817
#ifndef MDASSEMBLE
 
5818
static int is_initializing(struct imsm_dev *dev)
 
5819
{
 
5820
        struct imsm_map *migr_map;
 
5821
 
 
5822
        if (!dev->vol.migr_state)
 
5823
                return 0;
 
5824
 
 
5825
        if (migr_type(dev) != MIGR_INIT)
 
5826
                return 0;
 
5827
 
 
5828
        migr_map = get_imsm_map(dev, MAP_1);
 
5829
 
 
5830
        if (migr_map->map_state == IMSM_T_STATE_UNINITIALIZED)
 
5831
                return 1;
 
5832
 
 
5833
        return 0;
 
5834
}
 
5835
#endif
 
5836
 
5467
5837
static void update_recovery_start(struct intel_super *super,
5468
5838
                                        struct imsm_dev *dev,
5469
5839
                                        struct mdinfo *array)
5515
5885
        struct imsm_super *mpb = super->anchor;
5516
5886
        struct mdinfo *rest = NULL;
5517
5887
        unsigned int i;
5518
 
        int bbm_errors = 0;
 
5888
        int sb_errors = 0;
5519
5889
        struct dl *d;
5520
5890
        int spare_disks = 0;
5521
5891
 
5522
5892
        /* do not assemble arrays when not all attributes are supported */
5523
5893
        if (imsm_check_attributes(mpb->attributes) == 0) {
5524
 
                fprintf(stderr, Name ": IMSM metadata loading not allowed "
5525
 
                        "due to attributes incompatibility.\n");
5526
 
                return NULL;
 
5894
                sb_errors = 1;
 
5895
                fprintf(stderr, Name ": Unsupported attributes in IMSM metadata."
 
5896
                        "Arrays activation is blocked.\n");
5527
5897
        }
5528
5898
 
5529
5899
        /* check for bad blocks */
5530
 
        if (imsm_bbm_log_size(super->anchor))
5531
 
                bbm_errors = 1;
 
5900
        if (imsm_bbm_log_size(super->anchor)) {
 
5901
                fprintf(stderr, Name ": BBM log found in IMSM metadata."
 
5902
                        "Arrays activation is blocked.\n");
 
5903
                sb_errors = 1;
 
5904
        }
 
5905
 
5532
5906
 
5533
5907
        /* count spare devices, not used in maps
5534
5908
         */
5541
5915
                struct imsm_map *map;
5542
5916
                struct imsm_map *map2;
5543
5917
                struct mdinfo *this;
5544
 
                int slot, chunk;
 
5918
                int slot;
 
5919
#ifndef MDASSEMBLE
 
5920
                int chunk;
 
5921
#endif
5545
5922
                char *ep;
5546
5923
 
5547
5924
                if (subarray &&
5549
5926
                        continue;
5550
5927
 
5551
5928
                dev = get_imsm_dev(super, i);
5552
 
                map = get_imsm_map(dev, 0);
5553
 
                map2 = get_imsm_map(dev, 1);
 
5929
                map = get_imsm_map(dev, MAP_0);
 
5930
                map2 = get_imsm_map(dev, MAP_1);
5554
5931
 
5555
5932
                /* do not publish arrays that are in the middle of an
5556
5933
                 * unsupported migration
5566
5943
                 * OROM/EFI
5567
5944
                 */
5568
5945
 
 
5946
                this = malloc(sizeof(*this));
 
5947
                if (!this) {
 
5948
                        fprintf(stderr, Name ": failed to allocate %zu bytes\n",
 
5949
                                sizeof(*this));
 
5950
                        break;
 
5951
                }
 
5952
 
 
5953
                super->current_vol = i;
 
5954
                getinfo_super_imsm_volume(st, this, NULL);
 
5955
                this->next = rest;
 
5956
#ifndef MDASSEMBLE
5569
5957
                chunk = __le16_to_cpu(map->blocks_per_strip) >> 1;
5570
 
#ifndef MDASSEMBLE
 
5958
                /* mdadm does not support all metadata features- set the bit in all arrays state */
5571
5959
                if (!validate_geometry_imsm_orom(super,
5572
5960
                                                 get_imsm_raid_level(map), /* RAID level */
5573
5961
                                                 imsm_level_to_layout(get_imsm_raid_level(map)),
5574
5962
                                                 map->num_members, /* raid disks */
5575
5963
                                                 &chunk,
5576
5964
                                                 1 /* verbose */)) {
5577
 
                        fprintf(stderr, Name ": RAID gemetry validation failed. "
5578
 
                                "Cannot proceed with the action(s).\n");
5579
 
                        continue;
5580
 
                }
5581
 
#endif /* MDASSEMBLE */
5582
 
                this = malloc(sizeof(*this));
5583
 
                if (!this) {
5584
 
                        fprintf(stderr, Name ": failed to allocate %zu bytes\n",
5585
 
                                sizeof(*this));
5586
 
                        break;
5587
 
                }
5588
 
 
5589
 
                super->current_vol = i;
5590
 
                getinfo_super_imsm_volume(st, this, NULL);
5591
 
                this->next = rest;
 
5965
                        fprintf(stderr, Name ": IMSM RAID geometry validation"
 
5966
                                " failed.  Array %s activation is blocked.\n",
 
5967
                                dev->volume);
 
5968
                        this->array.state |=
 
5969
                          (1<<MD_SB_BLOCK_CONTAINER_RESHAPE) |
 
5970
                          (1<<MD_SB_BLOCK_VOLUME);
 
5971
                }
 
5972
#endif
 
5973
 
 
5974
                /* if array has bad blocks, set suitable bit in all arrays state */
 
5975
                if (sb_errors)
 
5976
                        this->array.state |=
 
5977
                          (1<<MD_SB_BLOCK_CONTAINER_RESHAPE) |
 
5978
                          (1<<MD_SB_BLOCK_VOLUME);
 
5979
 
5592
5980
                for (slot = 0 ; slot <  map->num_members; slot++) {
5593
5981
                        unsigned long long recovery_start;
5594
5982
                        struct mdinfo *info_d;
5598
5986
                        __u32 ord;
5599
5987
 
5600
5988
                        skip = 0;
5601
 
                        idx = get_imsm_disk_idx(dev, slot, 0);
5602
 
                        ord = get_imsm_ord_tbl_ent(dev, slot, -1);
 
5989
                        idx = get_imsm_disk_idx(dev, slot, MAP_0);
 
5990
                        ord = get_imsm_ord_tbl_ent(dev, slot, MAP_X);
5603
5991
                        for (d = super->disks; d ; d = d->next)
5604
5992
                                if (d->index == idx)
5605
5993
                                        break;
5677
6065
                rest = this;
5678
6066
        }
5679
6067
 
5680
 
        /* if array has bad blocks, set suitable bit in array status */
5681
 
        if (bbm_errors)
5682
 
                rest->array.state |= (1<<MD_SB_BBM_ERRORS);
5683
 
 
5684
6068
        return rest;
5685
6069
}
5686
6070
 
5687
6071
 
5688
 
static __u8 imsm_check_degraded(struct intel_super *super, struct imsm_dev *dev, int failed)
 
6072
static __u8 imsm_check_degraded(struct intel_super *super, struct imsm_dev *dev,
 
6073
                                int failed, int look_in_map)
5689
6074
{
5690
 
        struct imsm_map *map = get_imsm_map(dev, 0);
 
6075
        struct imsm_map *map;
 
6076
 
 
6077
        map = get_imsm_map(dev, look_in_map);
5691
6078
 
5692
6079
        if (!failed)
5693
6080
                return map->map_state == IMSM_T_STATE_UNINITIALIZED ? 
5715
6102
                int insync = insync;
5716
6103
 
5717
6104
                for (i = 0; i < map->num_members; i++) {
5718
 
                        __u32 ord = get_imsm_ord_tbl_ent(dev, i, -1);
 
6105
                        __u32 ord = get_imsm_ord_tbl_ent(dev, i, MAP_X);
5719
6106
                        int idx = ord_to_idx(ord);
5720
6107
                        struct imsm_disk *disk;
5721
6108
 
5751
6138
        return map->map_state;
5752
6139
}
5753
6140
 
5754
 
static int imsm_count_failed(struct intel_super *super, struct imsm_dev *dev)
 
6141
static int imsm_count_failed(struct intel_super *super, struct imsm_dev *dev,
 
6142
                             int look_in_map)
5755
6143
{
5756
6144
        int i;
5757
6145
        int failed = 0;
5758
6146
        struct imsm_disk *disk;
5759
 
        struct imsm_map *map = get_imsm_map(dev, 0);
5760
 
        struct imsm_map *prev = get_imsm_map(dev, dev->vol.migr_state);
 
6147
        struct imsm_map *map = get_imsm_map(dev, MAP_0);
 
6148
        struct imsm_map *prev = get_imsm_map(dev, MAP_1);
 
6149
        struct imsm_map *map_for_loop;
5761
6150
        __u32 ord;
5762
6151
        int idx;
 
6152
        int idx_1;
5763
6153
 
5764
6154
        /* at the beginning of migration we set IMSM_ORD_REBUILD on
5765
6155
         * disks that are being rebuilt.  New failures are recorded to
5766
6156
         * map[0].  So we look through all the disks we started with and
5767
6157
         * see if any failures are still present, or if any new ones
5768
6158
         * have arrived
5769
 
         *
5770
 
         * FIXME add support for online capacity expansion and
5771
 
         * raid-level-migration
5772
6159
         */
5773
 
        for (i = 0; i < prev->num_members; i++) {
5774
 
                ord = __le32_to_cpu(prev->disk_ord_tbl[i]);
5775
 
                ord |= __le32_to_cpu(map->disk_ord_tbl[i]);
5776
 
                idx = ord_to_idx(ord);
5777
 
 
5778
 
                disk = get_imsm_disk(super, idx);
5779
 
                if (!disk || is_failed(disk) || ord & IMSM_ORD_REBUILD)
5780
 
                        failed++;
 
6160
        map_for_loop = map;
 
6161
        if (prev && (map->num_members < prev->num_members))
 
6162
                map_for_loop = prev;
 
6163
 
 
6164
        for (i = 0; i < map_for_loop->num_members; i++) {
 
6165
                idx_1 = -255;
 
6166
                /* when MAP_X is passed both maps failures are counted
 
6167
                 */
 
6168
                if (prev &&
 
6169
                    ((look_in_map == MAP_1) || (look_in_map == MAP_X)) &&
 
6170
                    (i < prev->num_members)) {
 
6171
                        ord = __le32_to_cpu(prev->disk_ord_tbl[i]);
 
6172
                        idx_1 = ord_to_idx(ord);
 
6173
 
 
6174
                        disk = get_imsm_disk(super, idx_1);
 
6175
                        if (!disk || is_failed(disk) || ord & IMSM_ORD_REBUILD)
 
6176
                                failed++;
 
6177
                }
 
6178
                if (((look_in_map == MAP_0) || (look_in_map == MAP_X)) &&
 
6179
                    (i < map->num_members)) {
 
6180
                        ord = __le32_to_cpu(map->disk_ord_tbl[i]);
 
6181
                        idx = ord_to_idx(ord);
 
6182
 
 
6183
                        if (idx != idx_1) {
 
6184
                                disk = get_imsm_disk(super, idx);
 
6185
                                if (!disk || is_failed(disk) ||
 
6186
                                    ord & IMSM_ORD_REBUILD)
 
6187
                                        failed++;
 
6188
                        }
 
6189
                }
5781
6190
        }
5782
6191
 
5783
6192
        return failed;
5815
6224
        if (migr_type(dev) == MIGR_GEN_MIGR)
5816
6225
                return 0;
5817
6226
 
5818
 
        migr_map = get_imsm_map(dev, 1);
 
6227
        migr_map = get_imsm_map(dev, MAP_1);
5819
6228
 
5820
6229
        if ((migr_map->map_state == IMSM_T_STATE_NORMAL) &&
5821
6230
            (dev->vol.migr_type != MIGR_GEN_MIGR))
5830
6239
        __u32 ord;
5831
6240
        int slot;
5832
6241
        struct imsm_map *map;
 
6242
        char buf[MAX_RAID_SERIAL_LEN+3];
 
6243
        unsigned int len, shift = 0;
5833
6244
 
5834
6245
        /* new failures are always set in map[0] */
5835
 
        map = get_imsm_map(dev, 0);
 
6246
        map = get_imsm_map(dev, MAP_0);
5836
6247
 
5837
6248
        slot = get_imsm_disk_slot(map, idx);
5838
6249
        if (slot < 0)
5842
6253
        if (is_failed(disk) && (ord & IMSM_ORD_REBUILD))
5843
6254
                return 0;
5844
6255
 
 
6256
        memcpy(buf, disk->serial, MAX_RAID_SERIAL_LEN);
 
6257
        buf[MAX_RAID_SERIAL_LEN] = '\000';
 
6258
        strcat(buf, ":0");
 
6259
        if ((len = strlen(buf)) >= MAX_RAID_SERIAL_LEN)
 
6260
                shift = len - MAX_RAID_SERIAL_LEN + 1;
 
6261
        strncpy((char *)disk->serial, &buf[shift], MAX_RAID_SERIAL_LEN);
 
6262
 
5845
6263
        disk->status |= FAILED_DISK;
5846
6264
        set_imsm_ord_tbl_ent(map, slot, idx | IMSM_ORD_REBUILD);
 
6265
        /* mark failures in second map if second map exists and this disk
 
6266
         * in this slot.
 
6267
         * This is valid for migration, initialization and rebuild
 
6268
         */
 
6269
        if (dev->vol.migr_state) {
 
6270
                struct imsm_map *map2 = get_imsm_map(dev, MAP_1);
 
6271
                int slot2 = get_imsm_disk_slot(map2, idx);
 
6272
 
 
6273
                if ((slot2 < map2->num_members) &&
 
6274
                    (slot2 >= 0))
 
6275
                        set_imsm_ord_tbl_ent(map2, slot2,
 
6276
                                             idx | IMSM_ORD_REBUILD);
 
6277
        }
5847
6278
        if (map->failed_disk_num == 0xff)
5848
6279
                map->failed_disk_num = slot;
5849
6280
        return 1;
5862
6293
 
5863
6294
static void handle_missing(struct intel_super *super, struct imsm_dev *dev)
5864
6295
{
5865
 
        __u8 map_state;
5866
6296
        struct dl *dl;
5867
 
        int failed;
5868
6297
 
5869
6298
        if (!super->missing)
5870
6299
                return;
5871
 
        failed = imsm_count_failed(super, dev);
5872
 
        map_state = imsm_check_degraded(super, dev, failed);
5873
6300
 
5874
6301
        dprintf("imsm: mark missing\n");
5875
 
        end_migration(dev, map_state);
 
6302
        /* end process for initialization and rebuild only
 
6303
         */
 
6304
        if (is_gen_migration(dev) == 0) {
 
6305
                __u8 map_state;
 
6306
                int failed;
 
6307
 
 
6308
                failed = imsm_count_failed(super, dev, MAP_0);
 
6309
                map_state = imsm_check_degraded(super, dev, failed, MAP_0);
 
6310
 
 
6311
                end_migration(dev, super, map_state);
 
6312
        }
5876
6313
        for (dl = super->missing; dl; dl = dl->next)
5877
6314
                mark_missing(dev, &dl->disk, dl->index);
5878
6315
        super->updates_pending++;
5880
6317
 
5881
6318
static unsigned long long imsm_set_array_size(struct imsm_dev *dev)
5882
6319
{
5883
 
        int used_disks = imsm_num_data_members(dev, 0);
 
6320
        int used_disks = imsm_num_data_members(dev, MAP_0);
5884
6321
        unsigned long long array_blocks;
5885
6322
        struct imsm_map *map;
5886
6323
 
5897
6334
 
5898
6335
        /* set array size in metadata
5899
6336
         */
5900
 
        map = get_imsm_map(dev, 0);
 
6337
        map = get_imsm_map(dev, MAP_0);
5901
6338
        array_blocks = map->blocks_per_member * used_disks;
5902
6339
 
5903
6340
        /* round array size down to closest MB
5925
6362
 
5926
6363
        for (i = 0; i < mpb->num_raid_devs; i++) {
5927
6364
                struct imsm_dev *dev = get_imsm_dev(super, i);
5928
 
                struct imsm_map *map = get_imsm_map(dev, 0);
 
6365
                struct imsm_map *map = get_imsm_map(dev, MAP_0);
5929
6366
                struct imsm_map *map2;
5930
6367
                int prev_num_members;
5931
6368
 
5946
6383
                map->num_members = prev_disks;
5947
6384
                dev->vol.migr_state = 1;
5948
6385
                dev->vol.curr_migr_unit = 0;
5949
 
                dev->vol.migr_type = MIGR_GEN_MIGR;
 
6386
                set_migr_type(dev, MIGR_GEN_MIGR);
5950
6387
                for (i = prev_num_members;
5951
6388
                     i < map->num_members; i++)
5952
6389
                        set_imsm_ord_tbl_ent(map, i, i);
5953
 
                map2 = get_imsm_map(dev, 1);
 
6390
                map2 = get_imsm_map(dev, MAP_1);
5954
6391
                /* Copy the current map */
5955
6392
                memcpy(map2, map, copy_map_size);
5956
6393
                map2->num_members = prev_num_members;
5970
6407
        int inst = a->info.container_member;
5971
6408
        struct intel_super *super = a->container->sb;
5972
6409
        struct imsm_dev *dev = get_imsm_dev(super, inst);
5973
 
        struct imsm_map *map = get_imsm_map(dev, 0);
5974
 
        int failed = imsm_count_failed(super, dev);
5975
 
        __u8 map_state = imsm_check_degraded(super, dev, failed);
 
6410
        struct imsm_map *map = get_imsm_map(dev, MAP_0);
 
6411
        int failed = imsm_count_failed(super, dev, MAP_0);
 
6412
        __u8 map_state = imsm_check_degraded(super, dev, failed, MAP_0);
5976
6413
        __u32 blocks_per_unit;
5977
6414
 
5978
6415
        if (dev->vol.migr_state &&
5994
6431
                                 * user action is required to recover process
5995
6432
                                 */
5996
6433
                                if (0) {
5997
 
                                struct imsm_map *map2 = get_imsm_map(dev, 1);
5998
 
                                dev->vol.migr_state = 0;
5999
 
                                dev->vol.migr_type = 0;
6000
 
                                dev->vol.curr_migr_unit = 0;
6001
 
                                memcpy(map, map2, sizeof_imsm_map(map2));
6002
 
                                super->updates_pending++;
 
6434
                                        struct imsm_map *map2 =
 
6435
                                                get_imsm_map(dev, MAP_1);
 
6436
                                        dev->vol.migr_state = 0;
 
6437
                                        set_migr_type(dev, 0);
 
6438
                                        dev->vol.curr_migr_unit = 0;
 
6439
                                        memcpy(map, map2,
 
6440
                                               sizeof_imsm_map(map2));
 
6441
                                        super->updates_pending++;
6003
6442
                                }
6004
6443
                        }
6005
6444
                        if (a->last_checkpoint >= a->info.component_size) {
6007
6446
                                int used_disks;
6008
6447
                                struct mdinfo *mdi;
6009
6448
 
6010
 
                                used_disks = imsm_num_data_members(dev, 0);
 
6449
                                used_disks = imsm_num_data_members(dev, MAP_0);
6011
6450
                                if (used_disks > 0) {
6012
6451
                                        array_blocks =
6013
6452
                                                map->blocks_per_member *
6052
6491
                 */
6053
6492
                if (is_resyncing(dev)) {
6054
6493
                        dprintf("imsm: mark resync done\n");
6055
 
                        end_migration(dev, map_state);
 
6494
                        end_migration(dev, super, map_state);
6056
6495
                        super->updates_pending++;
6057
6496
                        a->last_checkpoint = 0;
6058
6497
                }
6059
 
        } else if (!is_resyncing(dev) && !failed) {
 
6498
        } else if ((!is_resyncing(dev) && !failed) &&
 
6499
                   (imsm_reshape_blocks_arrays_changes(super) == 0)) {
6060
6500
                /* mark the start of the init process if nothing is failed */
6061
6501
                dprintf("imsm: mark resync start\n");
6062
6502
                if (map->map_state == IMSM_T_STATE_UNINITIALIZED)
6113
6553
        int inst = a->info.container_member;
6114
6554
        struct intel_super *super = a->container->sb;
6115
6555
        struct imsm_dev *dev = get_imsm_dev(super, inst);
6116
 
        struct imsm_map *map = get_imsm_map(dev, 0);
 
6556
        struct imsm_map *map = get_imsm_map(dev, MAP_0);
6117
6557
        struct imsm_disk *disk;
6118
6558
        int failed;
6119
6559
        __u32 ord;
6128
6568
 
6129
6569
        dprintf("imsm: set_disk %d:%x\n", n, state);
6130
6570
 
6131
 
        ord = get_imsm_ord_tbl_ent(dev, n, -1);
 
6571
        ord = get_imsm_ord_tbl_ent(dev, n, MAP_0);
6132
6572
        disk = get_imsm_disk(super, ord_to_idx(ord));
6133
6573
 
6134
6574
        /* check for new failures */
6139
6579
 
6140
6580
        /* check if in_sync */
6141
6581
        if (state & DS_INSYNC && ord & IMSM_ORD_REBUILD && is_rebuilding(dev)) {
6142
 
                struct imsm_map *migr_map = get_imsm_map(dev, 1);
 
6582
                struct imsm_map *migr_map = get_imsm_map(dev, MAP_1);
6143
6583
 
6144
6584
                set_imsm_ord_tbl_ent(migr_map, n, ord_to_idx(ord));
6145
6585
                super->updates_pending++;
6146
6586
        }
6147
6587
 
6148
 
        failed = imsm_count_failed(super, dev);
6149
 
        map_state = imsm_check_degraded(super, dev, failed);
 
6588
        failed = imsm_count_failed(super, dev, MAP_0);
 
6589
        map_state = imsm_check_degraded(super, dev, failed, MAP_0);
6150
6590
 
6151
6591
        /* check if recovery complete, newly degraded, or failed */
6152
 
        if (map_state == IMSM_T_STATE_NORMAL && is_rebuilding(dev)) {
6153
 
                end_migration(dev, map_state);
6154
 
                map = get_imsm_map(dev, 0);
6155
 
                map->failed_disk_num = ~0;
6156
 
                super->updates_pending++;
6157
 
                a->last_checkpoint = 0;
6158
 
        } else if (map_state == IMSM_T_STATE_DEGRADED &&
6159
 
                   map->map_state != map_state &&
6160
 
                   !dev->vol.migr_state) {
6161
 
                dprintf("imsm: mark degraded\n");
6162
 
                map->map_state = map_state;
6163
 
                super->updates_pending++;
6164
 
                a->last_checkpoint = 0;
6165
 
        } else if (map_state == IMSM_T_STATE_FAILED &&
6166
 
                   map->map_state != map_state) {
6167
 
                dprintf("imsm: mark failed\n");
6168
 
                end_migration(dev, map_state);
6169
 
                super->updates_pending++;
6170
 
                a->last_checkpoint = 0;
6171
 
        } else if (is_gen_migration(dev)) {
6172
 
                dprintf("imsm: Detected General Migration in state: ");
6173
 
                if (map_state == IMSM_T_STATE_NORMAL) {
6174
 
                        end_migration(dev, map_state);
6175
 
                        map = get_imsm_map(dev, 0);
6176
 
                        map->failed_disk_num = ~0;
6177
 
                        dprintf("normal\n");
6178
 
                } else {
6179
 
                        if (map_state == IMSM_T_STATE_DEGRADED) {
6180
 
                                printf("degraded\n");
6181
 
                                end_migration(dev, map_state);
6182
 
                        } else {
6183
 
                                dprintf("failed\n");
6184
 
                        }
6185
 
                        map->map_state = map_state;
6186
 
                }
6187
 
                super->updates_pending++;
 
6592
        dprintf("imsm: Detected transition to state ");
 
6593
        switch (map_state) {
 
6594
        case IMSM_T_STATE_NORMAL: /* transition to normal state */
 
6595
                dprintf("normal: ");
 
6596
                if (is_rebuilding(dev)) {
 
6597
                        dprintf("while rebuilding");
 
6598
                        end_migration(dev, super, map_state);
 
6599
                        map = get_imsm_map(dev, MAP_0);
 
6600
                        map->failed_disk_num = ~0;
 
6601
                        super->updates_pending++;
 
6602
                        a->last_checkpoint = 0;
 
6603
                        break;
 
6604
                }
 
6605
                if (is_gen_migration(dev)) {
 
6606
                        dprintf("while general migration");
 
6607
                        if (a->last_checkpoint >= a->info.component_size)
 
6608
                                end_migration(dev, super, map_state);
 
6609
                        else
 
6610
                                map->map_state = map_state;
 
6611
                        map = get_imsm_map(dev, MAP_0);
 
6612
                        map->failed_disk_num = ~0;
 
6613
                        super->updates_pending++;
 
6614
                        break;
 
6615
                }
 
6616
        break;
 
6617
        case IMSM_T_STATE_DEGRADED: /* transition to degraded state */
 
6618
                dprintf("degraded: ");
 
6619
                if ((map->map_state != map_state) &&
 
6620
                    !dev->vol.migr_state) {
 
6621
                        dprintf("mark degraded");
 
6622
                        map->map_state = map_state;
 
6623
                        super->updates_pending++;
 
6624
                        a->last_checkpoint = 0;
 
6625
                        break;
 
6626
                }
 
6627
                if (is_rebuilding(dev)) {
 
6628
                        dprintf("while rebuilding.");
 
6629
                        if (map->map_state != map_state)  {
 
6630
                                dprintf(" Map state change");
 
6631
                                end_migration(dev, super, map_state);
 
6632
                                super->updates_pending++;
 
6633
                        }
 
6634
                        break;
 
6635
                }
 
6636
                if (is_gen_migration(dev)) {
 
6637
                        dprintf("while general migration");
 
6638
                        if (a->last_checkpoint >= a->info.component_size)
 
6639
                                end_migration(dev, super, map_state);
 
6640
                        else {
 
6641
                                map->map_state = map_state;
 
6642
                                manage_second_map(super, dev);
 
6643
                        }
 
6644
                        super->updates_pending++;
 
6645
                        break;
 
6646
                }
 
6647
                if (is_initializing(dev)) {
 
6648
                        dprintf("while initialization.");
 
6649
                        map->map_state = map_state;
 
6650
                        super->updates_pending++;
 
6651
                        break;
 
6652
                }
 
6653
        break;
 
6654
        case IMSM_T_STATE_FAILED: /* transition to failed state */
 
6655
                dprintf("failed: ");
 
6656
                if (is_gen_migration(dev)) {
 
6657
                        dprintf("while general migration");
 
6658
                        map->map_state = map_state;
 
6659
                        super->updates_pending++;
 
6660
                        break;
 
6661
                }
 
6662
                if (map->map_state != map_state) {
 
6663
                        dprintf("mark failed");
 
6664
                        end_migration(dev, super, map_state);
 
6665
                        super->updates_pending++;
 
6666
                        a->last_checkpoint = 0;
 
6667
                        break;
 
6668
                }
 
6669
        break;
 
6670
        default:
 
6671
                dprintf("state %i\n", map_state);
6188
6672
        }
 
6673
        dprintf("\n");
 
6674
 
6189
6675
}
6190
6676
 
6191
6677
static int store_imsm_mpb(int fd, struct imsm_super *mpb)
6236
6722
static struct dl *imsm_readd(struct intel_super *super, int idx, struct active_array *a)
6237
6723
{
6238
6724
        struct imsm_dev *dev = get_imsm_dev(super, a->info.container_member);
6239
 
        int i = get_imsm_disk_idx(dev, idx, -1);
 
6725
        int i = get_imsm_disk_idx(dev, idx, MAP_X);
6240
6726
        struct dl *dl;
6241
6727
 
6242
6728
        for (dl = super->disks; dl; dl = dl->next)
6257
6743
                                 struct mdinfo *additional_test_list)
6258
6744
{
6259
6745
        struct imsm_dev *dev = get_imsm_dev(super, a->info.container_member);
6260
 
        int idx = get_imsm_disk_idx(dev, slot, -1);
 
6746
        int idx = get_imsm_disk_idx(dev, slot, MAP_X);
6261
6747
        struct imsm_super *mpb = super->anchor;
6262
6748
        struct imsm_map *map;
6263
6749
        unsigned long long pos;
6319
6805
                }
6320
6806
                for (i = 0; i < mpb->num_raid_devs; i++) {
6321
6807
                        dev = get_imsm_dev(super, i);
6322
 
                        map = get_imsm_map(dev, 0);
 
6808
                        map = get_imsm_map(dev, MAP_0);
6323
6809
 
6324
6810
                        /* check if this disk is already a member of
6325
6811
                         * this array
6375
6861
 
6376
6862
        dev2 = get_imsm_dev(cont->sb, dev_idx);
6377
6863
        if (dev2) {
6378
 
                state = imsm_check_degraded(cont->sb, dev2, failed);
 
6864
                state = imsm_check_degraded(cont->sb, dev2, failed, MAP_0);
6379
6865
                if (state == IMSM_T_STATE_FAILED) {
6380
 
                        map = get_imsm_map(dev2, 0);
 
6866
                        map = get_imsm_map(dev2, MAP_0);
6381
6867
                        if (!map)
6382
6868
                                return 1;
6383
6869
                        for (slot = 0; slot < map->num_members; slot++) {
6385
6871
                                 * Check if failed disks are deleted from intel
6386
6872
                                 * disk list or are marked to be deleted
6387
6873
                                 */
6388
 
                                idx = get_imsm_disk_idx(dev2, slot, -1);
 
6874
                                idx = get_imsm_disk_idx(dev2, slot, MAP_X);
6389
6875
                                idisk = get_imsm_dl_disk(cont->sb, idx);
6390
6876
                                /*
6391
6877
                                 * Do not rebuild the array if failed disks
6419
6905
        struct intel_super *super = a->container->sb;
6420
6906
        int inst = a->info.container_member;
6421
6907
        struct imsm_dev *dev = get_imsm_dev(super, inst);
6422
 
        struct imsm_map *map = get_imsm_map(dev, 0);
 
6908
        struct imsm_map *map = get_imsm_map(dev, MAP_0);
6423
6909
        int failed = a->info.array.raid_disks;
6424
6910
        struct mdinfo *rv = NULL;
6425
6911
        struct mdinfo *d;
6443
6929
        dprintf("imsm: activate spare: inst=%d failed=%d (%d) level=%d\n",
6444
6930
                inst, failed, a->info.array.raid_disks, a->info.array.level);
6445
6931
 
6446
 
        if (dev->vol.migr_state &&
6447
 
            dev->vol.migr_type == MIGR_GEN_MIGR)
6448
 
                /* No repair during migration */
 
6932
        if (imsm_reshape_blocks_arrays_changes(super))
 
6933
                        return NULL;
 
6934
 
 
6935
        /* Cannot activate another spare if rebuild is in progress already
 
6936
         */
 
6937
        if (is_rebuilding(dev)) {
 
6938
                dprintf("imsm: No spare activation allowed. "
 
6939
                        "Rebuild in progress already.\n");
6449
6940
                return NULL;
 
6941
        }
6450
6942
 
6451
6943
        if (a->info.array.level == 4)
6452
6944
                /* No repair for takeovered array
6454
6946
                 */
6455
6947
                return NULL;
6456
6948
 
6457
 
        if (imsm_check_degraded(super, dev, failed) != IMSM_T_STATE_DEGRADED)
 
6949
        if (imsm_check_degraded(super, dev, failed, MAP_0) !=
 
6950
                        IMSM_T_STATE_DEGRADED)
6458
6951
                return NULL;
6459
6952
 
6460
6953
        /*
6463
6956
         * are removed from container.
6464
6957
         */
6465
6958
        if (failed) {
6466
 
                dprintf("found failed disks in %s, check if there another"
 
6959
                dprintf("found failed disks in %.*s, check if there another"
6467
6960
                        "failed sub-array.\n",
6468
 
                        dev->volume);
 
6961
                        MAX_RAID_SERIAL_LEN, dev->volume);
6469
6962
                /* check if states of the other volumes allow for rebuild */
6470
6963
                for (i = 0; i <  super->anchor->num_raid_devs; i++) {
6471
6964
                        if (i != inst) {
6495
6988
                 */
6496
6989
                dl = imsm_readd(super, i, a);
6497
6990
                if (!dl)
6498
 
                        dl = imsm_add_spare(super, i, a, 0, NULL);
 
6991
                        dl = imsm_add_spare(super, i, a, 0, rv);
6499
6992
                if (!dl)
6500
 
                        dl = imsm_add_spare(super, i, a, 1, NULL);
 
6993
                        dl = imsm_add_spare(super, i, a, 1, rv);
6501
6994
                if (!dl)
6502
6995
                        continue;
6503
6996
 
6534
7027
                num_spares++;
6535
7028
                dprintf("%x:%x to be %d at %llu\n", dl->major, dl->minor,
6536
7029
                        i, di->data_offset);
6537
 
 
6538
 
                break;
6539
7030
        }
6540
7031
 
6541
7032
        if (!rv)
6587
7078
static int disks_overlap(struct intel_super *super, int idx, struct imsm_update_create_array *u)
6588
7079
{
6589
7080
        struct imsm_dev *dev = get_imsm_dev(super, idx);
6590
 
        struct imsm_map *map = get_imsm_map(dev, 0);
6591
 
        struct imsm_map *new_map = get_imsm_map(&u->dev, 0);
 
7081
        struct imsm_map *map = get_imsm_map(dev, MAP_0);
 
7082
        struct imsm_map *new_map = get_imsm_map(&u->dev, MAP_0);
6592
7083
        struct disk_info *inf = get_disk_info(u);
6593
7084
        struct imsm_disk *disk;
6594
7085
        int i;
6595
7086
        int j;
6596
7087
 
6597
7088
        for (i = 0; i < map->num_members; i++) {
6598
 
                disk = get_imsm_disk(super, get_imsm_disk_idx(dev, i, -1));
 
7089
                disk = get_imsm_disk(super, get_imsm_disk_idx(dev, i, MAP_X));
6599
7090
                for (j = 0; j < new_map->num_members; j++)
6600
7091
                        if (serialcmp(disk->serial, inf[j].serial) == 0)
6601
7092
                                return 1;
6708
7199
                        struct imsm_map *map;
6709
7200
                        struct imsm_dev *new_dev =
6710
7201
                                (struct imsm_dev *)*space_list;
6711
 
                        struct imsm_map *migr_map = get_imsm_map(dev, 1);
 
7202
                        struct imsm_map *migr_map = get_imsm_map(dev, MAP_1);
6712
7203
                        int to_state;
6713
7204
                        struct dl *new_disk;
6714
7205
 
6716
7207
                                return ret_val;
6717
7208
                        *space_list = **space_list;
6718
7209
                        memcpy(new_dev, dev, sizeof_imsm_dev(dev, 0));
6719
 
                        map = get_imsm_map(new_dev, 0);
 
7210
                        map = get_imsm_map(new_dev, MAP_0);
6720
7211
                        if (migr_map) {
6721
7212
                                dprintf("imsm: Error: migration in progress");
6722
7213
                                return ret_val;
6736
7227
                        migrate(new_dev, super, to_state, MIGR_GEN_MIGR);
6737
7228
                        if (u->new_level > -1)
6738
7229
                                map->raid_level = u->new_level;
6739
 
                        migr_map = get_imsm_map(new_dev, 1);
 
7230
                        migr_map = get_imsm_map(new_dev, MAP_1);
6740
7231
                        if ((u->new_level == 5) &&
6741
7232
                            (migr_map->raid_level == 0)) {
6742
7233
                                int ord = map->num_members - 1;
6805
7296
        return ret_val;
6806
7297
}
6807
7298
 
 
7299
static int apply_update_activate_spare(struct imsm_update_activate_spare *u,
 
7300
                                       struct intel_super *super,       
 
7301
                                       struct active_array *active_array)
 
7302
{
 
7303
        struct imsm_super *mpb = super->anchor;
 
7304
        struct imsm_dev *dev = get_imsm_dev(super, u->array);
 
7305
        struct imsm_map *map = get_imsm_map(dev, MAP_0);
 
7306
        struct imsm_map *migr_map;
 
7307
        struct active_array *a;
 
7308
        struct imsm_disk *disk;
 
7309
        __u8 to_state;
 
7310
        struct dl *dl;
 
7311
        unsigned int found;
 
7312
        int failed;
 
7313
        int victim;
 
7314
        int i;
 
7315
        int second_map_created = 0;
 
7316
 
 
7317
        for (; u; u = u->next) {
 
7318
                victim = get_imsm_disk_idx(dev, u->slot, MAP_X);
 
7319
 
 
7320
                if (victim < 0)
 
7321
                        return 0;
 
7322
 
 
7323
                for (dl = super->disks; dl; dl = dl->next)
 
7324
                        if (dl == u->dl)
 
7325
                                break;
 
7326
 
 
7327
                if (!dl) {
 
7328
                        fprintf(stderr, "error: imsm_activate_spare passed "
 
7329
                                "an unknown disk (index: %d)\n",
 
7330
                                u->dl->index);
 
7331
                        return 0;
 
7332
                }
 
7333
 
 
7334
                /* count failures (excluding rebuilds and the victim)
 
7335
                 * to determine map[0] state
 
7336
                 */
 
7337
                failed = 0;
 
7338
                for (i = 0; i < map->num_members; i++) {
 
7339
                        if (i == u->slot)
 
7340
                                continue;
 
7341
                        disk = get_imsm_disk(super,
 
7342
                                             get_imsm_disk_idx(dev, i, MAP_X));
 
7343
                        if (!disk || is_failed(disk))
 
7344
                                failed++;
 
7345
                }
 
7346
 
 
7347
                /* adding a pristine spare, assign a new index */
 
7348
                if (dl->index < 0) {
 
7349
                        dl->index = super->anchor->num_disks;
 
7350
                        super->anchor->num_disks++;
 
7351
                }
 
7352
                disk = &dl->disk;
 
7353
                disk->status |= CONFIGURED_DISK;
 
7354
                disk->status &= ~SPARE_DISK;
 
7355
 
 
7356
                /* mark rebuild */
 
7357
                to_state = imsm_check_degraded(super, dev, failed, MAP_0);
 
7358
                if (!second_map_created) {
 
7359
                        second_map_created = 1;
 
7360
                        map->map_state = IMSM_T_STATE_DEGRADED;
 
7361
                        migrate(dev, super, to_state, MIGR_REBUILD);
 
7362
                } else
 
7363
                        map->map_state = to_state;
 
7364
                migr_map = get_imsm_map(dev, MAP_1);
 
7365
                set_imsm_ord_tbl_ent(map, u->slot, dl->index);
 
7366
                set_imsm_ord_tbl_ent(migr_map, u->slot,
 
7367
                                     dl->index | IMSM_ORD_REBUILD);
 
7368
 
 
7369
                /* update the family_num to mark a new container
 
7370
                 * generation, being careful to record the existing
 
7371
                 * family_num in orig_family_num to clean up after
 
7372
                 * earlier mdadm versions that neglected to set it.
 
7373
                 */
 
7374
                if (mpb->orig_family_num == 0)
 
7375
                        mpb->orig_family_num = mpb->family_num;
 
7376
                mpb->family_num += super->random;
 
7377
 
 
7378
                /* count arrays using the victim in the metadata */
 
7379
                found = 0;
 
7380
                for (a = active_array; a ; a = a->next) {
 
7381
                        dev = get_imsm_dev(super, a->info.container_member);
 
7382
                        map = get_imsm_map(dev, MAP_0);
 
7383
 
 
7384
                        if (get_imsm_disk_slot(map, victim) >= 0)
 
7385
                                found++;
 
7386
                }
 
7387
 
 
7388
                /* delete the victim if it is no longer being
 
7389
                 * utilized anywhere
 
7390
                 */
 
7391
                if (!found) {
 
7392
                        struct dl **dlp;
 
7393
 
 
7394
                        /* We know that 'manager' isn't touching anything,
 
7395
                         * so it is safe to delete
 
7396
                         */
 
7397
                        for (dlp = &super->disks; *dlp; dlp = &(*dlp)->next)
 
7398
                                if ((*dlp)->index == victim)
 
7399
                                        break;
 
7400
 
 
7401
                        /* victim may be on the missing list */
 
7402
                        if (!*dlp)
 
7403
                                for (dlp = &super->missing; *dlp;
 
7404
                                     dlp = &(*dlp)->next)
 
7405
                                        if ((*dlp)->index == victim)
 
7406
                                                break;
 
7407
                        imsm_delete(super, dlp, victim);
 
7408
                }
 
7409
        }
 
7410
 
 
7411
        return 1;
 
7412
}
6808
7413
 
6809
7414
static int apply_reshape_container_disks_update(struct imsm_update_reshape *u,
6810
7415
                                                struct intel_super *super,
6866
7471
                newdev = (void*)sp;
6867
7472
                /* Copy the dev, but not (all of) the map */
6868
7473
                memcpy(newdev, id->dev, sizeof(*newdev));
6869
 
                oldmap = get_imsm_map(id->dev, 0);
6870
 
                newmap = get_imsm_map(newdev, 0);
 
7474
                oldmap = get_imsm_map(id->dev, MAP_0);
 
7475
                newmap = get_imsm_map(newdev, MAP_0);
6871
7476
                /* Copy the current map */
6872
7477
                memcpy(newmap, oldmap, sizeof_imsm_map(oldmap));
6873
7478
                /* update one device only
6878
7483
                        devices_to_reshape--;
6879
7484
                        newdev->vol.migr_state = 1;
6880
7485
                        newdev->vol.curr_migr_unit = 0;
6881
 
                        newdev->vol.migr_type = MIGR_GEN_MIGR;
 
7486
                        set_migr_type(newdev, MIGR_GEN_MIGR);
6882
7487
                        newmap->num_members = u->new_raid_disks;
6883
7488
                        for (i = 0; i < delta_disks; i++) {
6884
7489
                                set_imsm_ord_tbl_ent(newmap,
6887
7492
                        }
6888
7493
                        /* New map is correct, now need to save old map
6889
7494
                         */
6890
 
                        newmap = get_imsm_map(newdev, 1);
 
7495
                        newmap = get_imsm_map(newdev, MAP_1);
6891
7496
                        memcpy(newmap, oldmap, sizeof_imsm_map(oldmap));
6892
7497
 
6893
7498
                        imsm_set_array_size(newdev);
6930
7535
        if (dev == NULL)
6931
7536
                return 0;
6932
7537
 
6933
 
        map = get_imsm_map(dev, 0);
 
7538
        map = get_imsm_map(dev, MAP_0);
6934
7539
 
6935
7540
        if (u->direction == R10_TO_R0) {
6936
7541
                /* Number of failed disks must be half of initial disk number */
6937
 
                if (imsm_count_failed(super, dev) != (map->num_members / 2))
 
7542
                if (imsm_count_failed(super, dev, MAP_0) !=
 
7543
                                (map->num_members / 2))
6938
7544
                        return 0;
6939
7545
 
6940
7546
                /* iterate through devices to mark removed disks as spare */
6948
7554
                                        if (du->index > idx)
6949
7555
                                                du->index--;
6950
7556
                                /* mark as spare disk */
6951
 
                                dm->disk.status = SPARE_DISK;
6952
 
                                dm->index = -1;
 
7557
                                mark_spare(dm);
6953
7558
                        }
6954
7559
                }
6955
7560
                /* update map */
6994
7599
                dev_new = (void *)space;
6995
7600
                memcpy(dev_new, dev, sizeof(*dev));
6996
7601
                /* update new map */
6997
 
                map = get_imsm_map(dev_new, 0);
 
7602
                map = get_imsm_map(dev_new, MAP_0);
6998
7603
                map->num_members = map->num_members * 2;
6999
7604
                map->map_state = IMSM_T_STATE_DEGRADED;
7000
7605
                map->num_domains = 2;
7100
7705
        }
7101
7706
        case update_activate_spare: {
7102
7707
                struct imsm_update_activate_spare *u = (void *) update->buf; 
7103
 
                struct imsm_dev *dev = get_imsm_dev(super, u->array);
7104
 
                struct imsm_map *map = get_imsm_map(dev, 0);
7105
 
                struct imsm_map *migr_map;
7106
 
                struct active_array *a;
7107
 
                struct imsm_disk *disk;
7108
 
                __u8 to_state;
7109
 
                struct dl *dl;
7110
 
                unsigned int found;
7111
 
                int failed;
7112
 
                int victim = get_imsm_disk_idx(dev, u->slot, -1);
7113
 
                int i;
7114
 
 
7115
 
                for (dl = super->disks; dl; dl = dl->next)
7116
 
                        if (dl == u->dl)
7117
 
                                break;
7118
 
 
7119
 
                if (!dl) {
7120
 
                        fprintf(stderr, "error: imsm_activate_spare passed "
7121
 
                                "an unknown disk (index: %d)\n",
7122
 
                                u->dl->index);
7123
 
                        return;
7124
 
                }
7125
 
 
7126
 
                super->updates_pending++;
7127
 
                /* count failures (excluding rebuilds and the victim)
7128
 
                 * to determine map[0] state
7129
 
                 */
7130
 
                failed = 0;
7131
 
                for (i = 0; i < map->num_members; i++) {
7132
 
                        if (i == u->slot)
7133
 
                                continue;
7134
 
                        disk = get_imsm_disk(super,
7135
 
                                             get_imsm_disk_idx(dev, i, -1));
7136
 
                        if (!disk || is_failed(disk))
7137
 
                                failed++;
7138
 
                }
7139
 
 
7140
 
                /* adding a pristine spare, assign a new index */
7141
 
                if (dl->index < 0) {
7142
 
                        dl->index = super->anchor->num_disks;
7143
 
                        super->anchor->num_disks++;
7144
 
                }
7145
 
                disk = &dl->disk;
7146
 
                disk->status |= CONFIGURED_DISK;
7147
 
                disk->status &= ~SPARE_DISK;
7148
 
 
7149
 
                /* mark rebuild */
7150
 
                to_state = imsm_check_degraded(super, dev, failed);
7151
 
                map->map_state = IMSM_T_STATE_DEGRADED;
7152
 
                migrate(dev, super, to_state, MIGR_REBUILD);
7153
 
                migr_map = get_imsm_map(dev, 1);
7154
 
                set_imsm_ord_tbl_ent(map, u->slot, dl->index);
7155
 
                set_imsm_ord_tbl_ent(migr_map, u->slot, dl->index | IMSM_ORD_REBUILD);
7156
 
 
7157
 
                /* update the family_num to mark a new container
7158
 
                 * generation, being careful to record the existing
7159
 
                 * family_num in orig_family_num to clean up after
7160
 
                 * earlier mdadm versions that neglected to set it.
7161
 
                 */
7162
 
                if (mpb->orig_family_num == 0)
7163
 
                        mpb->orig_family_num = mpb->family_num;
7164
 
                mpb->family_num += super->random;
7165
 
 
7166
 
                /* count arrays using the victim in the metadata */
7167
 
                found = 0;
7168
 
                for (a = st->arrays; a ; a = a->next) {
7169
 
                        dev = get_imsm_dev(super, a->info.container_member);
7170
 
                        map = get_imsm_map(dev, 0);
7171
 
 
7172
 
                        if (get_imsm_disk_slot(map, victim) >= 0)
7173
 
                                found++;
7174
 
                }
7175
 
 
7176
 
                /* delete the victim if it is no longer being
7177
 
                 * utilized anywhere
7178
 
                 */
7179
 
                if (!found) {
7180
 
                        struct dl **dlp;
7181
 
 
7182
 
                        /* We know that 'manager' isn't touching anything,
7183
 
                         * so it is safe to delete
7184
 
                         */
7185
 
                        for (dlp = &super->disks; *dlp; dlp = &(*dlp)->next)
7186
 
                                if ((*dlp)->index == victim)
7187
 
                                        break;
7188
 
 
7189
 
                        /* victim may be on the missing list */
7190
 
                        if (!*dlp)
7191
 
                                for (dlp = &super->missing; *dlp; dlp = &(*dlp)->next)
7192
 
                                        if ((*dlp)->index == victim)
7193
 
                                                break;
7194
 
                        imsm_delete(super, dlp, victim);
7195
 
                }
 
7708
                if (apply_update_activate_spare(u, super, st->arrays))
 
7709
                        super->updates_pending++;
7196
7710
                break;
7197
7711
        }
7198
7712
        case update_create_array: {
7229
7743
                        goto create_error;
7230
7744
                }
7231
7745
 
7232
 
                new_map = get_imsm_map(&u->dev, 0);
 
7746
                new_map = get_imsm_map(&u->dev, MAP_0);
7233
7747
                new_start = __le32_to_cpu(new_map->pba_of_lba0);
7234
7748
                new_end = new_start + __le32_to_cpu(new_map->blocks_per_member);
7235
7749
                inf = get_disk_info(u);
7240
7754
                 */
7241
7755
                for (i = 0; i < mpb->num_raid_devs; i++) {
7242
7756
                        dev = get_imsm_dev(super, i);
7243
 
                        map = get_imsm_map(dev, 0);
 
7757
                        map = get_imsm_map(dev, MAP_0);
7244
7758
                        start = __le32_to_cpu(map->pba_of_lba0);
7245
7759
                        end = start + __le32_to_cpu(map->blocks_per_member);
7246
7760
                        if ((new_start >= start && new_start <= end) ||
7421
7935
                if (u->direction == R0_TO_R10) {
7422
7936
                        void **tail = (void **)&update->space_list;
7423
7937
                        struct imsm_dev *dev = get_imsm_dev(super, u->subarray);
7424
 
                        struct imsm_map *map = get_imsm_map(dev, 0);
 
7938
                        struct imsm_map *map = get_imsm_map(dev, MAP_0);
7425
7939
                        int num_members = map->num_members;
7426
7940
                        void *space;
7427
7941
                        int size, i;
7553
8067
                                struct imsm_map *map;
7554
8068
 
7555
8069
                                dev = get_imsm_dev(super, u->subdev);
7556
 
                                map = get_imsm_map(dev, 0);
 
8070
                                map = get_imsm_map(dev, MAP_0);
7557
8071
                                current_level = map->raid_level;
7558
8072
                                break;
7559
8073
                        }
7587
8101
                struct imsm_update_create_array *u = (void *) update->buf;
7588
8102
                struct intel_dev *dv;
7589
8103
                struct imsm_dev *dev = &u->dev;
7590
 
                struct imsm_map *map = get_imsm_map(dev, 0);
 
8104
                struct imsm_map *map = get_imsm_map(dev, MAP_0);
7591
8105
                struct dl *dl;
7592
8106
                struct disk_info *inf;
7593
8107
                int i;
7672
8186
 
7673
8187
        for (i = 0; i < mpb->num_raid_devs; i++) {
7674
8188
                dev = get_imsm_dev(super, i);
7675
 
                map = get_imsm_map(dev, 0);
 
8189
                map = get_imsm_map(dev, MAP_0);
7676
8190
                num_members = map->num_members;
7677
8191
                for (j = 0; j < num_members; j++) {
7678
8192
                        /* update ord entries being careful not to propagate
7679
8193
                         * ord-flags to the first map
7680
8194
                         */
7681
 
                        ord = get_imsm_ord_tbl_ent(dev, j, -1);
 
8195
                        ord = get_imsm_ord_tbl_ent(dev, j, MAP_X);
7682
8196
 
7683
8197
                        if (ord_to_idx(ord) <= index)
7684
8198
                                continue;
7685
8199
 
7686
 
                        map = get_imsm_map(dev, 0);
 
8200
                        map = get_imsm_map(dev, MAP_0);
7687
8201
                        set_imsm_ord_tbl_ent(map, j, ord_to_idx(ord - 1));
7688
 
                        map = get_imsm_map(dev, 1);
 
8202
                        map = get_imsm_map(dev, MAP_1);
7689
8203
                        if (map)
7690
8204
                                set_imsm_ord_tbl_ent(map, j, ord - 1);
7691
8205
                }
7701
8215
        }
7702
8216
}
7703
8217
#endif /* MDASSEMBLE */
 
8218
 
 
8219
static void close_targets(int *targets, int new_disks)
 
8220
{
 
8221
        int i;
 
8222
 
 
8223
        if (!targets)
 
8224
                return;
 
8225
 
 
8226
        for (i = 0; i < new_disks; i++) {
 
8227
                if (targets[i] >= 0) {
 
8228
                        close(targets[i]);
 
8229
                        targets[i] = -1;
 
8230
                }
 
8231
        }
 
8232
}
 
8233
 
 
8234
static int imsm_get_allowed_degradation(int level, int raid_disks,
 
8235
                                        struct intel_super *super,
 
8236
                                        struct imsm_dev *dev)
 
8237
{
 
8238
        switch (level) {
 
8239
        case 10:{
 
8240
                int ret_val = 0;
 
8241
                struct imsm_map *map;
 
8242
                int i;
 
8243
 
 
8244
                ret_val = raid_disks/2;
 
8245
                /* check map if all disks pairs not failed
 
8246
                 * in both maps
 
8247
                 */
 
8248
                map = get_imsm_map(dev, MAP_0);
 
8249
                for (i = 0; i < ret_val; i++) {
 
8250
                        int degradation = 0;
 
8251
                        if (get_imsm_disk(super, i) == NULL)
 
8252
                                degradation++;
 
8253
                        if (get_imsm_disk(super, i + 1) == NULL)
 
8254
                                degradation++;
 
8255
                        if (degradation == 2)
 
8256
                                return 0;
 
8257
                }
 
8258
                map = get_imsm_map(dev, MAP_1);
 
8259
                /* if there is no second map
 
8260
                 * result can be returned
 
8261
                 */
 
8262
                if (map == NULL)
 
8263
                        return ret_val;
 
8264
                /* check degradation in second map
 
8265
                 */
 
8266
                for (i = 0; i < ret_val; i++) {
 
8267
                        int degradation = 0;
 
8268
                if (get_imsm_disk(super, i) == NULL)
 
8269
                                degradation++;
 
8270
                        if (get_imsm_disk(super, i + 1) == NULL)
 
8271
                                degradation++;
 
8272
                        if (degradation == 2)
 
8273
                                return 0;
 
8274
                }
 
8275
                return ret_val;
 
8276
        }
 
8277
        case 5:
 
8278
                return 1;
 
8279
        case 6:
 
8280
                return 2;
 
8281
        default:
 
8282
                return 0;
 
8283
        }
 
8284
}
 
8285
 
 
8286
 
7704
8287
/*******************************************************************************
7705
8288
 * Function:    open_backup_targets
7706
8289
 * Description: Function opens file descriptors for all devices given in
7709
8292
 *      info            : general array info
7710
8293
 *      raid_disks      : number of disks
7711
8294
 *      raid_fds        : table of device's file descriptors
 
8295
 *      super           : intel super for raid10 degradation check
 
8296
 *      dev             : intel device for raid10 degradation check
7712
8297
 * Returns:
7713
8298
 *       0 : success
7714
8299
 *      -1 : fail
7715
8300
 ******************************************************************************/
7716
 
int open_backup_targets(struct mdinfo *info, int raid_disks, int *raid_fds)
 
8301
int open_backup_targets(struct mdinfo *info, int raid_disks, int *raid_fds,
 
8302
                        struct intel_super *super, struct imsm_dev *dev)
7717
8303
{
7718
8304
        struct mdinfo *sd;
 
8305
        int i;
 
8306
        int opened = 0;
 
8307
 
 
8308
        for (i = 0; i < raid_disks; i++)
 
8309
                raid_fds[i] = -1;
7719
8310
 
7720
8311
        for (sd = info->devs ; sd ; sd = sd->next) {
7721
8312
                char *dn;
7734
8325
                raid_fds[sd->disk.raid_disk] = dev_open(dn, O_RDWR);
7735
8326
                if (raid_fds[sd->disk.raid_disk] < 0) {
7736
8327
                        fprintf(stderr, "cannot open component\n");
7737
 
                        return -1;
 
8328
                        continue;
7738
8329
                }
 
8330
                opened++;
 
8331
        }
 
8332
        /* check if maximum array degradation level is not exceeded
 
8333
        */
 
8334
        if ((raid_disks - opened) >
 
8335
                        imsm_get_allowed_degradation(info->new_level,
 
8336
                                                     raid_disks,
 
8337
                                                     super, dev)) {
 
8338
                fprintf(stderr, "Not enough disks can be opened.\n");
 
8339
                close_targets(raid_fds, raid_disks);
 
8340
                return -2;
7739
8341
        }
7740
8342
        return 0;
7741
8343
}
7762
8364
        struct mdinfo *sd;
7763
8365
        char nm[30];
7764
8366
        int fd;
7765
 
        struct imsm_map *map_dest = get_imsm_map(dev, 0);
7766
 
        struct imsm_map *map_src = get_imsm_map(dev, 1);
 
8367
        struct imsm_map *map_dest = get_imsm_map(dev, MAP_0);
 
8368
        struct imsm_map *map_src = get_imsm_map(dev, MAP_1);
7767
8369
        unsigned long long num_migr_units;
7768
8370
        unsigned long long array_blocks;
7769
8371
 
7776
8378
        migr_rec->dest_depth_per_unit = GEN_MIGR_AREA_SIZE /
7777
8379
                max(map_dest->blocks_per_strip, map_src->blocks_per_strip);
7778
8380
        migr_rec->dest_depth_per_unit *= map_dest->blocks_per_strip;
7779
 
        new_data_disks = imsm_num_data_members(dev, 0);
 
8381
        new_data_disks = imsm_num_data_members(dev, MAP_0);
7780
8382
        migr_rec->blocks_per_unit =
7781
8383
                __cpu_to_le32(migr_rec->dest_depth_per_unit * new_data_disks);
7782
8384
        migr_rec->dest_depth_per_unit =
7840
8442
        unsigned long long *target_offsets = NULL;
7841
8443
        int *targets = NULL;
7842
8444
        int i;
7843
 
        struct imsm_map *map_dest = get_imsm_map(dev, 0);
 
8445
        struct imsm_map *map_dest = get_imsm_map(dev, MAP_0);
7844
8446
        int new_disks = map_dest->num_members;
7845
8447
        int dest_layout = 0;
7846
8448
        int dest_chunk;
7847
8449
        unsigned long long start;
7848
 
        int data_disks = imsm_num_data_members(dev, 0);
 
8450
        int data_disks = imsm_num_data_members(dev, MAP_0);
7849
8451
 
7850
8452
        targets = malloc(new_disks * sizeof(int));
7851
8453
        if (!targets)
7868
8470
                target_offsets[i] -= start/data_disks;
7869
8471
        }
7870
8472
 
7871
 
        if (open_backup_targets(info, new_disks, targets))
 
8473
        if (open_backup_targets(info, new_disks, targets,
 
8474
                                super, dev))
7872
8475
                goto abort;
7873
8476
 
7874
8477
        dest_layout = imsm_level_to_layout(map_dest->raid_level);
7894
8497
 
7895
8498
abort:
7896
8499
        if (targets) {
7897
 
                for (i = 0; i < new_disks; i++)
7898
 
                        if (targets[i] >= 0)
7899
 
                                close(targets[i]);
 
8500
                close_targets(targets, new_disks);
7900
8501
                free(targets);
7901
8502
        }
7902
8503
        free(target_offsets);
7985
8586
        unsigned long num_migr_units = __le32_to_cpu(migr_rec->num_migr_units);
7986
8587
        char buffer[20];
7987
8588
        int skipped_disks = 0;
7988
 
        int max_degradation;
7989
8589
 
7990
8590
        err = sysfs_get_str(info, NULL, "array_state", (char *)buffer, 20);
7991
8591
        if (err < 1)
8007
8607
        if (id == NULL)
8008
8608
                return 1;
8009
8609
 
8010
 
        map_dest = get_imsm_map(id->dev, 0);
 
8610
        map_dest = get_imsm_map(id->dev, MAP_0);
8011
8611
        new_disks = map_dest->num_members;
8012
 
        max_degradation = new_disks - imsm_num_data_members(id->dev, 0);
8013
8612
 
8014
8613
        read_offset = (unsigned long long)
8015
8614
                        __le32_to_cpu(migr_rec->ckpt_area_pba) * 512;
8025
8624
        if (!targets)
8026
8625
                goto abort;
8027
8626
 
8028
 
        open_backup_targets(info, new_disks, targets);
 
8627
        if (open_backup_targets(info, new_disks, targets, super, id->dev)) {
 
8628
                fprintf(stderr,
 
8629
                        Name ": Cannot open some devices belonging to array.\n");
 
8630
                goto abort;
 
8631
        }
8029
8632
 
8030
8633
        for (i = 0; i < new_disks; i++) {
8031
8634
                if (targets[i] < 0) {
8036
8639
                        fprintf(stderr,
8037
8640
                                Name ": Cannot seek to block: %s\n",
8038
8641
                                strerror(errno));
8039
 
                        goto abort;
 
8642
                        skipped_disks++;
 
8643
                        continue;
8040
8644
                }
8041
8645
                if ((unsigned)read(targets[i], buf, unit_len) != unit_len) {
8042
8646
                        fprintf(stderr,
8043
8647
                                Name ": Cannot read copy area block: %s\n",
8044
8648
                                strerror(errno));
8045
 
                        goto abort;
 
8649
                        skipped_disks++;
 
8650
                        continue;
8046
8651
                }
8047
8652
                if (lseek64(targets[i], write_offset, SEEK_SET) < 0) {
8048
8653
                        fprintf(stderr,
8049
8654
                                Name ": Cannot seek to block: %s\n",
8050
8655
                                strerror(errno));
8051
 
                        goto abort;
 
8656
                        skipped_disks++;
 
8657
                        continue;
8052
8658
                }
8053
8659
                if ((unsigned)write(targets[i], buf, unit_len) != unit_len) {
8054
8660
                        fprintf(stderr,
8055
8661
                                Name ": Cannot restore block: %s\n",
8056
8662
                                strerror(errno));
8057
 
                        goto abort;
 
8663
                        skipped_disks++;
 
8664
                        continue;
8058
8665
                }
8059
8666
        }
8060
8667
 
8061
 
        if (skipped_disks > max_degradation) {
 
8668
        if (skipped_disks > imsm_get_allowed_degradation(info->new_level,
 
8669
                                                         new_disks,
 
8670
                                                         super,
 
8671
                                                         id->dev)) {
8062
8672
                fprintf(stderr,
8063
8673
                        Name ": Cannot restore data from backup."
8064
8674
                        " Too many failed disks\n");
8382
8992
        if (dev) {
8383
8993
                struct imsm_map *map;
8384
8994
 
8385
 
                map = get_imsm_map(dev, 0);
 
8995
                map = get_imsm_map(dev, MAP_0);
8386
8996
                if (map) {
8387
8997
                        int current_chunk_size =
8388
8998
                                __le16_to_cpu(map->blocks_per_strip) / 2;
8451
9061
        int change = -1;
8452
9062
        int check_devs = 0;
8453
9063
        int chunk;
 
9064
        /* number of added/removed disks in operation result */
 
9065
        int devNumChange = 0;
 
9066
        /* imsm compatible layout value for array geometry verification */
 
9067
        int imsm_layout = -1;
8454
9068
 
8455
9069
        getinfo_super_imsm_volume(st, &info, NULL);
8456
9070
        if ((geo->level != info.array.level) &&
8468
9082
                                        change = -1;
8469
9083
                                        goto analyse_change_exit;
8470
9084
                                }
 
9085
                                imsm_layout =  geo->layout;
8471
9086
                                check_devs = 1;
8472
 
                        }
8473
 
                        if (geo->level == 10) {
 
9087
                                devNumChange = 1; /* parity disk added */
 
9088
                        } else if (geo->level == 10) {
8474
9089
                                change = CH_TAKEOVER;
8475
9090
                                check_devs = 1;
 
9091
                                devNumChange = 2; /* two mirrors added */
 
9092
                                imsm_layout = 0x102; /* imsm supported layout */
8476
9093
                        }
8477
9094
                        break;
8478
9095
                case 1:
8479
 
                        if (geo->level == 0) {
8480
 
                                change = CH_TAKEOVER;
8481
 
                                check_devs = 1;
8482
 
                        }
8483
 
                        break;
8484
9096
                case 10:
8485
9097
                        if (geo->level == 0) {
8486
9098
                                change = CH_TAKEOVER;
8487
9099
                                check_devs = 1;
 
9100
                                devNumChange = -(geo->raid_disks/2);
 
9101
                                imsm_layout = 0; /* imsm raid0 layout */
8488
9102
                        }
8489
9103
                        break;
8490
9104
                }
8519
9133
                        change = -1;
8520
9134
                        goto analyse_change_exit;
8521
9135
                }
8522
 
        } else
 
9136
        } else {
8523
9137
                geo->layout = info.array.layout;
 
9138
                if (imsm_layout == -1)
 
9139
                        imsm_layout = info.array.layout;
 
9140
        }
8524
9141
 
8525
9142
        if ((geo->chunksize > 0) && (geo->chunksize != UnSet)
8526
9143
            && (geo->chunksize != info.array.chunk_size))
8531
9148
        chunk = geo->chunksize / 1024;
8532
9149
        if (!validate_geometry_imsm(st,
8533
9150
                                    geo->level,
8534
 
                                    geo->layout,
8535
 
                                    geo->raid_disks,
 
9151
                                    imsm_layout,
 
9152
                                    geo->raid_disks + devNumChange,
8536
9153
                                    &chunk,
8537
9154
                                    geo->size,
8538
9155
                                    0, 0, 1))
8661
9278
                dprintf("imsm: info: Volume operation\n");
8662
9279
                /* find requested device */
8663
9280
                while (dev) {
8664
 
                        imsm_find_array_minor_by_subdev(dev->index, st->container_dev, &devnum);
8665
 
                        if (devnum == geo.dev_id)
 
9281
                        if (imsm_find_array_minor_by_subdev(
 
9282
                                    dev->index, st->container_dev, &devnum) == 0
 
9283
                            && devnum == geo.dev_id)
8666
9284
                                break;
8667
9285
                        dev = dev->next;
8668
9286
                }
8891
9509
                goto abort;
8892
9510
        }
8893
9511
 
8894
 
        map_src = get_imsm_map(dev, 1);
 
9512
        map_src = get_imsm_map(dev, MAP_1);
8895
9513
        if (map_src == NULL)
8896
9514
                goto abort;
8897
9515
 
8898
 
        ndata = imsm_num_data_members(dev, 0);
8899
 
        odata = imsm_num_data_members(dev, 1);
 
9516
        ndata = imsm_num_data_members(dev, MAP_0);
 
9517
        odata = imsm_num_data_members(dev, MAP_1);
8900
9518
 
8901
9519
        chunk = __le16_to_cpu(map_src->blocks_per_strip) * 512;
8902
9520
        old_data_stripe_length = odata * chunk;