summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPeter Rajnoha <prajnoha@redhat.com>2015-03-23 13:32:00 +0100
committerPeter Rajnoha <prajnoha@redhat.com>2015-03-24 08:43:08 +0100
commit8759f7d755cec7286d1bccda3a323b12481d5738 (patch)
tree535eb0bcd4fffbf0396ea84441666ff0e5e4a803 /lib
parentc9f021de0b4d2c873ef5b97d17c602d0380359fd (diff)
downloadlvm2-8759f7d755cec7286d1bccda3a323b12481d5738.tar.gz
metadata: vg: add removed_lvs field to collect LVs which have been removed
Do not keep dangling LVs if they're removed from the vg->lvs list and move them to vg->removed_lvs instead (this is actually similar to already existing vg->removed_pvs list, just it's for LVs now). Once we have this vg->removed_lvs list indexed so it's possible to do lookups for LVs quickly, we can remove the LV_REMOVED flag as that one won't be needed anymore - instead of checking the flag, we can directly check the vg->removed_lvs list if the LV is present there or not and to say if the LV is removed or not then. For now, we don't have this index, but it may be implemented in the future.
Diffstat (limited to 'lib')
-rw-r--r--lib/metadata/lv_manip.c2
-rw-r--r--lib/metadata/metadata-exported.h2
-rw-r--r--lib/metadata/metadata.c14
-rw-r--r--lib/metadata/vg.c1
-rw-r--r--lib/metadata/vg.h5
5 files changed, 23 insertions, 1 deletions
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index b9cd056d2..99fb91f49 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -5350,7 +5350,7 @@ int unlink_lv_from_vg(struct logical_volume *lv)
if (!(lvl = find_lv_in_vg(lv->vg, lv->name)))
return_0;
- dm_list_del(&lvl->list);
+ dm_list_move(&lv->vg->removed_lvs, &lvl->list);
lv->status |= LV_REMOVED;
return 1;
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 75cd94f22..47fb9ae56 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -125,6 +125,8 @@
be referenced on internal lists of LVs.
Any remaining references should check for
this flag and ignore the LV is set.
+ FIXME: Remove this flag once we have indexed
+ vg->removed_lvs for quick lookup.
*/
#define LV_ERROR_WHEN_FULL UINT64_C(0x0008000000000000) /* LV - error when full */
#define PV_ALLOCATION_PROHIBITED UINT64_C(0x0010000000000000) /* PV - internal use only - allocation prohibited
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 33ce3708d..a1a31eb27 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -2568,12 +2568,26 @@ int vg_validate(struct volume_group *vg)
r = 0;
}
+ dm_list_iterate_items(lvl, &vg->removed_lvs) {
+ if (!(lvl->lv->status & LV_REMOVED)) {
+ log_error(INTERNAL_ERROR "LV %s is not marked as removed while it's part "
+ "of removed LV list for VG %s", lvl->lv->name, vg->name);
+ r = 0;
+ }
+ }
+
/*
* Count all non-snapshot invisible LVs
*/
dm_list_iterate_items(lvl, &vg->lvs) {
lv_count++;
+ if (lvl->lv->status & LV_REMOVED) {
+ log_error(INTERNAL_ERROR "LV %s is marked as removed while it's "
+ "still part of the VG %s", lvl->lv->name, vg->name);
+ r = 0;
+ }
+
if (lvl->lv->status & LVM_WRITE_LOCKED) {
log_error(INTERNAL_ERROR "LV %s has external flag LVM_WRITE_LOCKED set internally.",
lvl->lv->name);
diff --git a/lib/metadata/vg.c b/lib/metadata/vg.c
index 404cc6fa6..c9a7e9e1b 100644
--- a/lib/metadata/vg.c
+++ b/lib/metadata/vg.c
@@ -63,6 +63,7 @@ struct volume_group *alloc_vg(const char *pool_name, struct cmd_context *cmd,
dm_list_init(&vg->pvs_to_create);
dm_list_init(&vg->lvs);
dm_list_init(&vg->tags);
+ dm_list_init(&vg->removed_lvs);
dm_list_init(&vg->removed_pvs);
log_debug_mem("Allocated VG %s at %p.", vg->name, vg);
diff --git a/lib/metadata/vg.h b/lib/metadata/vg.h
index 67a04a05f..b0ab12217 100644
--- a/lib/metadata/vg.h
+++ b/lib/metadata/vg.h
@@ -113,6 +113,11 @@ struct volume_group {
*/
/*
+ * List of removed logical volumes by _lv_reduce.
+ */
+ struct dm_list removed_lvs;
+
+ /*
* List of removed physical volumes by pvreduce.
* They have to get cleared on vg_commit.
*/