From 1d62a42c793d2908e7677774242dd8af2c8be222 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Feb 16 2016 10:12:47 +0000 Subject: import lvm2-2.02.130-5.el7_2.1 --- diff --git a/SOURCES/lvm2-2_02_135-fix-resize-of-full-thin-pool-causing-data-loss.patch b/SOURCES/lvm2-2_02_135-fix-resize-of-full-thin-pool-causing-data-loss.patch new file mode 100644 index 0000000..e297080 --- /dev/null +++ b/SOURCES/lvm2-2_02_135-fix-resize-of-full-thin-pool-causing-data-loss.patch @@ -0,0 +1,204 @@ +commit 8aa13d867d8c707450bb1de1479e18a3bbbc324a +Author: Peter Rajnoha +Date: Tue Dec 1 13:10:31 2015 +0100 + + bz1274676 +--- + lib/activate/dev_manager.c | 11 ++++-- + libdm/.exported_symbols.Base | 1 - + libdm/.exported_symbols.DM_1_02_107 | 1 + + libdm/libdevmapper.h | 5 +++ + libdm/libdm-deptree.c | 25 ++++++++++++-- + test/shell/lvextend-thin-bz1274676.sh | 63 +++++++++++++++++++++++++++++++++++ + 6 files changed, 100 insertions(+), 6 deletions(-) + +diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c +index c8e9589..e1f547f 100644 +--- a/lib/activate/dev_manager.c ++++ b/lib/activate/dev_manager.c +@@ -3277,7 +3277,7 @@ static int _tree_action(struct dev_manager *dm, const struct logical_volume *lv, + break; + case SUSPEND: + dm_tree_skip_lockfs(root); +- if (!dm->flush_required && lv_is_mirror(lv) && !lv_is_pvmove(lv)) ++ if (!dm->flush_required && !lv_is_pvmove(lv)) + dm_tree_use_no_flush_suspend(root); + /* Fall through */ + case SUSPEND_WITH_LOCKFS: +@@ -3296,7 +3296,14 @@ static int _tree_action(struct dev_manager *dm, const struct logical_volume *lv, + if (!dm_tree_preload_children(root, dlid, DLID_SIZE)) + goto_out; + +- if (dm_tree_node_size_changed(root)) ++ if ((dm_tree_node_size_changed(root) < 0)) ++ dm->flush_required = 1; ++ ++ /* Currently keep the code require flush for any ++ * non 'thin pool/volume, mirror' or with any size change */ ++ if (!lv_is_thin_volume(lv) && ++ !lv_is_thin_pool(lv) && ++ (!lv_is_mirror(lv) || dm_tree_node_size_changed(root))) + dm->flush_required = 1; + + if (action == ACTIVATE) { +diff --git a/libdm/.exported_symbols.Base b/libdm/.exported_symbols.Base +index f9c3cb1..27fef53 100644 +--- a/libdm/.exported_symbols.Base ++++ b/libdm/.exported_symbols.Base +@@ -262,7 +262,6 @@ dm_tree_node_set_thin_external_origin + dm_tree_node_set_thin_pool_discard + dm_tree_node_set_thin_pool_error_if_no_space + dm_tree_node_set_udev_flags +-dm_tree_node_size_changed + dm_tree_preload_children + dm_tree_retry_remove + dm_tree_set_cookie +diff --git a/libdm/.exported_symbols.DM_1_02_107 b/libdm/.exported_symbols.DM_1_02_107 +index 89d3464..0c7b7af 100644 +--- a/libdm/.exported_symbols.DM_1_02_107 ++++ b/libdm/.exported_symbols.DM_1_02_107 +@@ -13,3 +13,4 @@ dm_stats_create_region + dm_stats_driver_supports_histogram + dm_stats_get_histogram + dm_stats_get_region_nr_histogram_bins ++dm_tree_node_size_changed +diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h +index 098fa85..8d4b096 100644 +--- a/libdm/libdevmapper.h ++++ b/libdm/libdevmapper.h +@@ -1252,6 +1252,11 @@ const char *dm_tree_node_get_name(const struct dm_tree_node *node); + const char *dm_tree_node_get_uuid(const struct dm_tree_node *node); + const struct dm_info *dm_tree_node_get_info(const struct dm_tree_node *node); + void *dm_tree_node_get_context(const struct dm_tree_node *node); ++/* ++ * Returns 0 when node size and its children is unchanged. ++ * Returns 1 when node or any of its children has increased size. ++ * Rerurns -1 when node or any of its children has reduced size. ++ */ + int dm_tree_node_size_changed(const struct dm_tree_node *dnode); + + /* +diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c +index fc79e33..0584079 100644 +--- a/libdm/libdm-deptree.c ++++ b/libdm/libdm-deptree.c +@@ -220,7 +220,7 @@ struct load_properties { + uint32_t read_ahead_flags; + + unsigned segment_count; +- unsigned size_changed; ++ int size_changed; + struct dm_list segs; + + const char *new_name; +@@ -2768,7 +2768,8 @@ static int _load_node(struct dm_tree_node *dnode) + + existing_table_size = dm_task_get_existing_table_size(dmt); + if ((dnode->props.size_changed = +- (existing_table_size == seg_start) ? 0 : 1)) { ++ (existing_table_size == seg_start) ? 0 : ++ (existing_table_size > seg_start) ? -1 : 1)) { + /* + * Kernel usually skips size validation on zero-length devices + * now so no need to preload them. +@@ -2864,8 +2865,10 @@ int dm_tree_preload_children(struct dm_tree_node *dnode, + } + + /* Propagate device size change change */ +- if (child->props.size_changed) ++ if (child->props.size_changed > 0 && !dnode->props.size_changed) + dnode->props.size_changed = 1; ++ else if (child->props.size_changed < 0) ++ dnode->props.size_changed = -1; + + /* Resume device immediately if it has parents and its size changed */ + if (!dm_tree_node_num_children(child, 1) || !child->props.size_changed) +@@ -4190,3 +4193,19 @@ void dm_tree_node_set_callback(struct dm_tree_node *dnode, + dnode->callback = cb; + dnode->callback_data = data; + } ++ ++/* ++ * Backward compatible dm_tree_node_size_changed() implementations. ++ * ++ * Keep these at the end of the file to avoid adding clutter around the ++ * current dm_tree_node_size_changed() version. ++ */ ++#if defined(__GNUC__) ++int dm_tree_node_size_changed_base(const struct dm_tree_node *dnode); ++DM_EXPORT_SYMBOL_BASE(dm_tree_node_size_changed); ++int dm_tree_node_size_changed_base(const struct dm_tree_node *dnode) ++{ ++ /* Base does not make difference between smaller and bigger */ ++ return dm_tree_node_size_changed(dnode) ? 1 : 0; ++} ++#endif +diff --git a/test/shell/lvextend-thin-bz1274676.sh b/test/shell/lvextend-thin-bz1274676.sh +new file mode 100644 +index 0000000..facace0 +--- /dev/null ++++ b/test/shell/lvextend-thin-bz1274676.sh +@@ -0,0 +1,63 @@ ++#!/bin/bash ++# Copyright (C) 2015 Red Hat, Inc. All rights reserved. ++# ++# This copyrighted material is made available to anyone wishing to use, ++# modify, copy, or redistribute it subject to the terms and conditions ++# of the GNU General Public License v.2. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software Foundation, ++# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ ++# ensure there is no data loss during thin-pool resize ++ ++export LVM_TEST_THIN_REPAIR_CMD=${LVM_TEST_THIN_REPAIR_CMD-/bin/false} ++ ++. lib/inittest ++ ++test -e LOCAL_LVMPOLLD && skip ++ ++which md5sum || skip ++ ++aux have_thin 1 0 0 || skip ++ ++aux prepare_pvs 2 20 ++ ++vgcreate -s 512K $vg $(< DEVICES) ++ ++lvcreate -L1M -V2M -n $lv1 -T $vg/pool ++ ++# just ensure we check what we need to check ++check lv_field $vg/pool size "1.00m" ++check lv_field $vg/$lv1 size "2.00m" ++ ++# prepare 2097152 file content ++seq 0 315465 > 2M ++md5sum 2M | cut -f 1 -d ' ' | tee MD5 ++dd if=2M of="$DM_DEV_DIR/mapper/$vg-$lv1" bs=512K conv=fdatasync 2>&1 >log & ++#dd if=2M of="$DM_DEV_DIR/mapper/$vg-$lv1" bs=2M oflag=direct & ++ ++# give it some time to fill thin-volume ++# eventually loop to wait for 100% full pool... ++sleep .1 ++lvs -a $vg ++ ++# this must not 'block & wait' on suspending flush ++# if it waits on thin-pool's target timeout ++# it will harm queued data ++lvextend -L+512k $vg/pool ++lvextend -L+512k $vg/pool ++ ++# collect 'dd' result ++wait ++cat log ++ ++lvs -a $vg ++ ++dd if="$DM_DEV_DIR/mapper/$vg-$lv1" of=2M-2 iflag=direct ++md5sum 2M-2 | cut -f 1 -d ' ' | tee MD5-2 ++ ++# these 2 are supposed to match ++diff MD5 MD5-2 ++ ++vgremove -f $vg diff --git a/SOURCES/lvm2-rhel7.patch b/SOURCES/lvm2-rhel7.patch index fec262d..a671864 100644 --- a/SOURCES/lvm2-rhel7.patch +++ b/SOURCES/lvm2-rhel7.patch @@ -8,11 +8,11 @@ index dd4e60e..39d6c15 100644 +++ b/VERSION @@ -1 +1 @@ -2.02.130(2) (2015-09-05) -+2.02.130(2)-RHEL7 (2015-10-14) ++2.02.130(2)-RHEL7 (2015-12-01) diff --git a/VERSION_DM b/VERSION_DM index d53f47a..005fbd4 100644 --- a/VERSION_DM +++ b/VERSION_DM @@ -1 +1 @@ -1.02.107 (2015-09-05) -+1.02.107-RHEL7 (2015-10-14) ++1.02.107-RHEL7 (2015-12-01) diff --git a/SPECS/lvm2.spec b/SPECS/lvm2.spec index 9377a64..ecba3dc 100644 --- a/SPECS/lvm2.spec +++ b/SPECS/lvm2.spec @@ -52,7 +52,7 @@ Summary: Userland logical volume management tools Name: lvm2 Epoch: 7 Version: 2.02.130 -Release: 5%{?dist} +Release: 5%{?dist}.1 License: GPLv2 Group: System Environment/Base URL: http://sources.redhat.com/lvm2 @@ -72,6 +72,7 @@ Patch11: lvm2-2_02_131-disallow-usage-of-stripe-and-stripesize-when-creating-cac Patch12: lvm2-2_02_131-fix-vgimportclone-cache_dir-path-name.patch Patch13: lvm2-2_02_133-check-for-space-in-thin-pool-before-creating-new-thin.patch Patch14: lvm2-2_02_133-enforce-writethrough-mode-for-cleaner-policy.patch +Patch15: lvm2-2_02_135-fix-resize-of-full-thin-pool-causing-data-loss.patch BuildRequires: libselinux-devel >= %{libselinux_version}, libsepol-devel BuildRequires: libblkid-devel >= %{util_linux_version} @@ -132,6 +133,7 @@ or more physical volumes and creating one or more logical volumes %patch12 -p1 -b .vgimportclone_cache_dir %patch13 -p1 -b .check_for_thin_pool_space %patch14 -p1 -b .writethrough_cleaner_policy +%patch15 -p1 -b .thin_pool_resize_data_loss %build %define _default_pid_dir /run @@ -830,6 +832,10 @@ the device-mapper event library. %{_libdir}/pkgconfig/devmapper-event.pc %changelog +* Tue Dec 01 2015 Peter Rajnoha - 7:2.02.130-5.el7_2.1 +- Fix possible data loss caused by lost buffered writes during thin pool + resize after reaching its capacity. + * Wed Oct 14 2015 Peter Rajnoha - 7:2.02.130-5 - Fixup /etc/lvm/archive ownership.