diff options
author | Zdenek Kabelac <zkabelac@redhat.com> | 2016-11-08 11:54:28 +0100 |
---|---|---|
committer | Zdenek Kabelac <zkabelac@redhat.com> | 2016-11-08 16:00:14 +0100 |
commit | ada5733c5652d456ffa138b0d07e6897824813b0 (patch) | |
tree | 28bff709d7a2ede44f6fd1cbf4c8c861789b9394 | |
parent | 9e03fc3c2ac682b4edc9a91eea7256e272a5bd71 (diff) | |
download | lvm2-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_NEW | 1 | ||||
-rw-r--r-- | lib/metadata/lv_manip.c | 78 |
2 files changed, 48 insertions, 31 deletions
@@ -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; |