diff options
author | Artur Paszkiewicz <artur.paszkiewicz@intel.com> | 2017-03-29 11:54:19 +0200 |
---|---|---|
committer | Jes Sorensen <Jes.Sorensen@gmail.com> | 2017-03-29 17:35:07 +0200 |
commit | e6e9dd3f1b255f9921ebc023c1e5b65601a637e2 (patch) | |
tree | 8d96ee140e10e64a77c72b27aafcb424e8aea11e /super1.c | |
parent | super1: PPL support (diff) | |
download | mdadm-e6e9dd3f1b255f9921ebc023c1e5b65601a637e2.tar.xz mdadm-e6e9dd3f1b255f9921ebc023c1e5b65601a637e2.zip |
Add 'ppl' and 'no-ppl' options for --update=
This can be used with --assemble for super1 and with --update-subarray
for imsm to enable or disable PPL in the metadata.
Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Signed-off-by: Jes Sorensen <Jes.Sorensen@gmail.com>
Diffstat (limited to 'super1.c')
-rw-r--r-- | super1.c | 49 |
1 files changed, 49 insertions, 0 deletions
@@ -1325,6 +1325,55 @@ static int update_super1(struct supertype *st, struct mdinfo *info, sb->bblog_size = 0; sb->bblog_shift = 0; sb->bblog_offset = 0; + } else if (strcmp(update, "ppl") == 0) { + 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_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)) { + pr_err("Cannot add PPL to array with bitmap\n"); + return -2; + } + + if (sb->feature_map & __cpu_to_le32(MD_FEATURE_JOURNAL)) { + pr_err("Cannot add PPL to array with journal\n"); + return -2; + } + + if (sb_offset < data_offset) { + if (bb_offset) + space = bb_offset - 8; + else + space = data_offset - sb_offset - 8; + offset = 8; + } else { + offset = -(sb_offset - data_offset - data_size); + if (offset < INT16_MIN) + offset = INT16_MIN; + space = -(offset - bb_offset); + } + + if (space < (PPL_HEADER_SIZE >> 9) + 8) { + pr_err("Not enough space to add ppl\n"); + 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; + + 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); } else if (strcmp(update, "name") == 0) { if (info->name[0] == 0) sprintf(info->name, "%d", info->array.md_minor); |