diff options
author | David Teigland <teigland@redhat.com> | 2021-05-24 16:08:27 -0500 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2021-05-24 16:09:35 -0500 |
commit | 4a746f7ffcc8e61c9cb5ce9f9e8a061d1ef6b28e (patch) | |
tree | 3996e93ccbb0d356b6948714dcf16ed6dd8931a1 /lib/metadata | |
parent | a65f8e0a62b9ab3c2fc909a63abfa0e933619a8c (diff) | |
download | lvm2-4a746f7ffcc8e61c9cb5ce9f9e8a061d1ef6b28e.tar.gz |
lvremove: fix removing thin pool with writecache on data
Diffstat (limited to 'lib/metadata')
-rw-r--r-- | lib/metadata/lv_manip.c | 19 | ||||
-rw-r--r-- | lib/metadata/metadata-exported.h | 2 | ||||
-rw-r--r-- | lib/metadata/thin_manip.c | 12 |
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, |