super1.c (mdadm-4.1) | : | super1.c (mdadm-4.2) | ||
---|---|---|---|---|
skipping to change at line 46 | skipping to change at line 46 | |||
__u32 magic; /* MD_SB_MAGIC: 0xa92b4efc - little endian */ | __u32 magic; /* MD_SB_MAGIC: 0xa92b4efc - little endian */ | |||
__u32 major_version; /* 1 */ | __u32 major_version; /* 1 */ | |||
__u32 feature_map; /* 0 for now */ | __u32 feature_map; /* 0 for now */ | |||
__u32 pad0; /* always set to 0 when writing */ | __u32 pad0; /* always set to 0 when writing */ | |||
__u8 set_uuid[16]; /* user-space generated. */ | __u8 set_uuid[16]; /* user-space generated. */ | |||
char set_name[32]; /* set and interpreted by user-space */ | char set_name[32]; /* set and interpreted by user-space */ | |||
__u64 ctime; /* lo 40 bits are seconds, top 24 are microsecond s or 0*/ | __u64 ctime; /* lo 40 bits are seconds, top 24 are microsecond s or 0*/ | |||
__u32 level; /* -4 (multipath), -1 (linear), 0,1,4,5 */ | __u32 level; /* -4 (multipath), -1 (linear), 0,1,4,5 */ | |||
__u32 layout; /* only for raid5 currently */ | __u32 layout; /* used for raid5, raid6, raid10, and raid0 */ | |||
__u64 size; /* used size of component devices, in 512byte sec tors */ | __u64 size; /* used size of component devices, in 512byte sec tors */ | |||
__u32 chunksize; /* in 512byte sectors */ | __u32 chunksize; /* in 512byte sectors */ | |||
__u32 raid_disks; | __u32 raid_disks; | |||
union { | union { | |||
__u32 bitmap_offset; /* sectors after start of superblock that bitmap starts | __u32 bitmap_offset; /* sectors after start of superblock that bitmap starts | |||
* NOTE: signed, so bitmap can be before superblock | * NOTE: signed, so bitmap can be before superblock | |||
* only meaningful of feature_map[0] is s et. | * only meaningful of feature_map[0] is s et. | |||
*/ | */ | |||
skipping to change at line 147 | skipping to change at line 147 | |||
*/ | */ | |||
#define MD_FEATURE_RESHAPE_BACKWARDS 32 /* Reshape doesn't change numb er | #define MD_FEATURE_RESHAPE_BACKWARDS 32 /* Reshape doesn't change numb er | |||
* of devices, but is going | * of devices, but is going | |||
* backwards anyway. | * backwards anyway. | |||
*/ | */ | |||
#define MD_FEATURE_NEW_OFFSET 64 /* new_offset must be honoured */ | #define MD_FEATURE_NEW_OFFSET 64 /* new_offset must be honoured */ | |||
#define MD_FEATURE_BITMAP_VERSIONED 256 /* bitmap version number chec ked properly */ | #define MD_FEATURE_BITMAP_VERSIONED 256 /* bitmap version number chec ked properly */ | |||
#define MD_FEATURE_JOURNAL 512 /* support write journal */ | #define MD_FEATURE_JOURNAL 512 /* support write journal */ | |||
#define MD_FEATURE_PPL 1024 /* support PPL */ | #define MD_FEATURE_PPL 1024 /* support PPL */ | |||
#define MD_FEATURE_MUTLIPLE_PPLS 2048 /* support for multiple PPLs */ | #define MD_FEATURE_MUTLIPLE_PPLS 2048 /* support for multiple PPLs */ | |||
#define MD_FEATURE_RAID0_LAYOUT 4096 /* layout is meaningful in R AID0 */ | ||||
#define MD_FEATURE_ALL (MD_FEATURE_BITMAP_OFFSET \ | #define MD_FEATURE_ALL (MD_FEATURE_BITMAP_OFFSET \ | |||
|MD_FEATURE_RECOVERY_OFFSET \ | |MD_FEATURE_RECOVERY_OFFSET \ | |||
|MD_FEATURE_RESHAPE_ACTIVE \ | |MD_FEATURE_RESHAPE_ACTIVE \ | |||
|MD_FEATURE_BAD_BLOCKS \ | |MD_FEATURE_BAD_BLOCKS \ | |||
|MD_FEATURE_REPLACEMENT \ | |MD_FEATURE_REPLACEMENT \ | |||
|MD_FEATURE_RESHAPE_BACKWARDS \ | |MD_FEATURE_RESHAPE_BACKWARDS \ | |||
|MD_FEATURE_NEW_OFFSET \ | |MD_FEATURE_NEW_OFFSET \ | |||
|MD_FEATURE_BITMAP_VERSIONED \ | |MD_FEATURE_BITMAP_VERSIONED \ | |||
|MD_FEATURE_JOURNAL \ | |MD_FEATURE_JOURNAL \ | |||
|MD_FEATURE_PPL \ | |MD_FEATURE_PPL \ | |||
|MD_FEATURE_MULTIPLE_PPLS \ | |MD_FEATURE_MULTIPLE_PPLS \ | |||
|MD_FEATURE_RAID0_LAYOUT \ | ||||
) | ) | |||
static int role_from_sb(struct mdp_superblock_1 *sb) | static int role_from_sb(struct mdp_superblock_1 *sb) | |||
{ | { | |||
unsigned int d; | unsigned int d; | |||
int role; | int role; | |||
d = __le32_to_cpu(sb->dev_number); | d = __le32_to_cpu(sb->dev_number); | |||
if (d < __le32_to_cpu(sb->max_dev)) | if (d < __le32_to_cpu(sb->max_dev)) | |||
role = __le16_to_cpu(sb->dev_roles[d]); | role = __le16_to_cpu(sb->dev_roles[d]); | |||
skipping to change at line 331 | skipping to change at line 333 | |||
time_t atime; | time_t atime; | |||
unsigned int d; | unsigned int d; | |||
int role; | int role; | |||
int delta_extra = 0; | int delta_extra = 0; | |||
int i; | int i; | |||
char *c; | char *c; | |||
int l = homehost ? strlen(homehost) : 0; | int l = homehost ? strlen(homehost) : 0; | |||
int layout; | int layout; | |||
unsigned long long sb_offset; | unsigned long long sb_offset; | |||
struct mdinfo info; | struct mdinfo info; | |||
int inconsistent = 0; | ||||
printf(" Magic : %08x\n", __le32_to_cpu(sb->magic)); | printf(" Magic : %08x\n", __le32_to_cpu(sb->magic)); | |||
printf(" Version : 1"); | printf(" Version : 1"); | |||
sb_offset = __le64_to_cpu(sb->super_offset); | sb_offset = __le64_to_cpu(sb->super_offset); | |||
if (sb_offset <= 4) | if (sb_offset <= 4) | |||
printf(".1\n"); | printf(".1\n"); | |||
else if (sb_offset <= 8) | else if (sb_offset <= 8) | |||
printf(".2\n"); | printf(".2\n"); | |||
else | else | |||
printf(".0\n"); | printf(".0\n"); | |||
skipping to change at line 363 | skipping to change at line 366 | |||
printf("\n"); | printf("\n"); | |||
if (bms->nodes > 0 && | if (bms->nodes > 0 && | |||
(__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET)) | (__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET)) | |||
printf(" Cluster Name : %-64s\n", bms->cluster_name); | printf(" Cluster Name : %-64s\n", bms->cluster_name); | |||
atime = __le64_to_cpu(sb->ctime) & 0xFFFFFFFFFFULL; | atime = __le64_to_cpu(sb->ctime) & 0xFFFFFFFFFFULL; | |||
printf(" Creation Time : %.24s\n", ctime(&atime)); | printf(" Creation Time : %.24s\n", ctime(&atime)); | |||
c=map_num(pers, __le32_to_cpu(sb->level)); | c=map_num(pers, __le32_to_cpu(sb->level)); | |||
printf(" Raid Level : %s\n", c?c:"-unknown-"); | printf(" Raid Level : %s\n", c?c:"-unknown-"); | |||
printf(" Raid Devices : %d\n", __le32_to_cpu(sb->raid_disks)); | printf(" Raid Devices : %d\n", __le32_to_cpu(sb->raid_disks)); | |||
printf("\n"); | printf("\n"); | |||
printf(" Avail Dev Size : %llu%s\n", | printf(" Avail Dev Size : %llu sectors%s\n", | |||
(unsigned long long)__le64_to_cpu(sb->data_size), | (unsigned long long)__le64_to_cpu(sb->data_size), | |||
human_size(__le64_to_cpu(sb->data_size)<<9)); | human_size(__le64_to_cpu(sb->data_size)<<9)); | |||
if (__le32_to_cpu(sb->level) > 0) { | if (__le32_to_cpu(sb->level) > 0) { | |||
int ddsks = 0, ddsks_denom = 1; | int ddsks = 0, ddsks_denom = 1; | |||
switch(__le32_to_cpu(sb->level)) { | switch(__le32_to_cpu(sb->level)) { | |||
case 1: ddsks=1;break; | case 1: ddsks=1;break; | |||
case 4: | case 4: | |||
case 5: ddsks = __le32_to_cpu(sb->raid_disks)-1; break; | case 5: ddsks = __le32_to_cpu(sb->raid_disks)-1; break; | |||
case 6: ddsks = __le32_to_cpu(sb->raid_disks)-2; break; | case 6: ddsks = __le32_to_cpu(sb->raid_disks)-2; break; | |||
case 10: | case 10: | |||
layout = __le32_to_cpu(sb->layout); | layout = __le32_to_cpu(sb->layout); | |||
ddsks = __le32_to_cpu(sb->raid_disks); | ddsks = __le32_to_cpu(sb->raid_disks); | |||
ddsks_denom = (layout&255) * ((layout>>8)&255); | ddsks_denom = (layout&255) * ((layout>>8)&255); | |||
} | } | |||
if (ddsks) { | if (ddsks) { | |||
long long asize = __le64_to_cpu(sb->size); | long long asize = __le64_to_cpu(sb->size); | |||
asize = (asize << 9) * ddsks / ddsks_denom; | asize = (asize << 9) * ddsks / ddsks_denom; | |||
printf(" Array Size : %llu%s\n", | printf(" Array Size : %llu KiB%s\n", | |||
asize >> 10, human_size(asize)); | asize >> 10, human_size(asize)); | |||
} | } | |||
if (sb->size != sb->data_size) | if (sb->size != sb->data_size) | |||
printf(" Used Dev Size : %llu%s\n", | printf(" Used Dev Size : %llu sectors%s\n", | |||
(unsigned long long)__le64_to_cpu(sb->size), | (unsigned long long)__le64_to_cpu(sb->size), | |||
human_size(__le64_to_cpu(sb->size)<<9)); | human_size(__le64_to_cpu(sb->size)<<9)); | |||
} | } | |||
if (sb->data_offset) | if (sb->data_offset) | |||
printf(" Data Offset : %llu sectors\n", | printf(" Data Offset : %llu sectors\n", | |||
(unsigned long long)__le64_to_cpu(sb->data_offset)); | (unsigned long long)__le64_to_cpu(sb->data_offset)); | |||
if (sb->new_offset && | if (sb->new_offset && | |||
(__le32_to_cpu(sb->feature_map) & MD_FEATURE_NEW_OFFSET)) { | (__le32_to_cpu(sb->feature_map) & MD_FEATURE_NEW_OFFSET)) { | |||
unsigned long long offset = __le64_to_cpu(sb->data_offset); | unsigned long long offset = __le64_to_cpu(sb->data_offset); | |||
offset += (signed)(int32_t)__le32_to_cpu(sb->new_offset); | offset += (signed)(int32_t)__le32_to_cpu(sb->new_offset); | |||
skipping to change at line 501 | skipping to change at line 504 | |||
if (calc_sb_1_csum(sb) == sb->sb_csum) | if (calc_sb_1_csum(sb) == sb->sb_csum) | |||
printf(" Checksum : %x - correct\n", | printf(" Checksum : %x - correct\n", | |||
__le32_to_cpu(sb->sb_csum)); | __le32_to_cpu(sb->sb_csum)); | |||
else | else | |||
printf(" Checksum : %x - expected %x\n", | printf(" Checksum : %x - expected %x\n", | |||
__le32_to_cpu(sb->sb_csum), | __le32_to_cpu(sb->sb_csum), | |||
__le32_to_cpu(calc_sb_1_csum(sb))); | __le32_to_cpu(calc_sb_1_csum(sb))); | |||
printf(" Events : %llu\n", | printf(" Events : %llu\n", | |||
(unsigned long long)__le64_to_cpu(sb->events)); | (unsigned long long)__le64_to_cpu(sb->events)); | |||
printf("\n"); | printf("\n"); | |||
if (__le32_to_cpu(sb->level) == 0 && | ||||
(sb->feature_map & __cpu_to_le32(MD_FEATURE_RAID0_LAYOUT))) { | ||||
c = map_num(r0layout, __le32_to_cpu(sb->layout)); | ||||
printf(" Layout : %s\n", c?c:"-unknown-"); | ||||
} | ||||
if (__le32_to_cpu(sb->level) == 5) { | if (__le32_to_cpu(sb->level) == 5) { | |||
c = map_num(r5layout, __le32_to_cpu(sb->layout)); | c = map_num(r5layout, __le32_to_cpu(sb->layout)); | |||
printf(" Layout : %s\n", c?c:"-unknown-"); | printf(" Layout : %s\n", c?c:"-unknown-"); | |||
} | } | |||
if (__le32_to_cpu(sb->level) == 6) { | if (__le32_to_cpu(sb->level) == 6) { | |||
c = map_num(r6layout, __le32_to_cpu(sb->layout)); | c = map_num(r6layout, __le32_to_cpu(sb->layout)); | |||
printf(" Layout : %s\n", c?c:"-unknown-"); | printf(" Layout : %s\n", c?c:"-unknown-"); | |||
} | } | |||
if (__le32_to_cpu(sb->level) == 10) { | if (__le32_to_cpu(sb->level) == 10) { | |||
int lo = __le32_to_cpu(sb->layout); | int lo = __le32_to_cpu(sb->layout); | |||
skipping to change at line 572 | skipping to change at line 580 | |||
printf(" Array State : "); | printf(" Array State : "); | |||
for (d = 0; d < __le32_to_cpu(sb->raid_disks) + delta_extra; d++) { | for (d = 0; d < __le32_to_cpu(sb->raid_disks) + delta_extra; d++) { | |||
int cnt = 0; | int cnt = 0; | |||
unsigned int i; | unsigned int i; | |||
for (i = 0; i < __le32_to_cpu(sb->max_dev); i++) { | for (i = 0; i < __le32_to_cpu(sb->max_dev); i++) { | |||
unsigned int role = __le16_to_cpu(sb->dev_roles[i]); | unsigned int role = __le16_to_cpu(sb->dev_roles[i]); | |||
if (role == d) | if (role == d) | |||
cnt++; | cnt++; | |||
} | } | |||
if (cnt == 2) | if (cnt == 2 && __le32_to_cpu(sb->level) > 0) | |||
printf("R"); | printf("R"); | |||
else if (cnt == 1) | else if (cnt == 1) | |||
printf("A"); | printf("A"); | |||
else if (cnt == 0) | else if (cnt == 0) | |||
printf("."); | printf("."); | |||
else | else { | |||
printf("?"); | printf("?"); | |||
inconsistent = 1; | ||||
} | ||||
} | } | |||
#if 0 | #if 0 | |||
/* This is confusing too */ | /* This is confusing too */ | |||
faulty = 0; | faulty = 0; | |||
for (i = 0; i< __le32_to_cpu(sb->max_dev); i++) { | for (i = 0; i< __le32_to_cpu(sb->max_dev); i++) { | |||
int role = __le16_to_cpu(sb->dev_roles[i]); | int role = __le16_to_cpu(sb->dev_roles[i]); | |||
if (role == MD_DISK_ROLE_FAULTY) | if (role == MD_DISK_ROLE_FAULTY) | |||
faulty++; | faulty++; | |||
} | } | |||
if (faulty) | if (faulty) | |||
printf(" %d failed", faulty); | printf(" %d failed", faulty); | |||
#endif | #endif | |||
printf(" ('A' == active, '.' == missing, 'R' == replacing)"); | printf(" ('A' == active, '.' == missing, 'R' == replacing)"); | |||
printf("\n"); | printf("\n"); | |||
for (d = 0; d < __le32_to_cpu(sb->max_dev); d++) { | ||||
unsigned int r = __le16_to_cpu(sb->dev_roles[d]); | ||||
if (r <= MD_DISK_ROLE_MAX && | ||||
r > __le32_to_cpu(sb->raid_disks) + delta_extra) | ||||
inconsistent = 1; | ||||
} | ||||
if (inconsistent) { | ||||
printf("WARNING Array state is inconsistent - each number should | ||||
appear only once\n"); | ||||
for (d = 0; d < __le32_to_cpu(sb->max_dev); d++) | ||||
if (__le16_to_cpu(sb->dev_roles[d]) >= MD_DISK_ROLE_FAULT | ||||
Y) | ||||
printf(" %d:-", d); | ||||
else | ||||
printf(" %d:%d", d, __le16_to_cpu(sb->dev_roles[d | ||||
])); | ||||
printf("\n"); | ||||
} | ||||
} | } | |||
static void brief_examine_super1(struct supertype *st, int verbose) | static void brief_examine_super1(struct supertype *st, int verbose) | |||
{ | { | |||
struct mdp_superblock_1 *sb = st->sb; | struct mdp_superblock_1 *sb = st->sb; | |||
int i; | int i; | |||
unsigned long long sb_offset; | unsigned long long sb_offset; | |||
char *nm; | char *nm; | |||
char *c = map_num(pers, __le32_to_cpu(sb->level)); | char *c = map_num(pers, __le32_to_cpu(sb->level)); | |||
skipping to change at line 836 | skipping to change at line 861 | |||
} | } | |||
free(buf); | free(buf); | |||
return 0; | return 0; | |||
err: | err: | |||
free(buf); | free(buf); | |||
return 1; | return 1; | |||
} | } | |||
static void detail_super1(struct supertype *st, char *homehost) | static void detail_super1(struct supertype *st, char *homehost, char *subarray) | |||
{ | { | |||
struct mdp_superblock_1 *sb = st->sb; | struct mdp_superblock_1 *sb = st->sb; | |||
bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); | bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); | |||
int i; | int i; | |||
int l = homehost ? strlen(homehost) : 0; | int l = homehost ? strlen(homehost) : 0; | |||
printf(" Name : %.32s", sb->set_name); | printf(" Name : %.32s", sb->set_name); | |||
if (l > 0 && l < 32 && sb->set_name[l] == ':' && | if (l > 0 && l < 32 && sb->set_name[l] == ':' && | |||
strncmp(sb->set_name, homehost, l) == 0) | strncmp(sb->set_name, homehost, l) == 0) | |||
printf(" (local to host %s)", homehost); | printf(" (local to host %s)", homehost); | |||
skipping to change at line 860 | skipping to change at line 885 | |||
printf("\n UUID : "); | printf("\n UUID : "); | |||
for (i = 0; i < 16; i++) { | for (i = 0; i < 16; i++) { | |||
if ((i&3) == 0 && i != 0) | if ((i&3) == 0 && i != 0) | |||
printf(":"); | printf(":"); | |||
printf("%02x", sb->set_uuid[i]); | printf("%02x", sb->set_uuid[i]); | |||
} | } | |||
printf("\n Events : %llu\n\n", | printf("\n Events : %llu\n\n", | |||
(unsigned long long)__le64_to_cpu(sb->events)); | (unsigned long long)__le64_to_cpu(sb->events)); | |||
} | } | |||
static void brief_detail_super1(struct supertype *st) | static void brief_detail_super1(struct supertype *st, char *subarray) | |||
{ | { | |||
struct mdp_superblock_1 *sb = st->sb; | struct mdp_superblock_1 *sb = st->sb; | |||
int i; | int i; | |||
if (sb->set_name[0]) { | if (sb->set_name[0]) { | |||
printf(" name="); | printf(" name="); | |||
print_quoted(sb->set_name); | print_quoted(sb->set_name); | |||
} | } | |||
printf(" UUID="); | printf(" UUID="); | |||
for (i = 0; i < 16; i++) { | for (i = 0; i < 16; i++) { | |||
skipping to change at line 1260 | skipping to change at line 1285 | |||
sb->feature_map & | sb->feature_map & | |||
__le32_to_cpu(MD_FEATURE_RESHAPE_ACTIVE) && | __le32_to_cpu(MD_FEATURE_RESHAPE_ACTIVE) && | |||
info->delta_disks < 0 && | info->delta_disks < 0 && | |||
info->reshape_progress > | info->reshape_progress > | |||
__le64_to_cpu(sb->reshape_position)) { | __le64_to_cpu(sb->reshape_position)) { | |||
sb->reshape_position = | sb->reshape_position = | |||
__cpu_to_le64(info->reshape_progress); | __cpu_to_le64(info->reshape_progress); | |||
rv = 1; | rv = 1; | |||
} | } | |||
} else if (strcmp(update, "linear-grow-new") == 0) { | } else if (strcmp(update, "linear-grow-new") == 0) { | |||
unsigned int i; | int i; | |||
int fd; | int fd; | |||
unsigned int max = __le32_to_cpu(sb->max_dev); | int max = __le32_to_cpu(sb->max_dev); | |||
if (max > MAX_DEVS) | ||||
return -2; | ||||
for (i = 0; i < max; i++) | for (i = 0; i < max; i++) | |||
if (__le16_to_cpu(sb->dev_roles[i]) >= | if (__le16_to_cpu(sb->dev_roles[i]) >= | |||
MD_DISK_ROLE_FAULTY) | MD_DISK_ROLE_FAULTY) | |||
break; | break; | |||
if (i != info->disk.number) | ||||
return -2; | ||||
sb->dev_number = __cpu_to_le32(i); | sb->dev_number = __cpu_to_le32(i); | |||
info->disk.number = i; | ||||
if (i >= max) { | if (i == max) | |||
sb->max_dev = __cpu_to_le32(max+1); | sb->max_dev = __cpu_to_le32(max+1); | |||
} | if (i > max) | |||
return -2; | ||||
random_uuid(sb->device_uuid); | random_uuid(sb->device_uuid); | |||
sb->dev_roles[i] = __cpu_to_le16(info->disk.raid_disk); | sb->dev_roles[i] = __cpu_to_le16(info->disk.raid_disk); | |||
fd = open(devname, O_RDONLY); | fd = open(devname, O_RDONLY); | |||
if (fd >= 0) { | if (fd >= 0) { | |||
unsigned long long ds; | unsigned long long ds; | |||
get_dev_size(fd, devname, &ds); | get_dev_size(fd, devname, &ds); | |||
close(fd); | close(fd); | |||
skipping to change at line 1298 | skipping to change at line 1329 | |||
} else { | } else { | |||
ds -= 8*2; | ds -= 8*2; | |||
ds &= ~(unsigned long long)(4*2-1); | ds &= ~(unsigned long long)(4*2-1); | |||
sb->super_offset = __cpu_to_le64(ds); | sb->super_offset = __cpu_to_le64(ds); | |||
sb->data_size = __cpu_to_le64( | sb->data_size = __cpu_to_le64( | |||
ds - __le64_to_cpu(sb->data_offset)); | ds - __le64_to_cpu(sb->data_offset)); | |||
} | } | |||
} | } | |||
} else if (strcmp(update, "linear-grow-update") == 0) { | } else if (strcmp(update, "linear-grow-update") == 0) { | |||
int max = __le32_to_cpu(sb->max_dev); | int max = __le32_to_cpu(sb->max_dev); | |||
sb->raid_disks = __cpu_to_le32(info->array.raid_disks); | int i = info->disk.number; | |||
if (info->array.raid_disks > max) { | if (max > MAX_DEVS || i > MAX_DEVS) | |||
return -2; | ||||
if (i > max) | ||||
return -2; | ||||
if (i == max) | ||||
sb->max_dev = __cpu_to_le32(max+1); | sb->max_dev = __cpu_to_le32(max+1); | |||
} | sb->raid_disks = __cpu_to_le32(info->array.raid_disks); | |||
sb->dev_roles[info->disk.number] = | sb->dev_roles[info->disk.number] = | |||
__cpu_to_le16(info->disk.raid_disk); | __cpu_to_le16(info->disk.raid_disk); | |||
} else if (strcmp(update, "resync") == 0) { | } else if (strcmp(update, "resync") == 0) { | |||
/* make sure resync happens */ | /* make sure resync happens */ | |||
sb->resync_offset = 0ULL; | sb->resync_offset = 0ULL; | |||
} else if (strcmp(update, "uuid") == 0) { | } else if (strcmp(update, "uuid") == 0) { | |||
copy_uuid(sb->set_uuid, info->uuid, super1.swapuuid); | copy_uuid(sb->set_uuid, info->uuid, super1.swapuuid); | |||
if (__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET) | if (__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET) | |||
memcpy(bms->uuid, sb->set_uuid, 16); | memcpy(bms->uuid, sb->set_uuid, 16); | |||
} else if (strcmp(update, "no-bitmap") == 0) { | } else if (strcmp(update, "no-bitmap") == 0) { | |||
sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_BITMAP_OFFSET); | sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_BITMAP_OFFSET); | |||
if (bms->version == BITMAP_MAJOR_CLUSTERED && !IsBitmapDirty(devn | ||||
ame)) | ||||
sb->resync_offset = MaxSector; | ||||
} else if (strcmp(update, "bbl") == 0) { | } else if (strcmp(update, "bbl") == 0) { | |||
/* only possible if there is room after the bitmap, or if | /* only possible if there is room after the bitmap, or if | |||
* there is no bitmap | * there is no bitmap | |||
*/ | */ | |||
unsigned long long sb_offset = __le64_to_cpu(sb->super_offset); | unsigned long long sb_offset = __le64_to_cpu(sb->super_offset); | |||
unsigned long long data_offset = __le64_to_cpu(sb->data_offset); | unsigned long long data_offset = __le64_to_cpu(sb->data_offset); | |||
long bitmap_offset = 0; | long bitmap_offset = 0; | |||
long bm_sectors = 0; | long bm_sectors = 0; | |||
long space; | long space; | |||
skipping to change at line 1546 | skipping to change at line 1583 | |||
} else if (strcmp(update, "_reshape_progress") == 0) | } else if (strcmp(update, "_reshape_progress") == 0) | |||
sb->reshape_position = __cpu_to_le64(info->reshape_progress); | sb->reshape_position = __cpu_to_le64(info->reshape_progress); | |||
else if (strcmp(update, "writemostly") == 0) | else if (strcmp(update, "writemostly") == 0) | |||
sb->devflags |= WriteMostly1; | sb->devflags |= WriteMostly1; | |||
else if (strcmp(update, "readwrite") == 0) | else if (strcmp(update, "readwrite") == 0) | |||
sb->devflags &= ~WriteMostly1; | sb->devflags &= ~WriteMostly1; | |||
else if (strcmp(update, "failfast") == 0) | else if (strcmp(update, "failfast") == 0) | |||
sb->devflags |= FailFast1; | sb->devflags |= FailFast1; | |||
else if (strcmp(update, "nofailfast") == 0) | else if (strcmp(update, "nofailfast") == 0) | |||
sb->devflags &= ~FailFast1; | sb->devflags &= ~FailFast1; | |||
else | else if (strcmp(update, "layout-original") == 0 || | |||
strcmp(update, "layout-alternate") == 0 || | ||||
strcmp(update, "layout-unspecified") == 0) { | ||||
if (__le32_to_cpu(sb->level) != 0) { | ||||
pr_err("%s: %s only supported for RAID0\n", | ||||
devname?:"", update); | ||||
rv = -1; | ||||
} else if (strcmp(update, "layout-unspecified") == 0) { | ||||
sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_RAID0_LAYOUT | ||||
); | ||||
sb->layout = 0; | ||||
} else { | ||||
sb->feature_map |= __cpu_to_le32(MD_FEATURE_RAID0_LAYOUT) | ||||
; | ||||
sb->layout = __cpu_to_le32(update[7] == 'o' ? 1 : 2); | ||||
} | ||||
} else | ||||
rv = -1; | rv = -1; | |||
sb->sb_csum = calc_sb_1_csum(sb); | sb->sb_csum = calc_sb_1_csum(sb); | |||
return rv; | return rv; | |||
} | } | |||
static int init_super1(struct supertype *st, mdu_array_info_t *info, | static int init_super1(struct supertype *st, mdu_array_info_t *info, | |||
struct shape *s, char *name, char *homehost, | struct shape *s, char *name, char *homehost, | |||
int *uuid, unsigned long long data_offset) | int *uuid, unsigned long long data_offset) | |||
skipping to change at line 1649 | skipping to change at line 1700 | |||
if (s->consistency_policy == CONSISTENCY_POLICY_PPL) | if (s->consistency_policy == CONSISTENCY_POLICY_PPL) | |||
sb->feature_map |= __cpu_to_le32(MD_FEATURE_PPL); | sb->feature_map |= __cpu_to_le32(MD_FEATURE_PPL); | |||
return 1; | return 1; | |||
} | } | |||
struct devinfo { | struct devinfo { | |||
int fd; | int fd; | |||
char *devname; | char *devname; | |||
long long data_offset; | long long data_offset; | |||
unsigned long long dev_size; | ||||
mdu_disk_info_t disk; | mdu_disk_info_t disk; | |||
struct devinfo *next; | struct devinfo *next; | |||
}; | }; | |||
/* Add a device to the superblock being created */ | /* Add a device to the superblock being created */ | |||
static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk, | static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk, | |||
int fd, char *devname, unsigned long long data_offset) | int fd, char *devname, unsigned long long data_offset) | |||
{ | { | |||
struct mdp_superblock_1 *sb = st->sb; | struct mdp_superblock_1 *sb = st->sb; | |||
__u16 *rp = sb->dev_roles + dk->number; | __u16 *rp = sb->dev_roles + dk->number; | |||
skipping to change at line 1690 | skipping to change at line 1742 | |||
sb->sb_csum = calc_sb_1_csum(sb); | sb->sb_csum = calc_sb_1_csum(sb); | |||
dip = (struct devinfo **)&st->info; | dip = (struct devinfo **)&st->info; | |||
while (*dip) | while (*dip) | |||
dip = &(*dip)->next; | dip = &(*dip)->next; | |||
di = xmalloc(sizeof(struct devinfo)); | di = xmalloc(sizeof(struct devinfo)); | |||
di->fd = fd; | di->fd = fd; | |||
di->devname = devname; | di->devname = devname; | |||
di->disk = *dk; | di->disk = *dk; | |||
di->data_offset = data_offset; | di->data_offset = data_offset; | |||
get_dev_size(fd, NULL, &di->dev_size); | ||||
di->next = NULL; | di->next = NULL; | |||
*dip = di; | *dip = di; | |||
return 0; | return 0; | |||
} | } | |||
static int locate_bitmap1(struct supertype *st, int fd, int node_num); | static int locate_bitmap1(struct supertype *st, int fd, int node_num); | |||
static int store_super1(struct supertype *st, int fd) | static int store_super1(struct supertype *st, int fd) | |||
{ | { | |||
skipping to change at line 1891 | skipping to change at line 1944 | |||
{ | { | |||
struct mdp_superblock_1 *sb = st->sb; | struct mdp_superblock_1 *sb = st->sb; | |||
struct supertype *refst; | struct supertype *refst; | |||
int rv = 0; | int rv = 0; | |||
unsigned long long bm_space; | unsigned long long bm_space; | |||
struct devinfo *di; | struct devinfo *di; | |||
unsigned long long dsize, array_size; | unsigned long long dsize, array_size; | |||
unsigned long long sb_offset; | unsigned long long sb_offset; | |||
unsigned long long data_offset; | unsigned long long data_offset; | |||
long bm_offset; | long bm_offset; | |||
int raid0_need_layout = 0; | ||||
for (di = st->info; di; di = di->next) { | for (di = st->info; di; di = di->next) { | |||
if (di->disk.state & (1 << MD_DISK_JOURNAL)) | if (di->disk.state & (1 << MD_DISK_JOURNAL)) | |||
sb->feature_map |= __cpu_to_le32(MD_FEATURE_JOURNAL); | sb->feature_map |= __cpu_to_le32(MD_FEATURE_JOURNAL); | |||
if (sb->level == 0 && sb->layout != 0) { | ||||
struct devinfo *di2 = st->info; | ||||
unsigned long long s1, s2; | ||||
s1 = di->dev_size; | ||||
if (di->data_offset != INVALID_SECTORS) | ||||
s1 -= di->data_offset; | ||||
s1 /= __le32_to_cpu(sb->chunksize); | ||||
s2 = di2->dev_size; | ||||
if (di2->data_offset != INVALID_SECTORS) | ||||
s2 -= di2->data_offset; | ||||
s2 /= __le32_to_cpu(sb->chunksize); | ||||
if (s1 != s2) | ||||
raid0_need_layout = 1; | ||||
} | ||||
} | } | |||
for (di = st->info; di; di = di->next) { | for (di = st->info; di; di = di->next) { | |||
if (di->disk.state & (1 << MD_DISK_FAULTY)) | if (di->disk.state & (1 << MD_DISK_FAULTY)) | |||
continue; | continue; | |||
if (di->fd < 0) | if (di->fd < 0) | |||
continue; | continue; | |||
while (Kill(di->devname, NULL, 0, -1, 1) == 0) | while (Kill(di->devname, NULL, 0, -1, 1) == 0) | |||
; | ; | |||
skipping to change at line 2042 | skipping to change at line 2110 | |||
} | } | |||
/* | /* | |||
* Disable badblock log on clusters, or when | * Disable badblock log on clusters, or when | |||
* explicitly requested | * explicitly requested | |||
*/ | */ | |||
if (st->nodes > 0 || conf_get_create_info()->bblist == 0) { | if (st->nodes > 0 || conf_get_create_info()->bblist == 0) { | |||
sb->bblog_size = 0; | sb->bblog_size = 0; | |||
sb->bblog_offset = 0; | sb->bblog_offset = 0; | |||
} | } | |||
/* RAID0 needs a layout if devices aren't all the same size */ | ||||
if (raid0_need_layout) | ||||
sb->feature_map |= __cpu_to_le32(MD_FEATURE_RAID0_LAYOUT) | ||||
; | ||||
sb->sb_csum = calc_sb_1_csum(sb); | sb->sb_csum = calc_sb_1_csum(sb); | |||
rv = store_super1(st, di->fd); | rv = store_super1(st, di->fd); | |||
if (rv == 0 && (di->disk.state & (1 << MD_DISK_JOURNAL))) { | if (rv == 0 && (di->disk.state & (1 << MD_DISK_JOURNAL))) { | |||
rv = write_empty_r5l_meta_block(st, di->fd); | rv = write_empty_r5l_meta_block(st, di->fd); | |||
if (rv) | if (rv) | |||
goto error_out; | goto error_out; | |||
} | } | |||
if (rv == 0 && | if (rv == 0 && | |||
skipping to change at line 2075 | skipping to change at line 2147 | |||
if (rv) | if (rv) | |||
goto error_out; | goto error_out; | |||
} | } | |||
error_out: | error_out: | |||
if (rv) | if (rv) | |||
pr_err("Failed to write metadata to %s\n", di->devname); | pr_err("Failed to write metadata to %s\n", di->devname); | |||
out: | out: | |||
return rv; | return rv; | |||
} | } | |||
static int compare_super1(struct supertype *st, struct supertype *tst) | static int compare_super1(struct supertype *st, struct supertype *tst, | |||
int verbose) | ||||
{ | { | |||
/* | /* | |||
* return: | * return: | |||
* 0 same, or first was empty, and second was copied | * 0 same, or first was empty, and second was copied | |||
* 1 second had wrong number | * 1 second had wrong number | |||
* 2 wrong uuid | * 2 wrong uuid | |||
* 3 wrong other info | * 3 wrong other info | |||
*/ | */ | |||
struct mdp_superblock_1 *first = st->sb; | struct mdp_superblock_1 *first = st->sb; | |||
struct mdp_superblock_1 *second = tst->sb; | struct mdp_superblock_1 *second = tst->sb; | |||
skipping to change at line 2543 | skipping to change at line 2616 | |||
strncpy((char *)bms->cluster_name, st->cluster_name, len); | strncpy((char *)bms->cluster_name, st->cluster_name, len); | |||
bms->cluster_name[len - 1] = '\0'; | bms->cluster_name[len - 1] = '\0'; | |||
} | } | |||
*chunkp = chunk; | *chunkp = chunk; | |||
return 0; | return 0; | |||
} | } | |||
static int locate_bitmap1(struct supertype *st, int fd, int node_num) | static int locate_bitmap1(struct supertype *st, int fd, int node_num) | |||
{ | { | |||
unsigned long long offset; | unsigned long long offset, bm_sectors_per_node; | |||
struct mdp_superblock_1 *sb; | struct mdp_superblock_1 *sb; | |||
bitmap_super_t *bms; | ||||
int mustfree = 0; | int mustfree = 0; | |||
int ret; | int ret; | |||
if (!st->sb) { | if (!st->sb) { | |||
if (st->ss->load_super(st, fd, NULL)) | if (st->ss->load_super(st, fd, NULL)) | |||
return -1; /* no error I hope... */ | return -1; /* no error I hope... */ | |||
mustfree = 1; | mustfree = 1; | |||
} | } | |||
sb = st->sb; | sb = st->sb; | |||
if ((__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET)) | if ((__le32_to_cpu(sb->feature_map) & MD_FEATURE_BITMAP_OFFSET)) | |||
ret = 0; | ret = 0; | |||
else | else | |||
ret = -1; | ret = -1; | |||
offset = __le64_to_cpu(sb->super_offset); | ||||
offset += (int32_t) __le32_to_cpu(sb->bitmap_offset) * (node_num + 1); | offset = __le64_to_cpu(sb->super_offset) + (int32_t)__le32_to_cpu(sb->bit | |||
map_offset); | ||||
if (node_num) { | ||||
bms = (bitmap_super_t*)(((char*)sb)+MAX_SB_SIZE); | ||||
bm_sectors_per_node = calc_bitmap_size(bms, 4096) >> 9; | ||||
offset += bm_sectors_per_node * node_num; | ||||
} | ||||
if (mustfree) | if (mustfree) | |||
free(sb); | free(sb); | |||
lseek64(fd, offset<<9, 0); | lseek64(fd, offset<<9, 0); | |||
return ret; | return ret; | |||
} | } | |||
static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update ) | static int write_bitmap1(struct supertype *st, int fd, enum bitmap_update update ) | |||
{ | { | |||
struct mdp_superblock_1 *sb = st->sb; | struct mdp_superblock_1 *sb = st->sb; | |||
bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb)+MAX_SB_SIZE); | bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb)+MAX_SB_SIZE); | |||
skipping to change at line 2644 | skipping to change at line 2723 | |||
bms->nodes = __cpu_to_le32(st->nodes); | bms->nodes = __cpu_to_le32(st->nodes); | |||
break; | break; | |||
case NoUpdate: | case NoUpdate: | |||
default: | default: | |||
break; | break; | |||
} | } | |||
init_afd(&afd, fd); | init_afd(&afd, fd); | |||
locate_bitmap1(st, fd, 0); | if (locate_bitmap1(st, fd, 0) < 0) { | |||
pr_err("Error: Invalid bitmap\n"); | ||||
return -EINVAL; | ||||
} | ||||
if (posix_memalign(&buf, 4096, 4096)) | if (posix_memalign(&buf, 4096, 4096)) | |||
return -ENOMEM; | return -ENOMEM; | |||
do { | do { | |||
/* Only the bitmap[0] should resync | /* Only the bitmap[0] should resync | |||
* whole device on initial assembly | * whole device on initial assembly | |||
*/ | */ | |||
if (i) | if (i) | |||
memset(buf, 0x00, 4096); | memset(buf, 0x00, 4096); | |||
skipping to change at line 2718 | skipping to change at line 2800 | |||
static int validate_geometry1(struct supertype *st, int level, | static int validate_geometry1(struct supertype *st, int level, | |||
int layout, int raiddisks, | int layout, int raiddisks, | |||
int *chunk, unsigned long long size, | int *chunk, unsigned long long size, | |||
unsigned long long data_offset, | unsigned long long data_offset, | |||
char *subdev, unsigned long long *freesize, | char *subdev, unsigned long long *freesize, | |||
int consistency_policy, int verbose) | int consistency_policy, int verbose) | |||
{ | { | |||
unsigned long long ldsize, devsize; | unsigned long long ldsize, devsize; | |||
int bmspace; | int bmspace; | |||
unsigned long long headroom; | unsigned long long headroom; | |||
unsigned long long overhead; | ||||
int fd; | int fd; | |||
if (level == LEVEL_CONTAINER) { | if (level == LEVEL_CONTAINER) { | |||
if (verbose) | if (verbose) | |||
pr_err("1.x metadata does not support containers\n"); | pr_err("1.x metadata does not support containers\n"); | |||
return 0; | return 0; | |||
} | } | |||
if (*chunk == UnSet) | if (*chunk == UnSet) | |||
*chunk = DEFAULT_CHUNK; | *chunk = DEFAULT_CHUNK; | |||
skipping to change at line 2750 | skipping to change at line 2833 | |||
return 0; | return 0; | |||
} | } | |||
if (!get_dev_size(fd, subdev, &ldsize)) { | if (!get_dev_size(fd, subdev, &ldsize)) { | |||
close(fd); | close(fd); | |||
return 0; | return 0; | |||
} | } | |||
close(fd); | close(fd); | |||
devsize = ldsize >> 9; | devsize = ldsize >> 9; | |||
if (devsize < 24) { | ||||
*freesize = 0; | ||||
return 0; | ||||
} | ||||
/* creating: allow suitable space for bitmap or PPL */ | /* creating: allow suitable space for bitmap or PPL */ | |||
if (consistency_policy == CONSISTENCY_POLICY_PPL) | if (consistency_policy == CONSISTENCY_POLICY_PPL) | |||
bmspace = MULTIPLE_PPL_AREA_SIZE_SUPER1 >> 9; | bmspace = MULTIPLE_PPL_AREA_SIZE_SUPER1 >> 9; | |||
else | else | |||
bmspace = choose_bm_space(devsize); | bmspace = choose_bm_space(devsize); | |||
if (data_offset == INVALID_SECTORS) | if (data_offset == INVALID_SECTORS) | |||
data_offset = st->data_offset; | data_offset = st->data_offset; | |||
if (data_offset == INVALID_SECTORS) | if (data_offset == INVALID_SECTORS) | |||
skipping to change at line 2794 | skipping to change at line 2873 | |||
#define ONE_MEG (2*1024) | #define ONE_MEG (2*1024) | |||
data_offset = ROUND_UP(data_offset, ONE_MEG); | data_offset = ROUND_UP(data_offset, ONE_MEG); | |||
break; | break; | |||
} | } | |||
if (st->data_offset == INVALID_SECTORS) | if (st->data_offset == INVALID_SECTORS) | |||
st->data_offset = data_offset; | st->data_offset = data_offset; | |||
switch(st->minor_version) { | switch(st->minor_version) { | |||
case 0: /* metadata at end. Round down and subtract space to reserve */ | case 0: /* metadata at end. Round down and subtract space to reserve */ | |||
devsize = (devsize & ~(4ULL*2-1)); | devsize = (devsize & ~(4ULL*2-1)); | |||
/* space for metadata, bblog, bitmap/ppl */ | /* space for metadata, bblog, bitmap/ppl */ | |||
devsize -= 8*2 + 8 + bmspace; | overhead = 8*2 + 8 + bmspace; | |||
if (devsize < overhead) /* detect underflow */ | ||||
goto dev_too_small_err; | ||||
devsize -= overhead; | ||||
break; | break; | |||
case 1: | case 1: | |||
case 2: | case 2: | |||
if (devsize < data_offset) /* detect underflow */ | ||||
goto dev_too_small_err; | ||||
devsize -= data_offset; | devsize -= data_offset; | |||
break; | break; | |||
} | } | |||
*freesize = devsize; | *freesize = devsize; | |||
return 1; | return 1; | |||
/* Error condition, device cannot even hold the overhead. */ | ||||
dev_too_small_err: | ||||
fprintf(stderr, "device %s is too small (%lluK) for " | ||||
"required metadata!\n", subdev, devsize>>1); | ||||
*freesize = 0; | ||||
return 0; | ||||
} | } | |||
void *super1_make_v0(struct supertype *st, struct mdinfo *info, mdp_super_t *sb0 ) | void *super1_make_v0(struct supertype *st, struct mdinfo *info, mdp_super_t *sb0 ) | |||
{ | { | |||
/* Create a v1.0 superblock based on 'info'*/ | /* Create a v1.0 superblock based on 'info'*/ | |||
void *ret; | void *ret; | |||
struct mdp_superblock_1 *sb; | struct mdp_superblock_1 *sb; | |||
int i; | int i; | |||
unsigned long long offset; | unsigned long long offset; | |||
End of changes. 38 change blocks. | ||||
27 lines changed or deleted | 126 lines changed or added |