mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
thin: support non power of 2 chunk size
Support thin chunk size with multiple of 64KiB if user has thin-pool target version at least 1.2.
This commit is contained in:
parent
b296e30f98
commit
ca09c9ab4c
@ -1,5 +1,6 @@
|
||||
Version 2.02.98 -
|
||||
=================================
|
||||
Allow non power of 2 thin chunk sizes if thin pool driver supports that.
|
||||
Allow limited metadata changes when PVs are missing via [vg|lv]change.
|
||||
Do not start dmeventd for lvchange --resync when monitoring is off.
|
||||
Remove ExecStartPost with pvscan --cache from lvm2-lvmetad.service.
|
||||
|
@ -241,6 +241,13 @@ static int _thin_pool_add_target_line(struct dev_manager *dm,
|
||||
if (!_thin_target_present(cmd, seg, &attr))
|
||||
return_0;
|
||||
|
||||
if (!(attr & THIN_FEATURE_BLOCK_SIZE) &&
|
||||
(seg->chunk_size & (seg->chunk_size - 1))) {
|
||||
log_error("Thin pool target does not support %uKiB chunk size "
|
||||
"(needs kernel >= 3.5).", seg->chunk_size / 2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!laopts->real_pool) {
|
||||
if (!(pool_dlid = build_dm_uuid(mem, seg->lv->lvid.s, "tpool"))) {
|
||||
log_error("Failed to build uuid for thin pool LV %s.", seg->pool_lv->name);
|
||||
@ -551,13 +558,13 @@ static int _thin_target_present(struct cmd_context *cmd,
|
||||
else
|
||||
/* FIXME Log this as WARNING later only if the user asked for the feature to be used but it's not present */
|
||||
log_debug("Target " THIN_MODULE " does not support external origins.");
|
||||
#if 0
|
||||
if (maj >=1 && min >= 1)
|
||||
|
||||
if (maj >=1 && min >= 2)
|
||||
_attrs |= THIN_FEATURE_BLOCK_SIZE;
|
||||
else
|
||||
/* FIXME Log this as WARNING later only if the user asked for the feature to be used but it's not present */
|
||||
log_debug("Target " THIN_MODULE " does not support non power of 2 block sizes.");
|
||||
#endif
|
||||
|
||||
_checked = 1;
|
||||
}
|
||||
|
||||
|
@ -129,10 +129,13 @@ activate only on the local node.
|
||||
Gives the size of chunk for snapshot and thin pool logical volumes.
|
||||
For snapshots the value must be power of 2 between 4KiB and 512KiB
|
||||
and the default value is 4.
|
||||
For thin pools the value must be power of 2 between 64KiB and
|
||||
For thin pools the value must be between 64KiB and
|
||||
1048576KiB and the default value starts with 64 and scales
|
||||
up to fit the pool metadata size within 128MB,
|
||||
if the poolmetadata size is not specified.
|
||||
Older dm thin pool target version (<1.2) requires the value to be power of 2.
|
||||
The newer version requires to be the multiple of 64KiB, however discard is
|
||||
not supported for non power of 2 values.
|
||||
Default unit is in kilobytes.
|
||||
.TP
|
||||
.BR \-C ", " \-\-contiguous " {" \fIy | \fIn }
|
||||
|
@ -105,7 +105,13 @@ static int lvchange_pool_update(struct cmd_context *cmd,
|
||||
if (arg_count(cmd, discards_ARG)) {
|
||||
discards = (thin_discards_t) arg_uint_value(cmd, discards_ARG, THIN_DISCARDS_IGNORE);
|
||||
if (discards != first_seg(lv)->discards) {
|
||||
if (((discards == THIN_DISCARDS_IGNORE) ||
|
||||
if ((discards != THIN_DISCARDS_IGNORE) &&
|
||||
(first_seg(lv)->chunk_size &
|
||||
(first_seg(lv)->chunk_size - 1)))
|
||||
log_error("Cannot change discards state for "
|
||||
"logical volume \"%s\" "
|
||||
"with non power of 2 chunk size.", lv->name);
|
||||
else if (((discards == THIN_DISCARDS_IGNORE) ||
|
||||
(first_seg(lv)->discards == THIN_DISCARDS_IGNORE)) &&
|
||||
lv_is_active(lv))
|
||||
log_error("Cannot change discards state for active "
|
||||
|
@ -684,6 +684,7 @@ static int _lvcreate_params(struct lvcreate_params *lp,
|
||||
struct arg_value_group_list *current_group;
|
||||
const char *segtype_str;
|
||||
const char *tag;
|
||||
unsigned attr = 0;
|
||||
|
||||
memset(lp, 0, sizeof(*lp));
|
||||
memset(lcp, 0, sizeof(*lcp));
|
||||
@ -799,7 +800,7 @@ static int _lvcreate_params(struct lvcreate_params *lp,
|
||||
}
|
||||
|
||||
if (activation() && lp->segtype->ops->target_present &&
|
||||
!lp->segtype->ops->target_present(cmd, NULL, NULL)) {
|
||||
!lp->segtype->ops->target_present(cmd, NULL, &attr)) {
|
||||
log_error("%s: Required device-mapper target(s) not "
|
||||
"detected in your kernel", lp->segtype->name);
|
||||
return 0;
|
||||
@ -851,14 +852,25 @@ static int _lvcreate_params(struct lvcreate_params *lp,
|
||||
lp->chunk_size = arg_uint_value(cmd, chunksize_ARG,
|
||||
DM_THIN_MIN_DATA_BLOCK_SIZE);
|
||||
if ((lp->chunk_size < DM_THIN_MIN_DATA_BLOCK_SIZE) ||
|
||||
(lp->chunk_size > DM_THIN_MAX_DATA_BLOCK_SIZE) ||
|
||||
(lp->chunk_size & (lp->chunk_size - 1))) {
|
||||
log_error("Chunk size must be a power of 2 in the "
|
||||
"range %uK to %uK",
|
||||
(lp->chunk_size > DM_THIN_MAX_DATA_BLOCK_SIZE)) {
|
||||
log_error("Chunk size must be in the range %uK to %uK",
|
||||
(DM_THIN_MIN_DATA_BLOCK_SIZE / 2),
|
||||
(DM_THIN_MAX_DATA_BLOCK_SIZE / 2));
|
||||
return 0;
|
||||
}
|
||||
if (!(attr & THIN_FEATURE_BLOCK_SIZE) &&
|
||||
(lp->chunk_size & (lp->chunk_size - 1))) {
|
||||
log_error("Chunk size must be a power of 2 for this thin target version.");
|
||||
return 0;
|
||||
} else if (lp->chunk_size & (DM_THIN_MIN_DATA_BLOCK_SIZE - 1)) {
|
||||
log_error("Chunk size must be multiple of %uK.",
|
||||
DM_THIN_MIN_DATA_BLOCK_SIZE / 2);
|
||||
return 0;
|
||||
} else if ((lp->discards != THIN_DISCARDS_IGNORE) &&
|
||||
(lp->chunk_size & (lp->chunk_size - 1))) {
|
||||
log_warn("WARNING: Using discards ignore for chunk size non power of 2.");
|
||||
lp->discards = THIN_DISCARDS_IGNORE;
|
||||
}
|
||||
}
|
||||
log_verbose("Setting chunksize to %u sectors.", lp->chunk_size);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user