X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=super1.c;h=636a286697bc00b12a1382277b15dd2c86f874e0;hb=5c4cc0c8205d367eb68d99dbd2dc0f93e538eb43;hp=b15a1c7a7854b313673bb09f60c72ad0a626012a;hpb=795bd44ed11aafbed2628ba21216c667371e79a5;p=thirdparty%2Fmdadm.git diff --git a/super1.c b/super1.c index b15a1c7a..636a2866 100644 --- a/super1.c +++ b/super1.c @@ -89,12 +89,12 @@ struct mdp_superblock_1 { /* 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 */ + __u8 bblog_shift; /* shift from sectors to block size for badblock list */ + __u16 bblog_size; /* number of sectors reserved for badblock list */ __u32 bblog_offset; /* sector offset from superblock to bblog, signed */ /* array state information - 64 bytes */ - __u64 utime; /* 40 bits second, 24 btes microseconds */ + __u64 utime; /* 40 bits second, 24 bits microseconds */ __u64 events; /* incremented when superblock updated */ __u64 resync_offset; /* data before this offset (from data_offset) known to be in sync */ __u32 sb_csum; /* checksum upto dev_roles[max_dev] */ @@ -121,6 +121,9 @@ struct misc_dev_info { __u64 device_size; }; +#define MULTIPLE_PPL_AREA_SIZE_SUPER1 (1024 * 1024) /* Size of the whole + * mutliple PPL area + */ /* feature_map bits */ #define MD_FEATURE_BITMAP_OFFSET 1 #define MD_FEATURE_RECOVERY_OFFSET 2 /* recovery_offset is present and @@ -140,6 +143,7 @@ struct misc_dev_info { #define MD_FEATURE_BITMAP_VERSIONED 256 /* bitmap version number checked properly */ #define MD_FEATURE_JOURNAL 512 /* support write journal */ #define MD_FEATURE_PPL 1024 /* support PPL */ +#define MD_FEATURE_MUTLIPLE_PPLS 2048 /* support for multiple PPLs */ #define MD_FEATURE_ALL (MD_FEATURE_BITMAP_OFFSET \ |MD_FEATURE_RECOVERY_OFFSET \ |MD_FEATURE_RESHAPE_ACTIVE \ @@ -150,6 +154,7 @@ struct misc_dev_info { |MD_FEATURE_BITMAP_VERSIONED \ |MD_FEATURE_JOURNAL \ |MD_FEATURE_PPL \ + |MD_FEATURE_MULTIPLE_PPLS \ ) static int role_from_sb(struct mdp_superblock_1 *sb) @@ -298,6 +303,12 @@ static int awrite(struct align_fd *afd, void *buf, int len) return len; } +static inline unsigned int md_feature_any_ppl_on(__u32 feature_map) +{ + return ((__cpu_to_le32(feature_map) & + (MD_FEATURE_PPL | MD_FEATURE_MUTLIPLE_PPLS))); +} + static inline unsigned int choose_ppl_space(int chunk) { return (PPL_HEADER_SIZE >> 9) + (chunk > 128*2 ? chunk : 128*2); @@ -409,7 +420,7 @@ static void examine_super1(struct supertype *st, char *homehost) if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) { printf("Internal Bitmap : %ld sectors from superblock\n", (long)(int32_t)__le32_to_cpu(sb->bitmap_offset)); - } else if (sb->feature_map & __cpu_to_le32(MD_FEATURE_PPL)) { + } else if (md_feature_any_ppl_on(sb->feature_map)) { printf(" PPL : %u sectors at offset %d sectors from superblock\n", __le16_to_cpu(sb->ppl.size), __le16_to_cpu(sb->ppl.offset)); @@ -977,15 +988,15 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) info->array.chunk_size = __le32_to_cpu(sb->chunksize)*512; info->array.state = (__le64_to_cpu(sb->resync_offset) == MaxSector) ? 1 : 0; - if (__le32_to_cpu(bsb->nodes) > 1) - info->array.state |= (1 << MD_SB_CLUSTERED); super_offset = __le64_to_cpu(sb->super_offset); info->data_offset = __le64_to_cpu(sb->data_offset); info->component_size = __le64_to_cpu(sb->size); if (sb->feature_map & __le32_to_cpu(MD_FEATURE_BITMAP_OFFSET)) { info->bitmap_offset = (int32_t)__le32_to_cpu(sb->bitmap_offset); - } else if (sb->feature_map & __le32_to_cpu(MD_FEATURE_PPL)) { + if (__le32_to_cpu(bsb->nodes) > 1) + info->array.state |= (1 << MD_SB_CLUSTERED); + } else if (md_feature_any_ppl_on(sb->feature_map)) { info->ppl_offset = __le16_to_cpu(sb->ppl.offset); info->ppl_size = __le16_to_cpu(sb->ppl.size); info->ppl_sector = super_offset + info->ppl_offset; @@ -1140,7 +1151,7 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map) if (sb->feature_map & __le32_to_cpu(MD_FEATURE_JOURNAL)) { info->journal_device_required = 1; info->consistency_policy = CONSISTENCY_POLICY_JOURNAL; - } else if (sb->feature_map & __le32_to_cpu(MD_FEATURE_PPL)) { + } else if (md_feature_any_ppl_on(sb->feature_map)) { info->consistency_policy = CONSISTENCY_POLICY_PPL; } else if (sb->feature_map & __le32_to_cpu(MD_FEATURE_BITMAP_OFFSET)) { info->consistency_policy = CONSISTENCY_POLICY_BITMAP; @@ -1174,20 +1185,9 @@ static int update_super1(struct supertype *st, struct mdinfo *info, * ignored. */ int rv = 0; - int lockid; struct mdp_superblock_1 *sb = st->sb; bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); - if (bms->version == BITMAP_MAJOR_CLUSTERED && dlm_funs_ready()) { - rv = cluster_get_dlmlock(&lockid); - if (rv) { - pr_err("Cannot get dlmlock in %s return %d\n", - __func__, rv); - cluster_release_dlmlock(lockid); - return rv; - } - } - if (strcmp(update, "homehost") == 0 && homehost) { /* Note that 'homehost' is special as it is really @@ -1324,7 +1324,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info, if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) { bitmap_offset = (long)__le32_to_cpu(sb->bitmap_offset); bm_sectors = calc_bitmap_size(bms, 4096) >> 9; - } else if (sb->feature_map & __cpu_to_le32(MD_FEATURE_PPL)) { + } else if (md_feature_any_ppl_on(sb->feature_map)) { bitmap_offset = (long)__le16_to_cpu(sb->ppl.offset); bm_sectors = (long)__le16_to_cpu(sb->ppl.size); } @@ -1377,7 +1377,6 @@ static int update_super1(struct supertype *st, struct mdinfo *info, unsigned long long data_size = __le64_to_cpu(sb->data_size); long bb_offset = __le32_to_cpu(sb->bblog_offset); int space; - int optimal_space; int offset; if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) { @@ -1408,18 +1407,23 @@ static int update_super1(struct supertype *st, struct mdinfo *info, return -2; } - optimal_space = choose_ppl_space(__le32_to_cpu(sb->chunksize)); - - if (space > optimal_space) - space = optimal_space; - if (space > UINT16_MAX) - space = UINT16_MAX; + if (space >= (MULTIPLE_PPL_AREA_SIZE_SUPER1 >> 9)) { + space = (MULTIPLE_PPL_AREA_SIZE_SUPER1 >> 9); + } else { + int optimal_space = choose_ppl_space( + __le32_to_cpu(sb->chunksize)); + if (space > optimal_space) + space = optimal_space; + if (space > UINT16_MAX) + space = UINT16_MAX; + } sb->ppl.offset = __cpu_to_le16(offset); sb->ppl.size = __cpu_to_le16(space); sb->feature_map |= __cpu_to_le32(MD_FEATURE_PPL); } else if (strcmp(update, "no-ppl") == 0) { - sb->feature_map &= ~ __cpu_to_le32(MD_FEATURE_PPL); + sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_PPL | + MD_FEATURE_MUTLIPLE_PPLS); } else if (strcmp(update, "name") == 0) { if (info->name[0] == 0) sprintf(info->name, "%d", info->array.md_minor); @@ -1430,8 +1434,15 @@ static int update_super1(struct supertype *st, struct mdinfo *info, strcpy(sb->set_name, homehost); strcat(sb->set_name, ":"); strcat(sb->set_name, info->name); - } else - strncpy(sb->set_name, info->name, sizeof(sb->set_name)); + } else { + int namelen; + + namelen = min((int)strlen(info->name), + (int)sizeof(sb->set_name) - 1); + memcpy(sb->set_name, info->name, namelen); + memset(&sb->set_name[namelen], '\0', + sizeof(sb->set_name) - namelen); + } } else if (strcmp(update, "devicesize") == 0 && __le64_to_cpu(sb->super_offset) < __le64_to_cpu(sb->data_offset)) { @@ -1536,8 +1547,6 @@ static int update_super1(struct supertype *st, struct mdinfo *info, rv = -1; sb->sb_csum = calc_sb_1_csum(sb); - if (bms->version == BITMAP_MAJOR_CLUSTERED && dlm_funs_ready()) - cluster_release_dlmlock(lockid); return rv; } @@ -1590,8 +1599,15 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info, strcpy(sb->set_name, homehost); strcat(sb->set_name, ":"); strcat(sb->set_name, name); - } else - strncpy(sb->set_name, name, sizeof(sb->set_name)); + } else { + int namelen; + + namelen = min((int)strlen(name), + (int)sizeof(sb->set_name) - 1); + memcpy(sb->set_name, name, namelen); + memset(&sb->set_name[namelen], '\0', + sizeof(sb->set_name) - namelen); + } sb->ctime = __cpu_to_le64((unsigned long long)time(0)); sb->level = __cpu_to_le32(info->level); @@ -1641,20 +1657,8 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk, struct mdp_superblock_1 *sb = st->sb; __u16 *rp = sb->dev_roles + dk->number; struct devinfo *di, **dip; - bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); - int rv, lockid; int dk_state; - if (bms->version == BITMAP_MAJOR_CLUSTERED && dlm_funs_ready()) { - rv = cluster_get_dlmlock(&lockid); - if (rv) { - pr_err("Cannot get dlmlock in %s return %d\n", - __func__, rv); - cluster_release_dlmlock(lockid); - return rv; - } - } - dk_state = dk->state & ~(1<next = NULL; *dip = di; - if (bms->version == BITMAP_MAJOR_CLUSTERED && dlm_funs_ready()) - cluster_release_dlmlock(lockid); - return 0; } @@ -1701,18 +1702,6 @@ static int store_super1(struct supertype *st, int fd) struct align_fd afd; int sbsize; unsigned long long dsize; - bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MAX_SB_SIZE); - int rv, lockid; - - if (bms->version == BITMAP_MAJOR_CLUSTERED && dlm_funs_ready()) { - rv = cluster_get_dlmlock(&lockid); - if (rv) { - pr_err("Cannot get dlmlock in %s return %d\n", - __func__, rv); - cluster_release_dlmlock(lockid); - return rv; - } - } if (!get_dev_size(fd, NULL, &dsize)) return 1; @@ -1773,8 +1762,6 @@ static int store_super1(struct supertype *st, int fd) } } fsync(fd); - if (bms->version == BITMAP_MAJOR_CLUSTERED && dlm_funs_ready()) - cluster_release_dlmlock(lockid); return 0; } @@ -1808,6 +1795,11 @@ static int write_init_ppl1(struct supertype *st, struct mdinfo *info, int fd) struct ppl_header *ppl_hdr; int ret; + /* first clear entire ppl space */ + ret = zero_disk_range(fd, info->ppl_sector, info->ppl_size); + if (ret) + return ret; + ret = posix_memalign(&buf, 4096, PPL_HEADER_SIZE); if (ret) { pr_err("Failed to allocate PPL header buffer\n"); @@ -1974,20 +1966,12 @@ static int write_init_super1(struct supertype *st) (((char *)sb) + MAX_SB_SIZE); bm_space = calc_bitmap_size(bms, 4096) >> 9; bm_offset = (long)__le32_to_cpu(sb->bitmap_offset); - } else if (sb->feature_map & __cpu_to_le32(MD_FEATURE_PPL)) { - bm_space = - choose_ppl_space(__le32_to_cpu(sb->chunksize)); - if (bm_space > UINT16_MAX) - bm_space = UINT16_MAX; - if (st->minor_version == 0) { + } else if (md_feature_any_ppl_on(sb->feature_map)) { + bm_space = MULTIPLE_PPL_AREA_SIZE_SUPER1 >> 9; + if (st->minor_version == 0) bm_offset = -bm_space - 8; - if (bm_offset < INT16_MIN) { - bm_offset = INT16_MIN; - bm_space = -bm_offset - 8; - } - } else { + else bm_offset = 8; - } sb->ppl.offset = __cpu_to_le16(bm_offset); sb->ppl.size = __cpu_to_le16(bm_space); } else { @@ -2069,7 +2053,7 @@ static int write_init_super1(struct supertype *st) MD_FEATURE_BITMAP_OFFSET)) { rv = st->ss->write_bitmap(st, di->fd, NodeNumUpdate); } else if (rv == 0 && - (__le32_to_cpu(sb->feature_map) & MD_FEATURE_PPL)) { + md_feature_any_ppl_on(sb->feature_map)) { struct mdinfo info; st->ss->getinfo_super(st, &info, NULL); @@ -2345,7 +2329,7 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize, struct bitmap_super_s *bsb; bsb = (struct bitmap_super_s *)(((char*)super)+MAX_SB_SIZE); bmspace = calc_bitmap_size(bsb, 4096) >> 9; - } else if (__le32_to_cpu(super->feature_map) & MD_FEATURE_PPL) { + } else if (md_feature_any_ppl_on(super->feature_map)) { bmspace = __le16_to_cpu(super->ppl.size); } @@ -2396,7 +2380,7 @@ add_internal_bitmap1(struct supertype *st, /* * If not may_change, then this is a 'Grow' without sysfs support for * bitmaps, and the bitmap must fit after the superblock at 1K offset. - * If may_change, then this is create or a Grow with sysfs syupport, + * If may_change, then this is create or a Grow with sysfs support, * and we can put the bitmap wherever we like. * * size is in sectors, chunk is in bytes !!! @@ -2769,8 +2753,10 @@ static int validate_geometry1(struct supertype *st, int level, } /* creating: allow suitable space for bitmap or PPL */ - bmspace = consistency_policy == CONSISTENCY_POLICY_PPL ? - choose_ppl_space((*chunk)*2) : choose_bm_space(devsize); + if (consistency_policy == CONSISTENCY_POLICY_PPL) + bmspace = MULTIPLE_PPL_AREA_SIZE_SUPER1 >> 9; + else + bmspace = choose_bm_space(devsize); if (data_offset == INVALID_SECTORS) data_offset = st->data_offset;