From f727829c300f5fd56306e5ed5708a55d28fe228e Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 27 Jul 2011 14:08:10 +1000 Subject: Bad block log --- super1.c | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/super1.c b/super1.c index 09be351..f911593 100644 --- a/super1.c +++ b/super1.c @@ -70,7 +70,12 @@ struct mdp_superblock_1 { __u8 device_uuid[16]; /* user-space setable, ignored by kernel */ __u8 devflags; /* per-device flags. Only one defined...*/ #define WriteMostly1 1 /* mask for writemostly flag in above */ - __u8 pad2[64-57]; /* set to 0 when writing */ + /* bad block log. If there are any bad blocks the feature flag is set. + * if offset and size are non-zero, that space is reserved and available. + */ + __u8 bblog_shift; /* shift from sectors to block size for badblocklist */ + __u16 bblog_size; /* number of sectors reserved for badblocklist */ + __u32 bblog_offset; /* sector offset from superblock to bblog, signed */ /* array state information - 64 bytes */ __u64 utime; /* 40 bits second, 24 btes microseconds */ @@ -99,8 +104,9 @@ struct misc_dev_info { * must be honoured */ #define MD_FEATURE_RESHAPE_ACTIVE 4 +#define MD_FEATURE_BAD_BLOCKS 8 /* badblock list is not empty */ -#define MD_FEATURE_ALL (1|2|4) +#define MD_FEATURE_ALL (1|2|4|8) #ifndef offsetof #define offsetof(t,f) ((size_t)&(((t*)0)->f)) @@ -278,7 +284,7 @@ static void examine_super1(struct supertype *st, char *homehost) printf("Internal Bitmap : %ld sectors from superblock\n", (long)(int32_t)__le32_to_cpu(sb->bitmap_offset)); } - if (sb->feature_map & __le32_to_cpu(MD_FEATURE_RESHAPE_ACTIVE)) { + if (sb->feature_map & __cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE)) { printf(" Reshape pos'n : %llu%s\n", (unsigned long long)__le64_to_cpu(sb->reshape_position)/2, human_size(__le64_to_cpu(sb->reshape_position)<<9)); if (__le32_to_cpu(sb->delta_disks)) { @@ -322,6 +328,17 @@ static void examine_super1(struct supertype *st, char *homehost) atime = __le64_to_cpu(sb->utime) & 0xFFFFFFFFFFULL; printf(" Update Time : %.24s\n", ctime(&atime)); + if (sb->bblog_size && sb->bblog_offset) { + printf(" Bad Block Log : %d entries available at offset %ld sectors", + __le16_to_cpu(sb->bblog_size)*512/8, + (long)__le32_to_cpu(sb->bblog_offset)); + if (sb->feature_map & + __cpu_to_le32(MD_FEATURE_BAD_BLOCKS)) + printf(" - bad blocks present."); + printf("\n"); + } + + if (calc_sb_1_csum(sb) == sb->sb_csum) printf(" Checksum : %x - correct\n", __le32_to_cpu(sb->sb_csum)); else @@ -1105,10 +1122,12 @@ static int write_init_super1(struct supertype *st) * 2: 4K from start of device. * Depending on the array size, we might leave extra space * for a bitmap. + * Also leave 4K for bad-block log. */ array_size = __le64_to_cpu(sb->size); - /* work out how much space we left for a bitmap */ - bm_space = choose_bm_space(array_size); + /* work out how much space we left for a bitmap, + * Add 8 sectors for bad block log */ + bm_space = choose_bm_space(array_size) + 8; switch(st->minor_version) { case 0: @@ -1120,6 +1139,10 @@ static int write_init_super1(struct supertype *st) if (sb_offset < array_size + bm_space) bm_space = sb_offset - array_size; sb->data_size = __cpu_to_le64(sb_offset - bm_space); + if (bm_space >= 8) { + sb->bblog_size = __cpu_to_le16(8); + sb->bblog_offset = __cpu_to_le32((unsigned)-8); + } break; case 1: sb->super_offset = __cpu_to_le64(0); @@ -1134,6 +1157,10 @@ static int write_init_super1(struct supertype *st) sb->data_offset = __cpu_to_le64(reserved); sb->data_size = __cpu_to_le64(dsize - reserved); + if (reserved >= 16) { + sb->bblog_size = __cpu_to_le16(8); + sb->bblog_offset = __cpu_to_le32(reserved-8); + } break; case 2: sb_offset = 4*2; @@ -1154,6 +1181,10 @@ static int write_init_super1(struct supertype *st) sb->data_offset = __cpu_to_le64(reserved); sb->data_size = __cpu_to_le64(dsize - reserved); + if (reserved >= 16+16) { + sb->bblog_size = __cpu_to_le16(8); + sb->bblog_offset = __cpu_to_le32(reserved-8-8); + } break; default: return -EINVAL; -- cgit v1.2.1