summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZdenek Kabelac <zkabelac@redhat.com>2016-11-08 11:54:28 +0100
committerZdenek Kabelac <zkabelac@redhat.com>2016-11-08 16:00:14 +0100
commitada5733c5652d456ffa138b0d07e6897824813b0 (patch)
tree28bff709d7a2ede44f6fd1cbf4c8c861789b9394
parent9e03fc3c2ac682b4edc9a91eea7256e272a5bd71 (diff)
downloadlvm2-ada5733c5652d456ffa138b0d07e6897824813b0.tar.gz
raid: faster rmeta clearing
Instead of clearing multiple rmeta device with sequential activation process and waiting for udev for every _rmeta device separately, activate all _rmeta devices first and then clear them and deactivate afterwards. Also update some tracing messages. When anyhing goes wrong during clearing process, always try to deactivate as much _rmeta devices as possible before fail.
-rw-r--r--WHATS_NEW1
-rw-r--r--lib/metadata/lv_manip.c78
2 files changed, 48 insertions, 31 deletions
diff --git a/WHATS_NEW b/WHATS_NEW
index 2e954923f..17fbdc092 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.168 -
====================================
+ More efficiently prepare _rmeta devices when creating a new raid LV.
Version 2.02.167 - 5th November 2016
====================================
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 5adf81e0b..06430006e 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -3844,6 +3844,7 @@ static int _lv_extend_layered_lv(struct alloc_handle *ah,
uint32_t fa, s;
int clear_metadata = 0;
uint32_t area_multiple = 1;
+ int fail;
if (!(segtype = get_segtype_from_string(lv->vg->cmd, SEG_TYPE_NAME_STRIPED)))
return_0;
@@ -3917,45 +3918,60 @@ static int _lv_extend_layered_lv(struct alloc_handle *ah,
if (!vg_write(lv->vg) || !vg_commit(lv->vg))
return_0;
- for (s = 0; s < seg->area_count; s++) {
- meta_lv = seg_metalv(seg, s);
-
- if (test_mode()) {
- lv_set_hidden(meta_lv);
- continue;
+ if (test_mode())
+ log_verbose("Test mode: Skipping wiping of metadata areas.");
+ else {
+ fail = 0;
+ /* Activate all rmeta devices locally first (more efficient) */
+ for (s = 0; !fail && s < seg->area_count; s++) {
+ meta_lv = seg_metalv(seg, s);
+
+ if (!activate_lv_local(meta_lv->vg->cmd, meta_lv)) {
+ log_error("Failed to activate %s for clearing.",
+ display_lvname(meta_lv));
+ fail = 1;
+ }
}
- /* For clearing, simply activate locally */
- if (!activate_lv_local(meta_lv->vg->cmd, meta_lv)) {
- log_error("Failed to activate %s/%s for clearing",
- meta_lv->vg->name, meta_lv->name);
- return 0;
- }
+ /* Clear all rmeta devices */
+ for (s = 0; !fail && s < seg->area_count; s++) {
+ meta_lv = seg_metalv(seg, s);
- log_verbose("Clearing metadata area of %s",
- display_lvname(meta_lv));
- /*
- * Rather than wiping meta_lv->size, we can simply
- * wipe '1' to remove the superblock of any previous
- * RAID devices. It is much quicker.
- */
- if (!wipe_lv(meta_lv, (struct wipe_params)
- { .do_zero = 1, .zero_sectors = 1 })) {
- log_error("Failed to zero %s/%s",
- meta_lv->vg->name, meta_lv->name);
- return 0;
+ log_verbose("Clearing metadata area of %s.",
+ display_lvname(meta_lv));
+ /*
+ * Rather than wiping meta_lv->size, we can simply
+ * wipe '1' to remove the superblock of any previous
+ * RAID devices. It is much quicker.
+ */
+ if (!wipe_lv(meta_lv, (struct wipe_params)
+ { .do_zero = 1, .zero_sectors = 1 })) {
+ stack;
+ fail = 1;
+ }
}
- if (!deactivate_lv(meta_lv->vg->cmd, meta_lv)) {
- log_error("Failed to deactivate %s/%s",
- meta_lv->vg->name, meta_lv->name);
- return 0;
+ /* Deactivate all rmeta devices */
+ for (s = 0; s < seg->area_count; s++) {
+ meta_lv = seg_metalv(seg, s);
+
+ if (!deactivate_lv(meta_lv->vg->cmd, meta_lv)) {
+ log_error("Failed to deactivate %s after clearing.",
+ display_lvname(meta_lv));
+ fail = 1;
+ }
+
+ /* Wipe any temporary tags required for activation. */
+ str_list_wipe(&meta_lv->tags);
}
- lv_set_hidden(meta_lv);
- /* Wipe any temporary tags required for activation. */
- str_list_wipe(&meta_lv->tags);
+ if (fail)
+ /* Fail, after trying to deactivate all we could */
+ return_0;
}
+
+ for (s = 0; s < seg->area_count; s++)
+ lv_set_hidden(seg_metalv(seg, s));
}
seg->area_len += extents / area_multiple;