mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
raid_manip: v2 fix multi-segment misallocation on 'lvconvert --repair'
The previous patch felt short WRT disabling allocation on PVs holding other legs of the RAID LV persistently; this patch introduces an internal, transient PV flag PV_ALLOCATION_PROHIBITED to address this very problem. General problem description for completeness: An 'lvconvert --repair $RAID_LV" to replace a failed leg of a multi-segment RAID10/4/5/6 logical volume can lead to allocation of (parts of) the replacement image component pair on the physical volume of another image component (e.g. image 0 allocated on the same PV as image 1 silently impeding resilience). Patch fixes this severe resilince issue by prohibiting allocation on PVs already holding other legs of the RAID set. It allows to allocate free space on any operational PV already holding parts of the image component pair.
This commit is contained in:
parent
0bcc0cf95d
commit
302b6c99a7
@ -119,8 +119,10 @@
|
|||||||
|
|
||||||
#define LV_PENDING_DELETE UINT64_C(0x0004000000000000) /* LV - Internal use only */
|
#define LV_PENDING_DELETE UINT64_C(0x0004000000000000) /* LV - Internal use only */
|
||||||
#define LV_ERROR_WHEN_FULL UINT64_C(0x0008000000000000) /* LV - error when full */
|
#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
|
||||||
/* Next unused flag: UINT64_C(0x0010000000000000) */
|
e.g. to prohibit allocation of a RAID image
|
||||||
|
on a PV already holing an image of the RAID set */
|
||||||
|
/* Next unused flag: UINT64_C(0x0020000000000000) */
|
||||||
|
|
||||||
/* Format features flags */
|
/* Format features flags */
|
||||||
#define FMT_SEGMENTS 0x00000001U /* Arbitrary segment params? */
|
#define FMT_SEGMENTS 0x00000001U /* Arbitrary segment params? */
|
||||||
|
@ -133,8 +133,11 @@ static int _create_maps(struct dm_pool *mem, struct dm_list *pvs, struct dm_list
|
|||||||
struct pv_list *pvl;
|
struct pv_list *pvl;
|
||||||
|
|
||||||
dm_list_iterate_items(pvl, pvs) {
|
dm_list_iterate_items(pvl, pvs) {
|
||||||
if (!(pvl->pv->status & ALLOCATABLE_PV))
|
if (!(pvl->pv->status & ALLOCATABLE_PV) ||
|
||||||
|
(pvl->pv->status & PV_ALLOCATION_PROHIBITED)) {
|
||||||
|
pvl->pv->status &= ~PV_ALLOCATION_PROHIBITED;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (is_missing_pv(pvl->pv))
|
if (is_missing_pv(pvl->pv))
|
||||||
continue;
|
continue;
|
||||||
assert(pvl->pv->dev);
|
assert(pvl->pv->dev);
|
||||||
|
@ -1553,14 +1553,15 @@ static int _avoid_pvs_of_lv(struct logical_volume *lv, void *data)
|
|||||||
dm_list_iterate_items(pvl, allocate_pvs)
|
dm_list_iterate_items(pvl, allocate_pvs)
|
||||||
if (!(lv->status & PARTIAL_LV) &&
|
if (!(lv->status & PARTIAL_LV) &&
|
||||||
lv_is_on_pv(lv, pvl->pv))
|
lv_is_on_pv(lv, pvl->pv))
|
||||||
pvl->pv->status &= ~ALLOCATABLE_PV;
|
pvl->pv->status |= PV_ALLOCATION_PROHIBITED;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prevent any PVs holding other image components of @lv from being used for allocation,
|
* Prevent any PVs holding other image components of @lv from being used for allocation
|
||||||
* I.e. reset ALLOCATABLE_PV on respective PVs listed on @allocatable_pvs
|
* by setting the internal PV_ALLOCATION_PROHIBITED flag to use it to avoid generating
|
||||||
|
* pv maps for those PVs.
|
||||||
*/
|
*/
|
||||||
static void _avoid_pvs_with_other_images_of_lv(struct logical_volume *lv, struct dm_list *allocate_pvs)
|
static void _avoid_pvs_with_other_images_of_lv(struct logical_volume *lv, struct dm_list *allocate_pvs)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user