diff --git a/SOURCES/lvm2-2_02_186-Fix-rounding-writes-up-to-sector-size.patch b/SOURCES/lvm2-2_02_186-Fix-rounding-writes-up-to-sector-size.patch new file mode 100644 index 0000000..749ed5f --- /dev/null +++ b/SOURCES/lvm2-2_02_186-Fix-rounding-writes-up-to-sector-size.patch @@ -0,0 +1,306 @@ +From 748d1076bf2ab590eb8cff68dba88d78f1f67e9f Mon Sep 17 00:00:00 2001 +From: David Teigland +Date: Wed, 24 Jul 2019 11:32:13 -0500 +Subject: [PATCH 2/2] Fix rounding writes up to sector size + +Do this at two levels, although one would be enough to +fix the problem seen recently: + +- Ignore any reported sector size other than 512 of 4096. + If either sector size (physical or logical) is reported + as 512, then use 512. If neither are reported as 512, + and one or the other is reported as 4096, then use 4096. + If neither is reported as either 512 or 4096, then use 512. + +- When rounding up a limited write in bcache to be a multiple + of the sector size, check that the resulting write size is + not larger than the bcache block itself. (This shouldn't + happen if the sector size is 512 or 4096.) + +(cherry picked from commit 7550665ba49ac7d497d5b212e14b69298ef01361) + +Conflicts: + lib/label/label.c +--- + lib/device/bcache.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++-- + lib/device/dev-io.c | 52 +++++++++++++++++++++++++++++++ + lib/device/device.h | 8 +++-- + lib/label/label.c | 30 +++++++++++++++--- + 4 files changed, 171 insertions(+), 8 deletions(-) + +diff --git a/lib/device/bcache.c b/lib/device/bcache.c +index f64931f..423eeb7 100644 +--- a/lib/device/bcache.c ++++ b/lib/device/bcache.c +@@ -170,6 +170,7 @@ static bool _async_issue(struct io_engine *ioe, enum dir d, int fd, + sector_t offset; + sector_t nbytes; + sector_t limit_nbytes; ++ sector_t orig_nbytes; + sector_t extra_nbytes = 0; + + if (((uintptr_t) data) & e->page_mask) { +@@ -192,11 +193,41 @@ static bool _async_issue(struct io_engine *ioe, enum dir d, int fd, + return false; + } + ++ /* ++ * If the bcache block offset+len goes beyond where lvm is ++ * intending to write, then reduce the len being written ++ * (which is the bcache block size) so we don't write past ++ * the limit set by lvm. If after applying the limit, the ++ * resulting size is not a multiple of the sector size (512 ++ * or 4096) then extend the reduced size to be a multiple of ++ * the sector size (we don't want to write partial sectors.) ++ */ + if (offset + nbytes > _last_byte_offset) { + limit_nbytes = _last_byte_offset - offset; +- if (limit_nbytes % _last_byte_sector_size) ++ ++ if (limit_nbytes % _last_byte_sector_size) { + extra_nbytes = _last_byte_sector_size - (limit_nbytes % _last_byte_sector_size); + ++ /* ++ * adding extra_nbytes to the reduced nbytes (limit_nbytes) ++ * should make the final write size a multiple of the ++ * sector size. This should never result in a final size ++ * larger than the bcache block size (as long as the bcache ++ * block size is a multiple of the sector size). ++ */ ++ if (limit_nbytes + extra_nbytes > nbytes) { ++ log_warn("Skip extending write at %llu len %llu limit %llu extra %llu sector_size %llu", ++ (unsigned long long)offset, ++ (unsigned long long)nbytes, ++ (unsigned long long)limit_nbytes, ++ (unsigned long long)extra_nbytes, ++ (unsigned long long)_last_byte_sector_size); ++ extra_nbytes = 0; ++ } ++ } ++ ++ orig_nbytes = nbytes; ++ + if (extra_nbytes) { + log_debug("Limit write at %llu len %llu to len %llu rounded to %llu", + (unsigned long long)offset, +@@ -211,6 +242,22 @@ static bool _async_issue(struct io_engine *ioe, enum dir d, int fd, + (unsigned long long)limit_nbytes); + nbytes = limit_nbytes; + } ++ ++ /* ++ * This shouldn't happen, the reduced+extended ++ * nbytes value should never be larger than the ++ * bcache block size. ++ */ ++ if (nbytes > orig_nbytes) { ++ log_error("Invalid adjusted write at %llu len %llu adjusted %llu limit %llu extra %llu sector_size %llu", ++ (unsigned long long)offset, ++ (unsigned long long)orig_nbytes, ++ (unsigned long long)nbytes, ++ (unsigned long long)limit_nbytes, ++ (unsigned long long)extra_nbytes, ++ (unsigned long long)_last_byte_sector_size); ++ return false; ++ } + } + } + +@@ -405,6 +452,7 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd, + uint64_t nbytes = len; + sector_t limit_nbytes = 0; + sector_t extra_nbytes = 0; ++ sector_t orig_nbytes = 0; + + if (offset > _last_byte_offset) { + log_error("Limit write at %llu len %llu beyond last byte %llu", +@@ -417,9 +465,30 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd, + + if (offset + nbytes > _last_byte_offset) { + limit_nbytes = _last_byte_offset - offset; +- if (limit_nbytes % _last_byte_sector_size) ++ ++ if (limit_nbytes % _last_byte_sector_size) { + extra_nbytes = _last_byte_sector_size - (limit_nbytes % _last_byte_sector_size); + ++ /* ++ * adding extra_nbytes to the reduced nbytes (limit_nbytes) ++ * should make the final write size a multiple of the ++ * sector size. This should never result in a final size ++ * larger than the bcache block size (as long as the bcache ++ * block size is a multiple of the sector size). ++ */ ++ if (limit_nbytes + extra_nbytes > nbytes) { ++ log_warn("Skip extending write at %llu len %llu limit %llu extra %llu sector_size %llu", ++ (unsigned long long)offset, ++ (unsigned long long)nbytes, ++ (unsigned long long)limit_nbytes, ++ (unsigned long long)extra_nbytes, ++ (unsigned long long)_last_byte_sector_size); ++ extra_nbytes = 0; ++ } ++ } ++ ++ orig_nbytes = nbytes; ++ + if (extra_nbytes) { + log_debug("Limit write at %llu len %llu to len %llu rounded to %llu", + (unsigned long long)offset, +@@ -434,6 +503,22 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd, + (unsigned long long)limit_nbytes); + nbytes = limit_nbytes; + } ++ ++ /* ++ * This shouldn't happen, the reduced+extended ++ * nbytes value should never be larger than the ++ * bcache block size. ++ */ ++ if (nbytes > orig_nbytes) { ++ log_error("Invalid adjusted write at %llu len %llu adjusted %llu limit %llu extra %llu sector_size %llu", ++ (unsigned long long)offset, ++ (unsigned long long)orig_nbytes, ++ (unsigned long long)nbytes, ++ (unsigned long long)limit_nbytes, ++ (unsigned long long)extra_nbytes, ++ (unsigned long long)_last_byte_sector_size); ++ return false; ++ } + } + + where = offset; +diff --git a/lib/device/dev-io.c b/lib/device/dev-io.c +index 6996a44..90c54ce 100644 +--- a/lib/device/dev-io.c ++++ b/lib/device/dev-io.c +@@ -136,6 +136,58 @@ static int _io(struct device_area *where, char *buffer, int should_write, dev_io + return (total == (size_t) where->size); + } + ++int dev_get_direct_block_sizes(struct device *dev, unsigned int *physical_block_size, ++ unsigned int *logical_block_size) ++{ ++ int fd = dev->bcache_fd; ++ int do_close = 0; ++ unsigned int pbs = 0; ++ unsigned int lbs = 0; ++ ++ if (dev->physical_block_size || dev->logical_block_size) { ++ *physical_block_size = dev->physical_block_size; ++ *logical_block_size = dev->logical_block_size; ++ return 1; ++ } ++ ++ if (fd <= 0) { ++ if (!dev_open_readonly(dev)) ++ return 0; ++ fd = dev_fd(dev); ++ do_close = 1; ++ } ++ ++ /* ++ * BLKPBSZGET from kernel comment for blk_queue_physical_block_size: ++ * "the lowest possible sector size that the hardware can operate on ++ * without reverting to read-modify-write operations" ++ */ ++ if (ioctl(fd, BLKPBSZGET, &pbs)) { ++ stack; ++ pbs = 0; ++ } ++ ++ /* ++ * BLKSSZGET from kernel comment for blk_queue_logical_block_size: ++ * "the lowest possible block size that the storage device can address." ++ */ ++ if (ioctl(fd, BLKSSZGET, &lbs)) { ++ stack; ++ lbs = 0; ++ } ++ ++ dev->physical_block_size = pbs; ++ dev->logical_block_size = lbs; ++ ++ *physical_block_size = pbs; ++ *logical_block_size = lbs; ++ ++ if (do_close && !dev_close_immediate(dev)) ++ stack; ++ ++ return 1; ++} ++ + /*----------------------------------------------------------------- + * LVM2 uses O_DIRECT when performing metadata io, which requires + * block size aligned accesses. If any io is not aligned we have +diff --git a/lib/device/device.h b/lib/device/device.h +index bbd965a..aafc401 100644 +--- a/lib/device/device.h ++++ b/lib/device/device.h +@@ -67,8 +67,10 @@ struct device { + int open_count; + int error_count; + int max_error_count; +- int phys_block_size; +- int block_size; ++ int phys_block_size; /* From either BLKPBSZGET or BLKSSZGET, don't use */ ++ int block_size; /* From BLKBSZGET, returns bdev->bd_block_size, likely set by fs, probably don't use */ ++ int physical_block_size; /* From BLKPBSZGET: lowest possible sector size that the hardware can operate on without reverting to read-modify-write operations */ ++ int logical_block_size; /* From BLKSSZGET: lowest possible block size that the storage device can address */ + int read_ahead; + int bcache_fd; + uint32_t flags; +@@ -132,6 +134,8 @@ void dev_size_seqno_inc(void); + * All io should use these routines. + */ + int dev_get_block_size(struct device *dev, unsigned int *phys_block_size, unsigned int *block_size); ++int dev_get_direct_block_sizes(struct device *dev, unsigned int *physical_block_size, ++ unsigned int *logical_block_size); + int dev_get_size(struct device *dev, uint64_t *size); + int dev_get_read_ahead(struct device *dev, uint32_t *read_ahead); + int dev_discard_blocks(struct device *dev, uint64_t offset_bytes, uint64_t size_bytes); +diff --git a/lib/label/label.c b/lib/label/label.c +index 4f8e135..66fb564 100644 +--- a/lib/label/label.c ++++ b/lib/label/label.c +@@ -1492,12 +1492,34 @@ bool dev_set_bytes(struct device *dev, uint64_t start, size_t len, uint8_t val) + + void dev_set_last_byte(struct device *dev, uint64_t offset) + { +- unsigned int phys_block_size = 0; +- unsigned int block_size = 0; ++ unsigned int physical_block_size = 0; ++ unsigned int logical_block_size = 0; ++ unsigned int bs; + +- dev_get_block_size(dev, &phys_block_size, &block_size); ++ if (!dev_get_direct_block_sizes(dev, &physical_block_size, &logical_block_size)) { ++ stack; ++ return; /* FIXME: error path ? */ ++ } ++ ++ if ((physical_block_size == 512) && (logical_block_size == 512)) ++ bs = 512; ++ else if ((physical_block_size == 4096) && (logical_block_size == 4096)) ++ bs = 4096; ++ else if ((physical_block_size == 512) || (logical_block_size == 512)) { ++ log_debug("Set last byte mixed block sizes physical %u logical %u using 512", ++ physical_block_size, logical_block_size); ++ bs = 512; ++ } else if ((physical_block_size == 4096) || (logical_block_size == 4096)) { ++ log_debug("Set last byte mixed block sizes physical %u logical %u using 4096", ++ physical_block_size, logical_block_size); ++ bs = 4096; ++ } else { ++ log_debug("Set last byte mixed block sizes physical %u logical %u using 512", ++ physical_block_size, logical_block_size); ++ bs = 512; ++ } + +- bcache_set_last_byte(scan_bcache, dev->bcache_fd, offset, phys_block_size); ++ bcache_set_last_byte(scan_bcache, dev->bcache_fd, offset, bs); + } + + void dev_unset_last_byte(struct device *dev) +-- +1.8.3.1 + diff --git a/SOURCES/lvm2-2_02_186-cov-Fix-a-leak.patch b/SOURCES/lvm2-2_02_186-cov-Fix-a-leak.patch new file mode 100644 index 0000000..e8d761b --- /dev/null +++ b/SOURCES/lvm2-2_02_186-cov-Fix-a-leak.patch @@ -0,0 +1,35 @@ +From de0ec5fed07468b7205f9b84c668cb73445a29d3 Mon Sep 17 00:00:00 2001 +From: Marian Csontos +Date: Tue, 27 Aug 2019 12:21:41 +0200 +Subject: [PATCH] cov: Fix a leak + +--- + lib/device/bcache.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/lib/device/bcache.c b/lib/device/bcache.c +index 423eeb7..b6ec8d4 100644 +--- a/lib/device/bcache.c ++++ b/lib/device/bcache.c +@@ -517,6 +517,7 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd, + (unsigned long long)limit_nbytes, + (unsigned long long)extra_nbytes, + (unsigned long long)_last_byte_sector_size); ++ free(io); + return false; + } + } +@@ -548,8 +549,8 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd, + log_debug("Device write error %d offset %llu len %llu", errno, + (unsigned long long)(where + pos), + (unsigned long long)(len - pos)); +- free(io); +- return false; ++ free(io); ++ return false; + } + pos += rv; + } +-- +1.8.3.1 + diff --git a/SOURCES/lvm2-2_02_186-lvconvert-allow-stripes-stripesize-in-mirror-convers.patch b/SOURCES/lvm2-2_02_186-lvconvert-allow-stripes-stripesize-in-mirror-convers.patch new file mode 100644 index 0000000..abad898 --- /dev/null +++ b/SOURCES/lvm2-2_02_186-lvconvert-allow-stripes-stripesize-in-mirror-convers.patch @@ -0,0 +1,41 @@ +From a9b36a2e6388f4b046af2f9de4f062e28e87015d Mon Sep 17 00:00:00 2001 +From: Heinz Mauelshagen +Date: Mon, 8 Jul 2019 19:07:18 +0200 +Subject: [PATCH 1/2] lvconvert: allow --stripes/--stripesize in 'mirror' + conversions + +This allows the creation of a striped mirror leg(s) during upconvert +by adding lvconvert command line options --stripes/--stripesize +for 'mirror' to tools/command-lines.in. + +In case multiple mirror legs are being added, all will have the +same requested striped layout. + +Resolves: rhbz1720705 +(cherry picked from commit e3c8cebd87f9bd7591529f3d65783cc6f1fd3f92) +--- + tools/command-lines.in | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/tools/command-lines.in b/tools/command-lines.in +index a8c06ba..b4a9896 100644 +--- a/tools/command-lines.in ++++ b/tools/command-lines.in +@@ -334,13 +334,11 @@ DESC: Convert LV to striped. + RULE: all not lv_is_locked lv_is_pvmove + + lvconvert --type mirror LV +-OO: --mirrors SNumber, --regionsize RegionSize, --interval Number, --mirrorlog MirrorLog, OO_LVCONVERT ++OO: --mirrors SNumber, --stripes_long Number, --stripesize SizeKB, --regionsize RegionSize, --interval Number, --mirrorlog MirrorLog, OO_LVCONVERT + OP: PV ... + ID: lvconvert_raid_types + DESC: Convert LV to type mirror (also see type raid1), +-DESC: (also see lvconvert --mirrors). + RULE: all not lv_is_locked lv_is_pvmove +-FLAGS: SECONDARY_SYNTAX + + # When LV is already raid, this changes the raid layout + # (changing layout of raid0 and raid1 not allowed.) +-- +1.8.3.1 + diff --git a/SOURCES/lvm2-make-generate-2.patch b/SOURCES/lvm2-make-generate-2.patch new file mode 100644 index 0000000..7df6bd2 --- /dev/null +++ b/SOURCES/lvm2-make-generate-2.patch @@ -0,0 +1,101 @@ +From a5e7bb16e2fadb216e0dfa8c3ae461d9667ebf50 Mon Sep 17 00:00:00 2001 +From: Marian Csontos +Date: Mon, 26 Aug 2019 15:51:11 +0200 +Subject: [PATCH] build: make generate + +(cherry picked from commit f68a37f806a71aa76901e7cdec63f59584521641) +--- + man/lvconvert.8_pregen | 70 +++++++++++++++++++++++++++----------------------- + 1 file changed, 38 insertions(+), 32 deletions(-) + +diff --git a/man/lvconvert.8_pregen b/man/lvconvert.8_pregen +index a47127b..e6de8f0 100644 +--- a/man/lvconvert.8_pregen ++++ b/man/lvconvert.8_pregen +@@ -354,6 +354,44 @@ Convert LV to striped. + .RE + - + ++Convert LV to type mirror (also see type raid1), ++.br ++.P ++\fBlvconvert\fP \fB--type\fP \fBmirror\fP \fILV\fP ++.br ++.RS 4 ++.ad l ++[ \fB-m\fP|\fB--mirrors\fP [\fB+\fP|\fB-\fP]\fINumber\fP ] ++.ad b ++.br ++.ad l ++[ \fB-I\fP|\fB--stripesize\fP \fISize\fP[k|UNIT] ] ++.ad b ++.br ++.ad l ++[ \fB-R\fP|\fB--regionsize\fP \fISize\fP[m|UNIT] ] ++.ad b ++.br ++.ad l ++[ \fB-i\fP|\fB--interval\fP \fINumber\fP ] ++.ad b ++.br ++.ad l ++[ \fB--stripes\fP \fINumber\fP ] ++.ad b ++.br ++.ad l ++[ \fB--mirrorlog\fP \fBcore\fP|\fBdisk\fP ] ++.ad b ++.br ++[ COMMON_OPTIONS ] ++.RE ++.br ++.RS 4 ++[ \fIPV\fP ... ] ++.RE ++- ++ + Convert LV to raid or change raid layout + .br + (a specific raid level must be used, e.g. raid1). +@@ -1472,38 +1510,6 @@ For example, LVM_VG_NAME can generally be substituted for a required VG paramete + .SH ADVANCED USAGE + Alternate command forms, advanced command usage, and listing of all valid syntax for completeness. + .P +-Convert LV to type mirror (also see type raid1), +-.br +-(also see lvconvert --mirrors). +-.br +-.P +-\fBlvconvert\fP \fB--type\fP \fBmirror\fP \fILV\fP +-.br +-.RS 4 +-.ad l +-[ \fB-m\fP|\fB--mirrors\fP [\fB+\fP|\fB-\fP]\fINumber\fP ] +-.ad b +-.br +-.ad l +-[ \fB-R\fP|\fB--regionsize\fP \fISize\fP[m|UNIT] ] +-.ad b +-.br +-.ad l +-[ \fB-i\fP|\fB--interval\fP \fINumber\fP ] +-.ad b +-.br +-.ad l +-[ \fB--mirrorlog\fP \fBcore\fP|\fBdisk\fP ] +-.ad b +-.br +-[ COMMON_OPTIONS ] +-.RE +-.br +-.RS 4 +-[ \fIPV\fP ... ] +-.RE +-- +- + Change the region size of an LV. + .br + .P +-- +1.8.3.1 + diff --git a/SPECS/lvm2.spec b/SPECS/lvm2.spec index 9d8bece..23e37a0 100644 --- a/SPECS/lvm2.spec +++ b/SPECS/lvm2.spec @@ -67,7 +67,7 @@ Summary: Userland logical volume management tools Name: lvm2 Epoch: 7 Version: 2.02.185 -Release: 2%{?dist}%{?scratch} +Release: 2%{?dist}%{?scratch}.2 License: GPLv2 Group: System Environment/Base URL: http://sources.redhat.com/lvm2 @@ -85,6 +85,10 @@ Patch8: lvm2-2_02_186-man-updates-to-lvmlockd.patch Patch9: lvm2-2_02_186-cache-support-no_discard_passdown.patch Patch10: lvm2-2_02_186-mirror-fix-monitoring-change.patch Patch11: lvm2-make-generate.patch +Patch12: lvm2-2_02_186-lvconvert-allow-stripes-stripesize-in-mirror-convers.patch +Patch13: lvm2-2_02_186-Fix-rounding-writes-up-to-sector-size.patch +Patch14: lvm2-make-generate-2.patch +Patch15: lvm2-2_02_186-cov-Fix-a-leak.patch BuildRequires: libselinux-devel >= %{libselinux_version}, libsepol-devel BuildRequires: libblkid-devel >= %{util_linux_version} @@ -149,6 +153,11 @@ or more physical volumes and creating one or more logical volumes %patch9 -p1 -b .cache_support_no_discard_passdown %patch10 -p1 -b .mirror_fix_monitoring_change %patch11 -p1 -b .generate +%patch12 -p1 -b .allow_stripes_in_mirror_conversions +%patch13 -p1 -b .fix_rounding_writes_up_to_sector_size +%patch14 -p1 -b .generate2 +%patch15 -p1 -b .cov_mem_leak + %build %global _default_pid_dir /run @@ -896,7 +905,7 @@ the device-mapper event library. %package -n %{boom_pkgname} Summary: %{boom_summary} Version: %{boom_version} -Release: %{boom_release}%{?dist}%{?scratch} +Release: %{boom_release}%{?dist}%{?scratch}.2 License: GPLv2 Group: System Environment/Base BuildArch: noarch @@ -927,6 +936,13 @@ This package provides the python2 version of boom. %endif %changelog +* Tue Aug 27 2019 Marian Csontos - 7:2.02.185-2.el7_7.2 +- Fix potential memory leak. + +* Mon Aug 26 2019 Marian Csontos - 7:2.02.185-2.el7_7.1 +- Allow stripes in mirror conversions. +- Fix rounding of writes to sector size. + * Fri Jun 21 2019 Marian Csontos - 7:2.02.185-2 - Fix cluster conversions from linear to mirror. - Report no_discard_passdown for cache LVs with lvs -o+kernel_discards.