mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
integrity: add new option raidintegrityjournalsize
to specify the integrity journal size
This commit is contained in:
parent
07576f7e51
commit
920a1d2229
@ -50,7 +50,8 @@ int lv_is_integrity_origin(const struct logical_volume *lv)
|
||||
* plus some initial space for journals.
|
||||
* (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 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. */
|
||||
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 <= 1G -> 8M
|
||||
* 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;
|
||||
else if (lv_size_bytes > (4ULL * ONE_GB_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;
|
||||
}
|
||||
|
||||
@ -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,
|
||||
struct volume_group *vg,
|
||||
struct lvcreate_params *lp,
|
||||
struct integrity_settings *settings,
|
||||
struct logical_volume **meta_lv)
|
||||
{
|
||||
char metaname[NAME_LEN] = { 0 };
|
||||
@ -115,7 +128,7 @@ static int _lv_create_integrity_metadata(struct cmd_context *cmd,
|
||||
lp_meta.pvh = lp->pvh;
|
||||
|
||||
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;
|
||||
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;
|
||||
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_extents = meta_sectors / vg->extent_size;
|
||||
|
||||
prev_meta_sectors = lv_imeta->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) {
|
||||
log_debug("extend not needed for imeta LV %s", lv_imeta->name);
|
||||
continue;
|
||||
@ -322,6 +340,18 @@ int integrity_mode_set(const char *mode, struct integrity_settings *settings)
|
||||
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,
|
||||
struct integrity_settings *settings,
|
||||
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.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;
|
||||
|
||||
revert_meta_lvs++;
|
||||
|
@ -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_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_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_raid_integrity_total_mismatches(struct cmd_context *cmd, const struct logical_volume *lv, uint64_t *mismatches);
|
||||
|
||||
|
@ -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"
|
||||
"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,
|
||||
"Prevent the command from making changes, including activation and\n"
|
||||
"metadata updates.\n")
|
||||
|
@ -843,7 +843,7 @@ FLAGS: SECONDARY_SYNTAX
|
||||
---
|
||||
|
||||
lvconvert --raidintegrity Bool LV_raid
|
||||
OO: --raidintegritymode String, --raidintegrityblocksize Number, OO_LVCONVERT
|
||||
OO: --raidintegritymode String, --raidintegrityblocksize Number, --raidintegrityjournalsize SizeMB, OO_LVCONVERT
|
||||
OP: PV ...
|
||||
ID: lvconvert_integrity
|
||||
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_RAID: --regionsize RegionSize, --minrecoveryrate SizeKB, --maxrecoveryrate SizeKB,
|
||||
--raidintegrity Bool, --raidintegritymode String, --raidintegrityblocksize Number
|
||||
--raidintegrity Bool, --raidintegritymode String, --raidintegrityblocksize Number, --raidintegrityjournalsize SizeMB
|
||||
|
||||
---
|
||||
|
||||
|
@ -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))
|
||||
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))
|
||||
settings.block_size = arg_int_value(cmd, raidintegrityblocksize_ARG, 0);
|
||||
|
||||
|
@ -609,12 +609,20 @@ static int _read_raid_params(struct cmd_context *cmd,
|
||||
|
||||
if (arg_int_value(cmd, raidintegrity_ARG, 0)) {
|
||||
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))
|
||||
lp->integrity_settings.block_size = arg_int_value(cmd, raidintegrityblocksize_ARG, 0);
|
||||
if (arg_is_set(cmd, raidintegritymode_ARG)) {
|
||||
if (!integrity_mode_set(arg_str_value(cmd, raidintegritymode_ARG, NULL), &lp->integrity_settings))
|
||||
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;
|
||||
@ -936,7 +944,8 @@ static int _lvcreate_params(struct cmd_context *cmd,
|
||||
raidminrecoveryrate_ARG, \
|
||||
raidintegrity_ARG, \
|
||||
raidintegritymode_ARG, \
|
||||
raidintegrityblocksize_ARG
|
||||
raidintegrityblocksize_ARG, \
|
||||
raidintegrityjournalsize_ARG
|
||||
|
||||
#define SIZE_ARGS \
|
||||
extents_ARG,\
|
||||
|
Loading…
Reference in New Issue
Block a user