summaryrefslogtreecommitdiff
path: root/lib/metadata
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2021-05-24 16:08:27 -0500
committerDavid Teigland <teigland@redhat.com>2021-05-24 16:09:35 -0500
commit4a746f7ffcc8e61c9cb5ce9f9e8a061d1ef6b28e (patch)
tree3996e93ccbb0d356b6948714dcf16ed6dd8931a1 /lib/metadata
parenta65f8e0a62b9ab3c2fc909a63abfa0e933619a8c (diff)
downloadlvm2-4a746f7ffcc8e61c9cb5ce9f9e8a061d1ef6b28e.tar.gz
lvremove: fix removing thin pool with writecache on data
Diffstat (limited to 'lib/metadata')
-rw-r--r--lib/metadata/lv_manip.c19
-rw-r--r--lib/metadata/metadata-exported.h2
-rw-r--r--lib/metadata/thin_manip.c12
3 files changed, 33 insertions, 0 deletions
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 508f78c13..37dd3611d 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -6692,6 +6692,25 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
return_0;
}
+ /* if thin pool data lv is writecache, then detach and remove the writecache */
+ if (lv_is_thin_pool(lv)) {
+ struct logical_volume *data_lv = data_lv_from_thin_pool(lv);
+
+ if (data_lv && lv_is_writecache(data_lv)) {
+ struct logical_volume *cachevol_lv = first_seg(data_lv)->writecache;
+
+ if (!lv_detach_writecache_cachevol(data_lv, 1)) {
+ log_error("Failed to detach writecache from %s", display_lvname(data_lv));
+ return 0;
+ }
+
+ if (!lv_remove_single(cmd, cachevol_lv, force, 1)) {
+ log_error("Failed to remove cachevol %s.", display_lvname(cachevol_lv));
+ return 0;
+ }
+ }
+ }
+
if (lv_is_writecache(lv)) {
struct logical_volume *cachevol_lv = first_seg(lv)->writecache;
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 52062a100..9ac3c677e 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -928,6 +928,8 @@ int handle_pool_metadata_spare(struct volume_group *vg, uint32_t extents,
int vg_set_pool_metadata_spare(struct logical_volume *lv);
int vg_remove_pool_metadata_spare(struct volume_group *vg);
+struct logical_volume *data_lv_from_thin_pool(struct logical_volume *pool_lv);
+
int attach_thin_external_origin(struct lv_segment *seg,
struct logical_volume *external_lv);
int detach_thin_external_origin(struct lv_segment *seg);
diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c
index 451c38260..6ce88bd3d 100644
--- a/lib/metadata/thin_manip.c
+++ b/lib/metadata/thin_manip.c
@@ -21,6 +21,18 @@
#include "lib/config/defaults.h"
#include "lib/display/display.h"
+struct logical_volume *data_lv_from_thin_pool(struct logical_volume *pool_lv)
+{
+ struct lv_segment *seg_thinpool = first_seg(pool_lv);
+
+ if (!seg_thinpool || !seg_is_thin_pool(seg_thinpool)) {
+ log_error(INTERNAL_ERROR "data_lv_from_thin_pool arg not thin pool %s", pool_lv->name);
+ return NULL;
+ }
+
+ return seg_thinpool->areas[0].u.lv.lv;
+}
+
/* TODO: drop unused no_update */
int attach_pool_message(struct lv_segment *pool_seg, dm_thin_message_t type,
struct logical_volume *lv, uint32_t delete_id,