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:
parent
07576f7e51
commit
920a1d2229
@ -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++;
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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")
|
||||||
|
@ -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
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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,\
|
||||||
|
Loading…
Reference in New Issue
Block a user