summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2020-06-30 12:52:27 -0500
committerDavid Teigland <teigland@redhat.com>2020-06-30 16:43:05 -0500
commitad773511c59aea239592c014a2dab4161ed92214 (patch)
tree661d9c7b63f52bf901db1fb31c4851cccc008ffc
parent3f32f9811e01c8953d201c7c9b563561ad856130 (diff)
downloadlvm2-ad773511c59aea239592c014a2dab4161ed92214.tar.gz
integrity: add initial size to metadata size
The metadata device size needs to include space for the dm-integrity "initial_sectors" which hold journals.
-rw-r--r--lib/metadata/integrity_manip.c28
-rw-r--r--test/shell/integrity-large.sh20
2 files changed, 38 insertions, 10 deletions
diff --git a/lib/metadata/integrity_manip.c b/lib/metadata/integrity_manip.c
index b622743f0..3322a2101 100644
--- a/lib/metadata/integrity_manip.c
+++ b/lib/metadata/integrity_manip.c
@@ -28,6 +28,7 @@
#define DEFAULT_BLOCK_SIZE 512
#define ONE_MB_IN_BYTES 1048576
+#define ONE_GB_IN_BYTES 1073741824
int lv_is_integrity_origin(const struct logical_volume *lv)
{
@@ -45,10 +46,35 @@ int lv_is_integrity_origin(const struct logical_volume *lv)
/*
* Every 500M of data needs 4M of metadata.
* (From trial and error testing.)
+ *
+ * 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)
{
- return ((lv_size_bytes / (500 * ONE_MB_IN_BYTES)) + 1) * (4 * ONE_MB_IN_BYTES);
+ uint64_t meta_bytes;
+ uint64_t initial_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);
+
+ /*
+ * initial space used for journals
+ * lv_size <= 512M -> 4M
+ * lv_size <= 1G -> 8M
+ * lv_size <= 4G -> 32M
+ * lv_size > 4G -> 64M
+ */
+ if (lv_size_bytes <= (512 * ONE_MB_IN_BYTES))
+ initial_bytes = 4 * ONE_MB_IN_BYTES;
+ else if (lv_size_bytes <= ONE_GB_IN_BYTES)
+ initial_bytes = 8 * ONE_MB_IN_BYTES;
+ else if (lv_size_bytes <= (4ULL * ONE_GB_IN_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;
+
+ return meta_bytes + initial_bytes;
}
/*
diff --git a/test/shell/integrity-large.sh b/test/shell/integrity-large.sh
index 1df9e6b53..06b0e03db 100644
--- a/test/shell/integrity-large.sh
+++ b/test/shell/integrity-large.sh
@@ -23,7 +23,7 @@ mnt="mnt"
mkdir -p $mnt
# raid1 LV needs to be extended to 512MB to test imeta being exended
-aux prepare_devs 4 600
+aux prepare_devs 4 632
printf "%0.sA" {1..16384} >> fileA
printf "%0.sB" {1..16384} >> fileB
@@ -131,8 +131,8 @@ _verify_data_on_lv
_wait_recalc $vg/${lv1}_rimage_0
_wait_recalc $vg/${lv1}_rimage_1
lvs -a -o+devices $vg
-check lv_field $vg/${lv1}_rimage_0_imeta size "8.00m"
-check lv_field $vg/${lv1}_rimage_1_imeta size "8.00m"
+check lv_field $vg/${lv1}_rimage_0_imeta size "12.00m"
+check lv_field $vg/${lv1}_rimage_1_imeta size "12.00m"
# provide space to extend the images onto new devs
vgextend $vg "$dev3" "$dev4"
@@ -153,33 +153,35 @@ lvconvert --raidintegrity y $vg/$lv1
_wait_recalc $vg/${lv1}_rimage_0
_wait_recalc $vg/${lv1}_rimage_1
lvs -a -o+devices $vg
-check lv_field $vg/${lv1}_rimage_0_imeta size "12.00m"
-check lv_field $vg/${lv1}_rimage_1_imeta size "12.00m"
+check lv_field $vg/${lv1}_rimage_0_imeta size "20.00m"
+check lv_field $vg/${lv1}_rimage_1_imeta size "20.00m"
lvchange -an $vg/$lv1
lvremove $vg/$lv1
# this succeeds because dev1,dev2 can hold rmeta+rimage
lvcreate --type raid1 -n $lv1 -L 592M -an $vg "$dev1" "$dev2"
+lvs -a -o+devices $vg
+lvchange -an $vg/$lv1
+lvremove $vg/$lv1
# this fails because dev1,dev2 can hold rmeta+rimage, but not imeta
# and we require imeta to be on same devs as rmeta/rimeta
-not lvcreate --type raid1 --raidintegrity y -n $lv1 -L 592M -an $vg "$dev1" "$dev2"
+not lvcreate --type raid1 --raidintegrity y -n $lv1 -L 624M -an $vg "$dev1" "$dev2"
lvs -a -o+devices $vg
-lvremove $vg/$lv1
# this can allocate from more devs so there's enough space for imeta to
# be allocated in the vg, but lvcreate fails because rmeta+rimage are
# allocated from dev1,dev2, we restrict imeta to being allocated on the
# same devs as rmeta/rimage, and dev1,dev2 can't fit imeta.
-not lvcreate --type raid1 --raidintegrity y -n $lv1 -L 592M -an $vg
+not lvcreate --type raid1 --raidintegrity y -n $lv1 -L 624M -an $vg
lvs -a -o+devices $vg
# counterintuitively, increasing the size will allow lvcreate to succeed
# because rmeta+rimage are pushed to being allocated on dev1,dev2,dev3,dev4
# which means imeta is now free to be allocated from dev3,dev4 which have
# plenty of space
-lvcreate --type raid1 --raidintegrity y -n $lv1 -L 600M -an $vg
+lvcreate --type raid1 --raidintegrity y -n $lv1 -L 640M -an $vg
lvs -a -o+devices $vg
vgremove -ff $vg