summaryrefslogtreecommitdiff
path: root/lib/snapshot
diff options
context:
space:
mode:
authorZdenek Kabelac <zkabelac@redhat.com>2014-02-25 19:43:07 +0100
committerZdenek Kabelac <zkabelac@redhat.com>2014-02-26 14:25:09 +0100
commit40e6176d251b68f5be8ca7925a2f073982de6cec (patch)
tree242b7de295036a3893fa0b1a956621ed50ff058d /lib/snapshot
parent014ba37cb19c9172b1b81af3f31897939f72b1d2 (diff)
downloadlvm2-40e6176d251b68f5be8ca7925a2f073982de6cec.tar.gz
snapshots: fix incorrect calculation of cow size
Code uses target driver version for better estimation of max size of COW device for snapshot. The bug can be tested with this script: VG=vg1 lvremove -f $VG/origin set -e lvcreate -L 2143289344b -n origin $VG lvcreate -n snap -c 8k -L 2304M -s $VG/origin dd if=/dev/zero of=/dev/$VG/snap bs=1M count=2044 oflag=direct The bug happens when these two conditions are met * origin size is divisible by (chunk_size/16) - so that the last metadata area is filled completely * the miscalculated snapshot metadata size is divisible by extent size - so that there is no padding to extent boundary which would otherwise save us Signed-off-by:Mikulas Patocka <mpatocka@redhat.com>
Diffstat (limited to 'lib/snapshot')
-rw-r--r--lib/snapshot/snapshot.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/lib/snapshot/snapshot.c b/lib/snapshot/snapshot.c
index 91e778f6d..0b7b84568 100644
--- a/lib/snapshot/snapshot.c
+++ b/lib/snapshot/snapshot.c
@@ -142,19 +142,30 @@ static int _snap_target_percent(void **target_state __attribute__((unused)),
static int _snap_target_present(struct cmd_context *cmd,
const struct lv_segment *seg,
- unsigned *attributes __attribute__((unused)))
+ unsigned *attributes)
{
static int _snap_checked = 0;
static int _snap_merge_checked = 0;
static int _snap_present = 0;
static int _snap_merge_present = 0;
+ static unsigned _snap_attrs = 0;
+ uint32_t maj, min, patchlevel;
if (!_snap_checked) {
+ _snap_checked = 1;
_snap_present = target_present(cmd, "snapshot", 1) &&
target_present(cmd, "snapshot-origin", 0);
- _snap_checked = 1;
+
+ if (_snap_present &&
+ target_version("snapshot", &maj, &min, &patchlevel) &&
+ (maj > 1 ||
+ (maj == 1 && (min >= 12 || (min == 10 && patchlevel >= 2)))))
+ _snap_attrs |= SNAPSHOT_FEATURE_FIXED_LEAK;
+ else
+ log_very_verbose("Target snapshot may leak metadata.");
}
+ /* TODO: test everything at once */
if (seg && (seg->status & MERGING)) {
if (!_snap_merge_checked) {
_snap_merge_present = target_present(cmd, "snapshot-merge", 0);