summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZdenek Kabelac <zkabelac@redhat.com>2020-01-30 15:23:47 +0100
committerZdenek Kabelac <zkabelac@redhat.com>2020-02-04 17:22:06 +0100
commit409362c127222640cd2d1fe3e1b62b50867741c1 (patch)
tree8b4f0758503d76e5f98fa90fb336c7534f8a491b
parente6a3c0901703bf98827e2da456daf0ced42dd96c (diff)
downloadlvm2-409362c127222640cd2d1fe3e1b62b50867741c1.tar.gz
lv_manip: add error handling for _reserve_area
Since _reserve_area() may fail due to error allocation failure, add support to report this already reported failure upward. FIXME: it's log_error() without causing direct command failure.
-rw-r--r--lib/metadata/lv_manip.c29
1 files changed, 19 insertions, 10 deletions
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index b4daa5633..ad9c756f6 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -2428,20 +2428,22 @@ static int _is_contiguous(struct pv_match *pvmatch __attribute((unused)), struct
return 1;
}
-static void _reserve_area(struct alloc_handle *ah, struct alloc_state *alloc_state, struct pv_area *pva,
+static int _reserve_area(struct alloc_handle *ah, struct alloc_state *alloc_state, struct pv_area *pva,
uint32_t required, uint32_t ix_pva, uint32_t unreserved)
{
struct pv_area_used *area_used = &alloc_state->areas[ix_pva];
const char *pv_tag_list = NULL;
if (ah->cling_tag_list_cn) {
- if (!dm_pool_begin_object(ah->mem, 256))
- log_error("PV tags string allocation failed");
- else if (!_tags_list_str(ah->mem, pva->map->pv, ah->cling_tag_list_cn))
+ if (!dm_pool_begin_object(ah->mem, 256)) {
+ log_error("PV tags string allocation failed.");
+ return 0;
+ } else if (!_tags_list_str(ah->mem, pva->map->pv, ah->cling_tag_list_cn))
dm_pool_abandon_object(ah->mem);
else if (!dm_pool_grow_object(ah->mem, "\0", 1)) {
dm_pool_abandon_object(ah->mem);
log_error("PV tags string extension failed.");
+ return 0;
} else
pv_tag_list = dm_pool_end_object(ah->mem);
}
@@ -2459,25 +2461,30 @@ static void _reserve_area(struct alloc_handle *ah, struct alloc_state *alloc_sta
area_used->pva = pva;
area_used->used = required;
+
+ return 1;
}
static int _reserve_required_area(struct alloc_handle *ah, struct alloc_state *alloc_state, struct pv_area *pva,
uint32_t required, uint32_t ix_pva, uint32_t unreserved)
{
uint32_t s;
+ struct pv_area_used *new_state;
/* Expand areas array if needed after an area was split. */
if (ix_pva >= alloc_state->areas_size) {
alloc_state->areas_size *= 2;
- if (!(alloc_state->areas = realloc(alloc_state->areas, sizeof(*alloc_state->areas) * (alloc_state->areas_size)))) {
+ if (!(new_state = realloc(alloc_state->areas, sizeof(*alloc_state->areas) * (alloc_state->areas_size)))) {
log_error("Memory reallocation for parallel areas failed.");
return 0;
}
+ alloc_state->areas = new_state;
for (s = alloc_state->areas_size / 2; s < alloc_state->areas_size; s++)
alloc_state->areas[s].pva = NULL;
}
- _reserve_area(ah, alloc_state, pva, required, ix_pva, unreserved);
+ if (!_reserve_area(ah, alloc_state, pva, required, ix_pva, unreserved))
+ return_0;
return 1;
}
@@ -2506,8 +2513,9 @@ static int _is_condition(struct cmd_context *cmd __attribute__((unused)),
* Only used for cling and contiguous policies (which only make one allocation per PV)
* so it's safe to say all the available space is used.
*/
- if (positional)
- _reserve_required_area(pvmatch->ah, pvmatch->alloc_state, pvmatch->pva, pvmatch->pva->count, s, 0);
+ if (positional &&
+ !_reserve_required_area(pvmatch->ah, pvmatch->alloc_state, pvmatch->pva, pvmatch->pva->count, s, 0))
+ return_0;
return 2; /* Finished */
}
@@ -2604,8 +2612,9 @@ static int _check_cling_to_alloced(struct alloc_handle *ah, const struct dm_conf
dm_list_iterate_items(aa, &ah->alloced_areas[s]) {
if ((!cling_tag_list_cn && (pva->map->pv == aa[0].pv)) ||
(cling_tag_list_cn && _pvs_have_matching_tag(cling_tag_list_cn, pva->map->pv, aa[0].pv, 0))) {
- if (positional)
- _reserve_required_area(ah, alloc_state, pva, pva->count, s, 0);
+ if (positional &&
+ !_reserve_required_area(ah, alloc_state, pva, pva->count, s, 0))
+ return_0;
return 1;
}
}