master - [bcache] bcache_invalidate_fd, only remove prefixes on success.
by Joe Thornber
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=25e7bf021a4e7c5ad5f...
Commit: 25e7bf021a4e7c5ad5f925b86605bf025ff1a949
Parent: 7e8296f4788d6a83863a268582280587ade2e26c
Author: Joe Thornber <ejt(a)redhat.com>
AuthorDate: Tue Oct 29 15:21:11 2019 +0000
Committer: Joe Thornber <ejt(a)redhat.com>
CommitterDate: Tue Oct 29 15:21:11 2019 +0000
[bcache] bcache_invalidate_fd, only remove prefixes on success.
---
lib/device/bcache.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/lib/device/bcache.c b/lib/device/bcache.c
index b0edf28..04d49f1 100644
--- a/lib/device/bcache.c
+++ b/lib/device/bcache.c
@@ -1376,7 +1376,10 @@ bool bcache_invalidate_fd(struct bcache *cache, int fd)
it.success = true;
it.it.visit = _invalidate_v;
radix_tree_iterate(cache->rtree, k.bytes, k.bytes + sizeof(k.parts.fd), &it.it);
- radix_tree_remove_prefix(cache->rtree, k.bytes, k.bytes + sizeof(k.parts.fd));
+
+ if (it.success)
+ radix_tree_remove_prefix(cache->rtree, k.bytes, k.bytes + sizeof(k.parts.fd));
+
return it.success;
}
4 years, 6 months
master - [bcache] reverse earlier patch.
by Joe Thornber
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=7e8296f4788d6a83863...
Commit: 7e8296f4788d6a83863a268582280587ade2e26c
Parent: 2b3c39e402b966043a65ae649797defb6db597fc
Author: Joe Thornber <ejt(a)redhat.com>
AuthorDate: Tue Oct 29 15:14:07 2019 +0000
Committer: Joe Thornber <ejt(a)redhat.com>
CommitterDate: Tue Oct 29 15:14:07 2019 +0000
[bcache] reverse earlier patch.
It broke some unit tests, for v. little benefit
---
lib/device/bcache.c | 7 ++-----
1 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/lib/device/bcache.c b/lib/device/bcache.c
index 1249d6e..b0edf28 100644
--- a/lib/device/bcache.c
+++ b/lib/device/bcache.c
@@ -293,10 +293,6 @@ static bool _async_issue(struct io_engine *ioe, enum dir d, int fd,
if (r < 0) {
_cb_free(e->cbs, cb);
- ((struct block *) context)->error = r;
- log_warn("io_submit <%c> off %llu bytes %llu return %d:%s",
- (d == DIR_READ) ? 'R' : 'W', (long long unsigned)offset,
- (long long unsigned) nbytes, r, strerror(-r));
return false;
}
@@ -873,7 +869,8 @@ static void _issue_low_level(struct block *b, enum dir d)
dm_list_move(&cache->io_pending, &b->list);
if (!cache->engine->issue(cache->engine, d, b->fd, sb, se, b->data, b)) {
- _complete_io(b, b->error);
+ /* FIXME: if io_submit() set an errno, return that instead of EIO? */
+ _complete_io(b, -EIO);
return;
}
}
4 years, 6 months
master - [bcache] pass up the error from io_submit rather than using generic -EIO
by Joe Thornber
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=2b3c39e402b966043a6...
Commit: 2b3c39e402b966043a65ae649797defb6db597fc
Parent: 5fdebf9bbf68a53b9d2153dbd8bf27a36e0ef3cd
Author: Joe Thornber <ejt(a)redhat.com>
AuthorDate: Tue Oct 29 10:39:20 2019 +0000
Committer: Joe Thornber <ejt(a)redhat.com>
CommitterDate: Tue Oct 29 10:39:20 2019 +0000
[bcache] pass up the error from io_submit rather than using generic -EIO
Author: Heming Zhao
---
lib/device/bcache.c | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/lib/device/bcache.c b/lib/device/bcache.c
index b0edf28..1249d6e 100644
--- a/lib/device/bcache.c
+++ b/lib/device/bcache.c
@@ -293,6 +293,10 @@ static bool _async_issue(struct io_engine *ioe, enum dir d, int fd,
if (r < 0) {
_cb_free(e->cbs, cb);
+ ((struct block *) context)->error = r;
+ log_warn("io_submit <%c> off %llu bytes %llu return %d:%s",
+ (d == DIR_READ) ? 'R' : 'W', (long long unsigned)offset,
+ (long long unsigned) nbytes, r, strerror(-r));
return false;
}
@@ -869,8 +873,7 @@ static void _issue_low_level(struct block *b, enum dir d)
dm_list_move(&cache->io_pending, &b->list);
if (!cache->engine->issue(cache->engine, d, b->fd, sb, se, b->data, b)) {
- /* FIXME: if io_submit() set an errno, return that instead of EIO? */
- _complete_io(b, -EIO);
+ _complete_io(b, b->error);
return;
}
}
4 years, 6 months
master - [bcache] add unit test
by Joe Thornber
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=5fdebf9bbf68a53b9d2...
Commit: 5fdebf9bbf68a53b9d2153dbd8bf27a36e0ef3cd
Parent: 6b0d969b2a85ba69046afa26af4d7bcddddbccd5
Author: Joe Thornber <ejt(a)redhat.com>
AuthorDate: Tue Oct 29 10:33:31 2019 +0000
Committer: Joe Thornber <ejt(a)redhat.com>
CommitterDate: Tue Oct 29 10:33:31 2019 +0000
[bcache] add unit test
abort-forces-read
---
test/unit/bcache_t.c | 24 ++++++++++++++++++++++++
1 files changed, 24 insertions(+), 0 deletions(-)
diff --git a/test/unit/bcache_t.c b/test/unit/bcache_t.c
index 668d24d..2a8f931 100644
--- a/test/unit/bcache_t.c
+++ b/test/unit/bcache_t.c
@@ -837,6 +837,29 @@ static void test_abort_single_block(void *context)
T_ASSERT(bcache_flush(cache));
}
+static void test_abort_forces_reread(void *context)
+{
+ struct fixture *f = context;
+ struct mock_engine *me = f->me;
+ struct bcache *cache = f->cache;
+ struct block *b;
+ int fd = 17;
+
+ _expect_read(me, fd, 0);
+ _expect(me, E_WAIT);
+ T_ASSERT(bcache_get(cache, fd, 0, GF_DIRTY, &b));
+ bcache_put(b);
+
+ bcache_abort_fd(cache, fd);
+ T_ASSERT(bcache_flush(cache));
+
+ // Check the block is re-read
+ _expect_read(me, fd, 0);
+ _expect(me, E_WAIT);
+ T_ASSERT(bcache_get(cache, fd, 0, 0, &b));
+ bcache_put(b);
+}
+
static void test_abort_only_specific_fd(void *context)
{
struct fixture *f = context;
@@ -960,6 +983,7 @@ static struct test_suite *_small_tests(void)
T("abort-with-no-blocks", "you can call abort, even if there are no blocks in the cache", test_abort_no_blocks);
T("abort-single-block", "single block get silently discarded", test_abort_single_block);
+ T("abort-forces-read", "if a block has been discarded then another read is necc.", test_abort_forces_reread);
T("abort-specific-fd", "abort doesn't effect other fds", test_abort_only_specific_fd);
T("concurrent-reads-after-invalidate", "prefetch should still issue concurrent reads after invalidate",
4 years, 6 months
master - [label] Use bcache_abort_fd() to ensure blocks are no longer in the cache.
by Joe Thornber
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=6b0d969b2a85ba69046...
Commit: 6b0d969b2a85ba69046afa26af4d7bcddddbccd5
Parent: 2938b4dcca0a1df661758abfab7f402ea7aab018
Author: Joe Thornber <ejt(a)redhat.com>
AuthorDate: Mon Oct 28 15:01:47 2019 +0000
Committer: Joe Thornber <ejt(a)redhat.com>
CommitterDate: Mon Oct 28 15:01:47 2019 +0000
[label] Use bcache_abort_fd() to ensure blocks are no longer in the cache.
The return value from bcache_invalidate_fd() was not being checked.
So I've introduced a little function, _invalidate_fd() that always
calls bcache_abort_fd() if the write fails.
---
lib/label/label.c | 32 ++++++++++++++++++++------------
1 files changed, 20 insertions(+), 12 deletions(-)
diff --git a/lib/label/label.c b/lib/label/label.c
index dc4d32d..7dcaf8a 100644
--- a/lib/label/label.c
+++ b/lib/label/label.c
@@ -620,6 +620,14 @@ static void _drop_bad_aliases(struct device *dev)
}
}
+// Like bcache_invalidate, only it throws any dirty data away if the
+// write fails.
+static void _invalidate_fd(struct bcache *cache, int fd)
+{
+ if (!bcache_invalidate_fd(cache, fd))
+ bcache_abort_fd(cache, fd);
+}
+
/*
* Read or reread label/metadata from selected devs.
*
@@ -731,7 +739,7 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
* drop it from bcache.
*/
if (scan_failed || !is_lvm_device) {
- bcache_invalidate_fd(scan_bcache, devl->dev->bcache_fd);
+ _invalidate_fd(scan_bcache, devl->dev->bcache_fd);
_scan_dev_close(devl->dev);
}
@@ -996,7 +1004,7 @@ int label_scan(struct cmd_context *cmd)
* so this will usually not be true.
*/
if (_in_bcache(dev)) {
- bcache_invalidate_fd(scan_bcache, dev->bcache_fd);
+ _invalidate_fd(scan_bcache, dev->bcache_fd);
_scan_dev_close(dev);
}
};
@@ -1169,7 +1177,7 @@ int label_scan_devs(struct cmd_context *cmd, struct dev_filter *f, struct dm_lis
dm_list_iterate_items(devl, devs) {
if (_in_bcache(devl->dev)) {
- bcache_invalidate_fd(scan_bcache, devl->dev->bcache_fd);
+ _invalidate_fd(scan_bcache, devl->dev->bcache_fd);
_scan_dev_close(devl->dev);
}
}
@@ -1196,7 +1204,7 @@ int label_scan_devs_rw(struct cmd_context *cmd, struct dev_filter *f, struct dm_
dm_list_iterate_items(devl, devs) {
if (_in_bcache(devl->dev)) {
- bcache_invalidate_fd(scan_bcache, devl->dev->bcache_fd);
+ _invalidate_fd(scan_bcache, devl->dev->bcache_fd);
_scan_dev_close(devl->dev);
}
/*
@@ -1218,7 +1226,7 @@ int label_scan_devs_excl(struct dm_list *devs)
dm_list_iterate_items(devl, devs) {
if (_in_bcache(devl->dev)) {
- bcache_invalidate_fd(scan_bcache, devl->dev->bcache_fd);
+ _invalidate_fd(scan_bcache, devl->dev->bcache_fd);
_scan_dev_close(devl->dev);
}
/*
@@ -1238,7 +1246,7 @@ int label_scan_devs_excl(struct dm_list *devs)
void label_scan_invalidate(struct device *dev)
{
if (_in_bcache(dev)) {
- bcache_invalidate_fd(scan_bcache, dev->bcache_fd);
+ _invalidate_fd(scan_bcache, dev->bcache_fd);
_scan_dev_close(dev);
}
}
@@ -1320,7 +1328,7 @@ int label_read(struct device *dev)
dm_list_add(&one_dev, &devl->list);
if (_in_bcache(dev)) {
- bcache_invalidate_fd(scan_bcache, dev->bcache_fd);
+ _invalidate_fd(scan_bcache, dev->bcache_fd);
_scan_dev_close(dev);
}
@@ -1362,7 +1370,7 @@ int label_scan_open_excl(struct device *dev)
if (_in_bcache(dev) && !(dev->flags & DEV_BCACHE_EXCL)) {
/* FIXME: avoid tossing out bcache blocks just to replace fd. */
log_debug("Close and reopen excl %s", dev_name(dev));
- bcache_invalidate_fd(scan_bcache, dev->bcache_fd);
+ _invalidate_fd(scan_bcache, dev->bcache_fd);
_scan_dev_close(dev);
}
dev->flags |= DEV_BCACHE_EXCL;
@@ -1375,7 +1383,7 @@ int label_scan_open_rw(struct device *dev)
if (_in_bcache(dev) && !(dev->flags & DEV_BCACHE_WRITE)) {
/* FIXME: avoid tossing out bcache blocks just to replace fd. */
log_debug("Close and reopen rw %s", dev_name(dev));
- bcache_invalidate_fd(scan_bcache, dev->bcache_fd);
+ _invalidate_fd(scan_bcache, dev->bcache_fd);
_scan_dev_close(dev);
}
dev->flags |= DEV_BCACHE_WRITE;
@@ -1423,7 +1431,7 @@ bool dev_write_bytes(struct device *dev, uint64_t start, size_t len, void *data)
if (_in_bcache(dev) && !(dev->flags & DEV_BCACHE_WRITE)) {
/* FIXME: avoid tossing out bcache blocks just to replace fd. */
log_debug("Close and reopen to write %s", dev_name(dev));
- bcache_invalidate_fd(scan_bcache, dev->bcache_fd);
+ _invalidate_fd(scan_bcache, dev->bcache_fd);
_scan_dev_close(dev);
dev->flags |= DEV_BCACHE_WRITE;
@@ -1469,7 +1477,7 @@ bool dev_write_zeros(struct device *dev, uint64_t start, size_t len)
if (_in_bcache(dev) && !(dev->flags & DEV_BCACHE_WRITE)) {
/* FIXME: avoid tossing out bcache blocks just to replace fd. */
log_debug("Close and reopen to write %s", dev_name(dev));
- bcache_invalidate_fd(scan_bcache, dev->bcache_fd);
+ _invalidate_fd(scan_bcache, dev->bcache_fd);
_scan_dev_close(dev);
dev->flags |= DEV_BCACHE_WRITE;
@@ -1520,7 +1528,7 @@ bool dev_set_bytes(struct device *dev, uint64_t start, size_t len, uint8_t val)
if (_in_bcache(dev) && !(dev->flags & DEV_BCACHE_WRITE)) {
/* FIXME: avoid tossing out bcache blocks just to replace fd. */
log_debug("Close and reopen to write %s", dev_name(dev));
- bcache_invalidate_fd(scan_bcache, dev->bcache_fd);
+ _invalidate_fd(scan_bcache, dev->bcache_fd);
_scan_dev_close(dev);
/* goes to label_scan_open() since bcache_fd < 0 */
}
4 years, 6 months
master - [bcache] add bcache_abort()
by Joe Thornber
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=2938b4dcca0a1df6617...
Commit: 2938b4dcca0a1df661758abfab7f402ea7aab018
Parent: 6163b733e1564b4c322204b9a8208e2ea4e63181
Author: Joe Thornber <ejt(a)redhat.com>
AuthorDate: Mon Oct 28 14:29:47 2019 +0000
Committer: Joe Thornber <ejt(a)redhat.com>
CommitterDate: Mon Oct 28 15:00:53 2019 +0000
[bcache] add bcache_abort()
This gives us a way to cope with write failures.
---
lib/device/bcache.c | 33 ++++++++++++++++++++++++
lib/device/bcache.h | 7 +++++
test/unit/bcache_t.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 106 insertions(+), 1 deletions(-)
diff --git a/lib/device/bcache.c b/lib/device/bcache.c
index d100419..b0edf28 100644
--- a/lib/device/bcache.c
+++ b/lib/device/bcache.c
@@ -1382,6 +1382,39 @@ bool bcache_invalidate_fd(struct bcache *cache, int fd)
//----------------------------------------------------------------
+static bool _abort_v(struct radix_tree_iterator *it,
+ uint8_t *kb, uint8_t *ke, union radix_value v)
+{
+ struct block *b = v.ptr;
+
+ if (b->ref_count) {
+ log_fatal("bcache_abort: block (%d, %llu) still held",
+ b->fd, (unsigned long long) b->index);
+ return true;
+ }
+
+ _unlink_block(b);
+ _free_block(b);
+
+ // We can't remove the block from the radix tree yet because
+ // we're in the middle of an iteration.
+ return true;
+}
+
+void bcache_abort_fd(struct bcache *cache, int fd)
+{
+ union key k;
+ struct radix_tree_iterator it;
+
+ k.parts.fd = fd;
+
+ it.visit = _abort_v;
+ radix_tree_iterate(cache->rtree, k.bytes, k.bytes + sizeof(k.parts.fd), &it);
+ radix_tree_remove_prefix(cache->rtree, k.bytes, k.bytes + sizeof(k.parts.fd));
+}
+
+//----------------------------------------------------------------
+
void bcache_set_last_byte(struct bcache *cache, int fd, uint64_t offset, int sector_size)
{
_last_byte_fd = fd;
diff --git a/lib/device/bcache.h b/lib/device/bcache.h
index 8c16caa..7622fd3 100644
--- a/lib/device/bcache.h
+++ b/lib/device/bcache.h
@@ -144,6 +144,13 @@ bool bcache_invalidate(struct bcache *cache, int fd, block_address index);
*/
bool bcache_invalidate_fd(struct bcache *cache, int fd);
+/*
+ * Call this function if flush, or invalidate fail and you do not
+ * wish to retry the writes. This will throw away any dirty data
+ * not written. If any blocks for fd are held, then it will call
+ * abort().
+ */
+void bcache_abort_fd(struct bcache *cache, int fd);
//----------------------------------------------------------------
// The next four functions are utilities written in terms of the above api.
diff --git a/test/unit/bcache_t.c b/test/unit/bcache_t.c
index 92c2d57..668d24d 100644
--- a/test/unit/bcache_t.c
+++ b/test/unit/bcache_t.c
@@ -793,7 +793,6 @@ static void test_invalidate_after_write_error(void *context)
static void test_invalidate_held_block(void *context)
{
-
struct fixture *f = context;
struct mock_engine *me = f->me;
struct bcache *cache = f->cache;
@@ -810,6 +809,67 @@ static void test_invalidate_held_block(void *context)
}
//----------------------------------------------------------------
+// abort tests
+
+static void test_abort_no_blocks(void *context)
+{
+ struct fixture *f = context;
+ struct bcache *cache = f->cache;
+ int fd = 17;
+
+ // We have no expectations
+ bcache_abort_fd(cache, fd);
+}
+
+static void test_abort_single_block(void *context)
+{
+ struct fixture *f = context;
+ struct bcache *cache = f->cache;
+ struct block *b;
+ int fd = 17;
+
+ T_ASSERT(bcache_get(cache, fd, 0, GF_ZERO, &b));
+ bcache_put(b);
+
+ bcache_abort_fd(cache, fd);
+
+ // no write should be issued
+ T_ASSERT(bcache_flush(cache));
+}
+
+static void test_abort_only_specific_fd(void *context)
+{
+ struct fixture *f = context;
+ struct mock_engine *me = f->me;
+ struct bcache *cache = f->cache;
+ struct block *b;
+ int fd1 = 17, fd2 = 18;
+
+ T_ASSERT(bcache_get(cache, fd1, 0, GF_ZERO, &b));
+ bcache_put(b);
+
+ T_ASSERT(bcache_get(cache, fd1, 1, GF_ZERO, &b));
+ bcache_put(b);
+
+ T_ASSERT(bcache_get(cache, fd2, 0, GF_ZERO, &b));
+ bcache_put(b);
+
+ T_ASSERT(bcache_get(cache, fd2, 1, GF_ZERO, &b));
+ bcache_put(b);
+
+ bcache_abort_fd(cache, fd2);
+
+ // writes for fd1 should still be issued
+ _expect_write(me, fd1, 0);
+ _expect_write(me, fd1, 1);
+
+ _expect(me, E_WAIT);
+ _expect(me, E_WAIT);
+
+ T_ASSERT(bcache_flush(cache));
+}
+
+//----------------------------------------------------------------
// Chasing a bug reported by dct
static void _cycle(struct fixture *f, unsigned nr_cache_blocks)
@@ -897,6 +957,11 @@ static struct test_suite *_small_tests(void)
T("invalidate-read-error", "invalidate a block that errored", test_invalidate_after_read_error);
T("invalidate-write-error", "invalidate a block that errored", test_invalidate_after_write_error);
T("invalidate-fails-in-held", "invalidating a held block fails", test_invalidate_held_block);
+
+ T("abort-with-no-blocks", "you can call abort, even if there are no blocks in the cache", test_abort_no_blocks);
+ T("abort-single-block", "single block get silently discarded", test_abort_single_block);
+ T("abort-specific-fd", "abort doesn't effect other fds", test_abort_only_specific_fd);
+
T("concurrent-reads-after-invalidate", "prefetch should still issue concurrent reads after invalidate",
test_concurrent_reads_after_invalidate);
4 years, 6 months
stable-2.02 - WHATS_NEW
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=5ee3d6dbdffc4746772...
Commit: 5ee3d6dbdffc47467727d8c89fc91d84aa97189a
Parent: 9a8bff003bb5cc64f785db7190c323cf6a714789
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sat Oct 26 00:48:00 2019 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Sat Oct 26 00:48:00 2019 +0200
WHATS_NEW
---
WHATS_NEW | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index a157986..4669443 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.187 -
===================================
+ Fix activation order when removing merged snapshot.
Add lvextend-raid.sh to check on RaidLV extensions synchronization.
Fix lvmetad shutdown and avoid lenghty timeouts when rebooting system.
Prevent creating VGs with PVs with different logical block sizes.
4 years, 6 months
stable-2.02 - tests: explicit testing of thin snapshot
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=9a8bff003bb5cc64f78...
Commit: 9a8bff003bb5cc64f785db7190c323cf6a714789
Parent: 963af243bfe68f4b8e83337529a39ff3324fef1d
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Sat Oct 26 00:15:31 2019 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Sat Oct 26 00:46:33 2019 +0200
tests: explicit testing of thin snapshot
Check merging of old snapshot of thin LV.
---
test/shell/snapshot-merge-thin.sh | 49 +++++++++++++++++++++++++++++++++++++
1 files changed, 49 insertions(+), 0 deletions(-)
diff --git a/test/shell/snapshot-merge-thin.sh b/test/shell/snapshot-merge-thin.sh
new file mode 100644
index 0000000..80969d1
--- /dev/null
+++ b/test/shell/snapshot-merge-thin.sh
@@ -0,0 +1,49 @@
+#!/usr/bin/env bash
+
+# Copyright (C) 2019 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+# Exercise merge of old snapshots over thin
+
+export LVM_TEST_THIN_REPAIR_CMD=${LVM_TEST_THIN_REPAIR_CMD-/bin/false}
+
+. lib/inittest
+
+aux target_at_least dm-snapshot-merge 1 0 0 || skip
+aux have_thin 1 0 0 || skip
+
+aux prepare_vg 2
+
+lvcreate -T -L1 -V1 -n $lv1 $vg/pool "$dev1"
+lvcreate -s -n $lv2 -L2 $vg/$lv1 "$dev2"
+dd if=/dev/zero of="$DM_DEV_DIR/$vg/$lv2" bs=1M count=1 conv=fdatasync
+
+# Initiate background merge
+lvconvert -b --merge $vg/$lv2
+
+# Query status of snapshot immediatelly after start
+# - may hit race of checking already in-progress merge
+lvs -a -o+lv_merging,lv_merge_failed $vg
+
+sleep 1
+
+# Here should be everything already merged
+lvs -a -o+lv_merging,lv_merge_failed $vg
+
+# -real must not exist for $vg/$lv1
+not dmsetup info ${vg}-${lv1}-real 2>&1 | tee out
+grep "not exist" out
+
+not dmsetup info ${vg}-${lv2}-cow 2>&1 | tee out
+grep "not exist" out
+
+check lv_not_exists $vg $lv2
+
+vgremove -f $vg
4 years, 6 months
stable-2.02 - snapshot: use single merging sequence
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=963af243bfe68f4b8e8...
Commit: 963af243bfe68f4b8e83337529a39ff3324fef1d
Parent: 8be8b994c6819343a13c547354507f6f89d837ca
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Oct 25 23:29:16 2019 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Sat Oct 26 00:42:50 2019 +0200
snapshot: use single merging sequence
The resume of 'released' 'COW' should preceed the resume of origin.
The fact we need to do the sequence differently for merge was
cause by bugs fixed in 2 previous commits - so we no longer need
to recognize 'merging' and we should always go with single
sequence.
The importance of this order is - to properly remove '-real' device
from origin LV. When COW is activated as 2nd. '-real' device is
kept in table as it cannot be removed during 1st. resume of origin,
and later activation of COW LV no longer builds tree associated
with origin LV.
---
lib/metadata/snapshot_manip.c | 19 +------------------
1 files changed, 1 insertions(+), 18 deletions(-)
diff --git a/lib/metadata/snapshot_manip.c b/lib/metadata/snapshot_manip.c
index aeb739c..95a3b2b 100644
--- a/lib/metadata/snapshot_manip.c
+++ b/lib/metadata/snapshot_manip.c
@@ -286,7 +286,6 @@ int vg_add_snapshot(struct logical_volume *origin,
int vg_remove_snapshot(struct logical_volume *cow)
{
- int merging_snapshot = 0;
struct logical_volume *origin = origin_from_cow(cow);
int is_origin_active = lv_is_active(origin);
@@ -315,17 +314,6 @@ int vg_remove_snapshot(struct logical_volume *cow)
* preload origin IFF "snapshot-merge" target is active
* - IMPORTANT: avoids preload if inactivate merge is pending
*/
- if (lv_has_target_type(origin->vg->vgmem, origin, NULL,
- TARGET_NAME_SNAPSHOT_MERGE)) {
- /*
- * preload origin to:
- * - allow proper release of -cow
- * - avoid allocations with other devices suspended
- * when transitioning from "snapshot-merge" to
- * "snapshot-origin after a merge completes.
- */
- merging_snapshot = 1;
- }
}
if (!lv_remove(cow->snapshot->lv)) {
@@ -356,7 +344,7 @@ int vg_remove_snapshot(struct logical_volume *cow)
* the LV lock on cluster has to be grabbed, so use
* activate_lv() which resumes suspend cow device.
*/
- if (!merging_snapshot && !activate_lv(cow->vg->cmd, cow)) {
+ if (!activate_lv(cow->vg->cmd, cow)) {
log_error("Failed to activate %s.", cow->name);
return 0;
}
@@ -365,11 +353,6 @@ int vg_remove_snapshot(struct logical_volume *cow)
log_error("Failed to resume %s.", origin->name);
return 0;
}
-
- if (merging_snapshot && !activate_lv(cow->vg->cmd, cow)) {
- log_error("Failed to activate %s.", cow->name);
- return 0;
- }
}
return 1;
4 years, 6 months
stable-2.02 - snapshot: fix checking of merged thin volume
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=8be8b994c6819343a13...
Commit: 8be8b994c6819343a13c547354507f6f89d837ca
Parent: 20d94e4072a93c199781e282d142ba7c80c9a437
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Oct 25 23:30:26 2019 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Sat Oct 26 00:41:40 2019 +0200
snapshot: fix checking of merged thin volume
When merging of thin snapshot is taking place, the origin target will
be of thin type.
---
lib/activate/activate.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index 561a965..f17be61 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -818,7 +818,8 @@ int lv_info_with_seg_status(struct cmd_context *cmd,
with_open_count, with_read_ahead))
return_0;
- if (status->seg_status.type == SEG_STATUS_SNAPSHOT) {
+ if (status->seg_status.type == SEG_STATUS_SNAPSHOT ||
+ (lv_is_thin_volume(olv) && (status->seg_status.type == SEG_STATUS_THIN))) {
log_debug_activation("Snapshot merge is in progress, querying status of %s instead.",
display_lvname(lv));
/*
4 years, 6 months