1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-22 17:35:59 +03:00

integrity: add new option raidintegrityjournalsize

to specify the integrity journal size
This commit is contained in:
David Teigland 2024-08-05 13:20:58 -05:00
parent 07576f7e51
commit 920a1d2229
6 changed files with 55 additions and 9 deletions

View File

@ -50,7 +50,8 @@ int lv_is_integrity_origin(const struct logical_volume *lv)
* plus some initial space for journals. * plus some initial space for journals.
* (again from trial and error testing.) * (again from trial and error testing.)
*/ */
static uint64_t _lv_size_bytes_to_integrity_meta_bytes(uint64_t lv_size_bytes) static uint64_t _lv_size_bytes_to_integrity_meta_bytes(uint64_t lv_size_bytes, uint32_t journal_sectors,
uint32_t extent_size)
{ {
uint64_t meta_bytes; uint64_t meta_bytes;
uint64_t initial_bytes; uint64_t initial_bytes;
@ -58,8 +59,16 @@ static uint64_t _lv_size_bytes_to_integrity_meta_bytes(uint64_t lv_size_bytes)
/* Every 500M of data needs 4M of metadata. */ /* Every 500M of data needs 4M of metadata. */
meta_bytes = ((lv_size_bytes / (500 * ONE_MB_IN_BYTES)) + 1) * (4 * ONE_MB_IN_BYTES); meta_bytes = ((lv_size_bytes / (500 * ONE_MB_IN_BYTES)) + 1) * (4 * ONE_MB_IN_BYTES);
if (journal_sectors) {
/* for calculating the metadata LV size for the specified
journal size, round the specified journal size up to the
nearest extent. extent_size is in sectors. */
initial_bytes = dm_round_up(journal_sectors, extent_size) * 512;
goto out;
}
/* /*
* initial space used for journals * initial space used for journals (when journal size is not specified):
* lv_size <= 512M -> 4M * lv_size <= 512M -> 4M
* lv_size <= 1G -> 8M * lv_size <= 1G -> 8M
* lv_size <= 4G -> 32M * lv_size <= 4G -> 32M
@ -73,7 +82,10 @@ static uint64_t _lv_size_bytes_to_integrity_meta_bytes(uint64_t lv_size_bytes)
initial_bytes = 32 * ONE_MB_IN_BYTES; initial_bytes = 32 * ONE_MB_IN_BYTES;
else if (lv_size_bytes > (4ULL * ONE_GB_IN_BYTES)) else if (lv_size_bytes > (4ULL * ONE_GB_IN_BYTES))
initial_bytes = 64 * ONE_MB_IN_BYTES; initial_bytes = 64 * ONE_MB_IN_BYTES;
out:
log_debug("integrity_meta_bytes %llu from lv_size_bytes %llu meta_bytes %llu initial_bytes %llu journal_sectors %u",
(unsigned long long)(meta_bytes+initial_bytes), (unsigned long long)lv_size_bytes,
(unsigned long long)meta_bytes, (unsigned long long)initial_bytes, journal_sectors);
return meta_bytes + initial_bytes; return meta_bytes + initial_bytes;
} }
@ -84,6 +96,7 @@ static uint64_t _lv_size_bytes_to_integrity_meta_bytes(uint64_t lv_size_bytes)
static int _lv_create_integrity_metadata(struct cmd_context *cmd, static int _lv_create_integrity_metadata(struct cmd_context *cmd,
struct volume_group *vg, struct volume_group *vg,
struct lvcreate_params *lp, struct lvcreate_params *lp,
struct integrity_settings *settings,
struct logical_volume **meta_lv) struct logical_volume **meta_lv)
{ {
char metaname[NAME_LEN] = { 0 }; char metaname[NAME_LEN] = { 0 };
@ -115,7 +128,7 @@ static int _lv_create_integrity_metadata(struct cmd_context *cmd,
lp_meta.pvh = lp->pvh; lp_meta.pvh = lp->pvh;
lv_size_bytes = (uint64_t)lp->extents * (uint64_t)vg->extent_size * 512; lv_size_bytes = (uint64_t)lp->extents * (uint64_t)vg->extent_size * 512;
meta_bytes = _lv_size_bytes_to_integrity_meta_bytes(lv_size_bytes); meta_bytes = _lv_size_bytes_to_integrity_meta_bytes(lv_size_bytes, settings->journal_sectors, vg->extent_size);
meta_sectors = meta_bytes / 512; meta_sectors = meta_bytes / 512;
lp_meta.extents = meta_sectors / vg->extent_size; lp_meta.extents = meta_sectors / vg->extent_size;
@ -181,13 +194,18 @@ int lv_extend_integrity_in_raid(struct logical_volume *lv, struct dm_list *pvh)
} }
lv_size_bytes = lv_iorig->size * 512; lv_size_bytes = lv_iorig->size * 512;
meta_bytes = _lv_size_bytes_to_integrity_meta_bytes(lv_size_bytes); meta_bytes = _lv_size_bytes_to_integrity_meta_bytes(lv_size_bytes, 0, 0);
meta_sectors = meta_bytes / 512; meta_sectors = meta_bytes / 512;
meta_extents = meta_sectors / vg->extent_size; meta_extents = meta_sectors / vg->extent_size;
prev_meta_sectors = lv_imeta->size; prev_meta_sectors = lv_imeta->size;
prev_meta_extents = prev_meta_sectors / vg->extent_size; prev_meta_extents = prev_meta_sectors / vg->extent_size;
/*
* FIXME: allow --raidintegrityjournalsize to be used with
* lvextend to override the default journal size calculation.
*/
if (meta_extents <= prev_meta_extents) { if (meta_extents <= prev_meta_extents) {
log_debug("extend not needed for imeta LV %s", lv_imeta->name); log_debug("extend not needed for imeta LV %s", lv_imeta->name);
continue; continue;
@ -322,6 +340,18 @@ int integrity_mode_set(const char *mode, struct integrity_settings *settings)
return 1; return 1;
} }
int integrity_journal_set(int num_sectors, struct integrity_settings *settings)
{
int size_mb = num_sectors / 2048;
if (size_mb < 4 || size_mb > 1024) {
log_error("Invalid raid integrity journal size %d MiB (use 4-1024 MiB).", size_mb);
return 0;
}
settings->journal_sectors = num_sectors;
settings->journal_sectors_set = 1;
return 1;
}
static int _set_integrity_block_size(struct cmd_context *cmd, struct logical_volume *lv, int is_active, static int _set_integrity_block_size(struct cmd_context *cmd, struct logical_volume *lv, int is_active,
struct integrity_settings *settings, struct integrity_settings *settings,
int lbs_4k, int lbs_512, int pbs_4k, int pbs_512) int lbs_4k, int lbs_512, int pbs_4k, int pbs_512)
@ -597,7 +627,7 @@ int lv_add_integrity_to_raid(struct logical_volume *lv, struct integrity_setting
lp.pvh = use_pvh; lp.pvh = use_pvh;
lp.extents = lv_image->size / vg->extent_size; lp.extents = lv_image->size / vg->extent_size;
if (!_lv_create_integrity_metadata(cmd, vg, &lp, &meta_lv)) if (!_lv_create_integrity_metadata(cmd, vg, &lp, settings, &meta_lv))
goto_bad; goto_bad;
revert_meta_lvs++; revert_meta_lvs++;

View File

@ -1508,6 +1508,7 @@ int lv_raid_has_integrity(struct logical_volume *lv);
int lv_extend_integrity_in_raid(struct logical_volume *lv, struct dm_list *pvh); int lv_extend_integrity_in_raid(struct logical_volume *lv, struct dm_list *pvh);
int lv_get_raid_integrity_settings(struct logical_volume *lv, struct integrity_settings **isettings); int lv_get_raid_integrity_settings(struct logical_volume *lv, struct integrity_settings **isettings);
int integrity_mode_set(const char *mode, struct integrity_settings *settings); int integrity_mode_set(const char *mode, struct integrity_settings *settings);
int integrity_journal_set(int size_mb, struct integrity_settings *settings);
int lv_integrity_mismatches(struct cmd_context *cmd, const struct logical_volume *lv, uint64_t *mismatches); int lv_integrity_mismatches(struct cmd_context *cmd, const struct logical_volume *lv, uint64_t *mismatches);
int lv_raid_integrity_total_mismatches(struct cmd_context *cmd, const struct logical_volume *lv, uint64_t *mismatches); int lv_raid_integrity_total_mismatches(struct cmd_context *cmd, const struct logical_volume *lv, uint64_t *mismatches);

View File

@ -670,6 +670,9 @@ arg(raidintegritymode_ARG, '\0', "raidintegritymode", string_VAL, 0, 0,
"bitmap mode can in theory achieve full write throughput of the device,\n" "bitmap mode can in theory achieve full write throughput of the device,\n"
"but would not benefit from the potential scattered write optimization.\n") "but would not benefit from the potential scattered write optimization.\n")
arg(raidintegrityjournalsize_ARG, '\0', "raidintegrityjournalsize", sizemb_VAL, 0, 0,
"The size of integrity journal.\n")
arg(readonly_ARG, '\0', "readonly", 0, 0, 0, arg(readonly_ARG, '\0', "readonly", 0, 0, 0,
"Prevent the command from making changes, including activation and\n" "Prevent the command from making changes, including activation and\n"
"metadata updates.\n") "metadata updates.\n")

View File

@ -843,7 +843,7 @@ FLAGS: SECONDARY_SYNTAX
--- ---
lvconvert --raidintegrity Bool LV_raid lvconvert --raidintegrity Bool LV_raid
OO: --raidintegritymode String, --raidintegrityblocksize Number, OO_LVCONVERT OO: --raidintegritymode String, --raidintegrityblocksize Number, --raidintegrityjournalsize SizeMB, OO_LVCONVERT
OP: PV ... OP: PV ...
ID: lvconvert_integrity ID: lvconvert_integrity
DESC: Add or remove data integrity checksums to raid images. DESC: Add or remove data integrity checksums to raid images.
@ -869,7 +869,7 @@ OO_LVCREATE_VDO: --compression Bool, --deduplication Bool, --vdosettings String
OO_LVCREATE_THINPOOL: --discards Discards, --errorwhenfull Bool, --pooldatavdo Bool, OO_LVCREATE_VDO, OO_LVCREATE_POOL OO_LVCREATE_THINPOOL: --discards Discards, --errorwhenfull Bool, --pooldatavdo Bool, OO_LVCREATE_VDO, OO_LVCREATE_POOL
OO_LVCREATE_RAID: --regionsize RegionSize, --minrecoveryrate SizeKB, --maxrecoveryrate SizeKB, OO_LVCREATE_RAID: --regionsize RegionSize, --minrecoveryrate SizeKB, --maxrecoveryrate SizeKB,
--raidintegrity Bool, --raidintegritymode String, --raidintegrityblocksize Number --raidintegrity Bool, --raidintegritymode String, --raidintegrityblocksize Number, --raidintegrityjournalsize SizeMB
--- ---

View File

@ -6522,6 +6522,9 @@ static int _lvconvert_integrity_single(struct cmd_context *cmd,
if (!integrity_mode_set(arg_str_value(cmd, raidintegritymode_ARG, NULL), &settings)) if (!integrity_mode_set(arg_str_value(cmd, raidintegritymode_ARG, NULL), &settings))
return_ECMD_FAILED; return_ECMD_FAILED;
if (!integrity_journal_set(arg_int_value(cmd, raidintegrityjournalsize_ARG, 0), &settings))
return_ECMD_FAILED;
if (arg_is_set(cmd, raidintegrityblocksize_ARG)) if (arg_is_set(cmd, raidintegrityblocksize_ARG))
settings.block_size = arg_int_value(cmd, raidintegrityblocksize_ARG, 0); settings.block_size = arg_int_value(cmd, raidintegrityblocksize_ARG, 0);

View File

@ -609,12 +609,20 @@ static int _read_raid_params(struct cmd_context *cmd,
if (arg_int_value(cmd, raidintegrity_ARG, 0)) { if (arg_int_value(cmd, raidintegrity_ARG, 0)) {
lp->raidintegrity = 1; lp->raidintegrity = 1;
log_debug("raid integrity enabled blocksize %d journalsize %d mode %s",
arg_int_value(cmd, raidintegrityblocksize_ARG, 0),
arg_int_value(cmd, raidintegrityjournalsize_ARG, 0),
arg_str_value(cmd, raidintegritymode_ARG, NULL) ?: "none");
if (arg_is_set(cmd, raidintegrityblocksize_ARG)) if (arg_is_set(cmd, raidintegrityblocksize_ARG))
lp->integrity_settings.block_size = arg_int_value(cmd, raidintegrityblocksize_ARG, 0); lp->integrity_settings.block_size = arg_int_value(cmd, raidintegrityblocksize_ARG, 0);
if (arg_is_set(cmd, raidintegritymode_ARG)) { if (arg_is_set(cmd, raidintegritymode_ARG)) {
if (!integrity_mode_set(arg_str_value(cmd, raidintegritymode_ARG, NULL), &lp->integrity_settings)) if (!integrity_mode_set(arg_str_value(cmd, raidintegritymode_ARG, NULL), &lp->integrity_settings))
return_0; return_0;
} }
if (arg_is_set(cmd, raidintegrityjournalsize_ARG)) {
if (!integrity_journal_set(arg_int_value(cmd, raidintegrityjournalsize_ARG, 0), &lp->integrity_settings))
return_0;
}
} }
return 1; return 1;
@ -936,7 +944,8 @@ static int _lvcreate_params(struct cmd_context *cmd,
raidminrecoveryrate_ARG, \ raidminrecoveryrate_ARG, \
raidintegrity_ARG, \ raidintegrity_ARG, \
raidintegritymode_ARG, \ raidintegritymode_ARG, \
raidintegrityblocksize_ARG raidintegrityblocksize_ARG, \
raidintegrityjournalsize_ARG
#define SIZE_ARGS \ #define SIZE_ARGS \
extents_ARG,\ extents_ARG,\