mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
lv_manip: enhance for_each_sub_lv
Fix missing 'externalLV' traversing for thins with external origins. Replace extra for_each_sub_lv_except_pools() with better internal logic allowing selectively to cut of processed subLV tree. Extend error code for function 'fn()' when it returns -1 it will stop futher tree scan for given LV. Also a bit simplify code to have only one place that is calling 'fn()' and use level counter to know depth of traversing. Update renaming travering to skip trees for pools and external origins.
This commit is contained in:
parent
6b48868cf0
commit
bc1adc32cb
@ -1,5 +1,6 @@
|
||||
Version 2.02.178 -
|
||||
=====================================
|
||||
Add external_origin visiting in for_each_sub_lv().
|
||||
Ensure cluster commands drop their device cache before locking VG.
|
||||
Do not report LV as remotely active when it's locally exclusive in cluster.
|
||||
Add deprecate messages for usage of mirrors with mirrorlog.
|
||||
|
@ -4341,53 +4341,62 @@ static int _rename_cb(struct logical_volume *lv, void *data)
|
||||
return _rename_sub_lv(lv, lv_names->old, lv_names->new);
|
||||
}
|
||||
|
||||
static int _rename_skip_pools_externals_cb(struct logical_volume *lv, void *data)
|
||||
{
|
||||
if (lv_is_pool(lv) || lv_is_external_origin(lv))
|
||||
return -1; /* and skip subLVs */
|
||||
|
||||
return _rename_cb(lv, data);
|
||||
}
|
||||
|
||||
/*
|
||||
* Loop down sub LVs and call fn for each.
|
||||
* fn is responsible to log necessary information on failure.
|
||||
* Return value '0' stops whole traversal.
|
||||
* Return value '-1' stops subtree traversal.
|
||||
*/
|
||||
static int _for_each_sub_lv(struct logical_volume *lv, int skip_pools,
|
||||
static int _for_each_sub_lv(struct logical_volume *lv, int level,
|
||||
int (*fn)(struct logical_volume *lv, void *data),
|
||||
void *data)
|
||||
{
|
||||
struct logical_volume *org;
|
||||
struct lv_segment *seg;
|
||||
uint32_t s;
|
||||
int r;
|
||||
|
||||
if (!lv)
|
||||
return 1;
|
||||
|
||||
if (level++) {
|
||||
if (!(r = fn(lv, data)))
|
||||
return_0;
|
||||
/* Only r == 1 lets you run for_each... */
|
||||
if (r == -1)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (lv_is_cow(lv) && lv_is_virtual_origin(org = origin_from_cow(lv))) {
|
||||
if (!fn(org, data))
|
||||
return_0;
|
||||
if (!_for_each_sub_lv(org, skip_pools, fn, data))
|
||||
if (!_for_each_sub_lv(org, level, fn, data))
|
||||
return_0;
|
||||
}
|
||||
|
||||
dm_list_iterate_items(seg, &lv->segments) {
|
||||
if (seg->log_lv) {
|
||||
if (!fn(seg->log_lv, data))
|
||||
return_0;
|
||||
if (!_for_each_sub_lv(seg->log_lv, skip_pools, fn, data))
|
||||
return_0;
|
||||
}
|
||||
if (!_for_each_sub_lv(seg->external_lv, level, fn, data))
|
||||
return_0;
|
||||
|
||||
if (seg->metadata_lv) {
|
||||
if (!fn(seg->metadata_lv, data))
|
||||
return_0;
|
||||
if (!_for_each_sub_lv(seg->metadata_lv, skip_pools, fn, data))
|
||||
return_0;
|
||||
}
|
||||
if (!_for_each_sub_lv(seg->log_lv, level, fn, data))
|
||||
return_0;
|
||||
|
||||
if (seg->pool_lv && !skip_pools) {
|
||||
if (!fn(seg->pool_lv, data))
|
||||
return_0;
|
||||
if (!_for_each_sub_lv(seg->pool_lv, skip_pools, fn, data))
|
||||
return_0;
|
||||
}
|
||||
if (!_for_each_sub_lv(seg->metadata_lv, level, fn, data))
|
||||
return_0;
|
||||
|
||||
if (!_for_each_sub_lv(seg->pool_lv, level, fn, data))
|
||||
return_0;
|
||||
|
||||
for (s = 0; s < seg->area_count; s++) {
|
||||
if (seg_type(seg, s) != AREA_LV)
|
||||
continue;
|
||||
if (!fn(seg_lv(seg, s), data))
|
||||
return_0;
|
||||
if (!_for_each_sub_lv(seg_lv(seg, s), skip_pools, fn, data))
|
||||
if (!_for_each_sub_lv(seg_lv(seg, s), level, fn, data))
|
||||
return_0;
|
||||
}
|
||||
|
||||
@ -4398,9 +4407,7 @@ static int _for_each_sub_lv(struct logical_volume *lv, int skip_pools,
|
||||
for (s = 0; s < seg->area_count; s++) {
|
||||
if ((seg_metatype(seg, s) != AREA_LV) || !seg_metalv(seg, s))
|
||||
continue;
|
||||
if (!fn(seg_metalv(seg, s), data))
|
||||
return_0;
|
||||
if (!_for_each_sub_lv(seg_metalv(seg, s), skip_pools, fn, data))
|
||||
if (!_for_each_sub_lv(seg_metalv(seg, s), level, fn, data))
|
||||
return_0;
|
||||
}
|
||||
}
|
||||
@ -4415,13 +4422,6 @@ int for_each_sub_lv(struct logical_volume *lv,
|
||||
return _for_each_sub_lv(lv, 0, fn, data);
|
||||
}
|
||||
|
||||
int for_each_sub_lv_except_pools(struct logical_volume *lv,
|
||||
int (*fn)(struct logical_volume *lv, void *data),
|
||||
void *data)
|
||||
{
|
||||
return _for_each_sub_lv(lv, 1, fn, data);
|
||||
}
|
||||
|
||||
/*
|
||||
* Core of LV renaming routine.
|
||||
* VG must be locked by caller.
|
||||
@ -4475,7 +4475,7 @@ int lv_rename_update(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
}
|
||||
|
||||
/* rename sub LVs */
|
||||
if (!for_each_sub_lv_except_pools(lv, _rename_cb, (void *) &lv_names))
|
||||
if (!for_each_sub_lv(lv, _rename_skip_pools_externals_cb, (void *) &lv_names))
|
||||
return_0;
|
||||
|
||||
/* rename main LV */
|
||||
|
@ -444,9 +444,6 @@ int add_glv_to_indirect_glvs(struct dm_pool *mem,
|
||||
int remove_glv_from_indirect_glvs(struct generic_logical_volume *origin_glv,
|
||||
struct generic_logical_volume *glv);
|
||||
|
||||
int for_each_sub_lv_except_pools(struct logical_volume *lv,
|
||||
int (*fn)(struct logical_volume *lv, void *data),
|
||||
void *data);
|
||||
int for_each_sub_lv(struct logical_volume *lv,
|
||||
int (*fn)(struct logical_volume *lv, void *data),
|
||||
void *data);
|
||||
|
Loading…
Reference in New Issue
Block a user