mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-03 05:18:29 +03:00
format_text: Refactor and document metadata offset calculation.
This commit is contained in:
parent
e932c5da50
commit
4002f5e206
@ -476,7 +476,9 @@ static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine offset for uncommitted metadata
|
* Find first aligned offset after end of existing metadata.
|
||||||
|
* Based on the alignment provided, this is the exact offset to use for the new metadata.
|
||||||
|
* The caller is responsible for validating the result.
|
||||||
*/
|
*/
|
||||||
static uint64_t _next_rlocn_offset(struct raw_locn *rlocn, struct mda_header *mdah, uint64_t mdac_area_start, uint64_t alignment)
|
static uint64_t _next_rlocn_offset(struct raw_locn *rlocn, struct mda_header *mdah, uint64_t mdac_area_start, uint64_t alignment)
|
||||||
{
|
{
|
||||||
@ -484,7 +486,7 @@ static uint64_t _next_rlocn_offset(struct raw_locn *rlocn, struct mda_header *md
|
|||||||
|
|
||||||
if (!rlocn)
|
if (!rlocn)
|
||||||
/* Find an empty slot */
|
/* Find an empty slot */
|
||||||
/* FIXME Assume only one VG per mdah for now */
|
/* FIXME Assumes only one VG per mdah for now */
|
||||||
return alignment;
|
return alignment;
|
||||||
|
|
||||||
/* Calculate new start position relative to start of buffer rounded up to absolute alignment */
|
/* Calculate new start position relative to start of buffer rounded up to absolute alignment */
|
||||||
@ -626,23 +628,28 @@ static int _metadata_fits_into_buffer(struct mda_context *mdac, struct mda_heade
|
|||||||
uint64_t old_wrap = 0; /* Amount of wrap around in existing metadata */
|
uint64_t old_wrap = 0; /* Amount of wrap around in existing metadata */
|
||||||
uint64_t new_end; /* The end location of the new metadata */
|
uint64_t new_end; /* The end location of the new metadata */
|
||||||
|
|
||||||
/* Do we have existing metadata that ends beyond the end of the buffer? */
|
/* Does the total amount of metadata, old and new, fit inside the buffer? */
|
||||||
if (rlocn && (rlocn->offset + rlocn->size > mdah->size))
|
if (MDA_HEADER_SIZE + (rlocn ? rlocn->size : 0) + mdac->rlocn.size >= mdah->size)
|
||||||
old_wrap = (rlocn->offset + rlocn->size) - mdah->size;
|
return_0;
|
||||||
|
|
||||||
new_end = new_wrap ? new_wrap + MDA_HEADER_SIZE :
|
/* Does the existing metadata wrap around the end of the buffer? */
|
||||||
mdac->rlocn.offset + mdac->rlocn.size;
|
if (rlocn) {
|
||||||
|
if (rlocn->offset + rlocn->size > mdah->size)
|
||||||
|
old_wrap = (rlocn->offset + rlocn->size) - mdah->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_end = new_wrap ? new_wrap + MDA_HEADER_SIZE : (mdac->rlocn.offset + mdac->rlocn.size);
|
||||||
|
|
||||||
/* If both wrap around, there's necessarily overlap */
|
/* If both wrap around, there's necessarily overlap */
|
||||||
if (new_wrap && old_wrap)
|
if (new_wrap && old_wrap)
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
/* If either wraps around, does the new end fall beyond the old start? */
|
/* If there's no existing metadata, we're OK */
|
||||||
if (rlocn && (new_wrap || old_wrap) && (new_end > rlocn->offset))
|
if (!rlocn)
|
||||||
return_0;
|
return 1;
|
||||||
|
|
||||||
/* Does the total amount of metadata, old and new, fit inside the buffer? */
|
/* If either wraps around, there's overlap if the new end falls beyond the old start */
|
||||||
if (MDA_HEADER_SIZE + (rlocn ? rlocn->size : 0) + mdac->rlocn.size >= mdah->size)
|
if ((new_wrap || old_wrap) && (new_end > rlocn->offset))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -658,6 +665,7 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
|
|||||||
struct pv_list *pvl;
|
struct pv_list *pvl;
|
||||||
int r = 0;
|
int r = 0;
|
||||||
uint64_t new_wrap; /* Number of bytes of new metadata that wrap around to start of buffer */
|
uint64_t new_wrap; /* Number of bytes of new metadata that wrap around to start of buffer */
|
||||||
|
uint64_t alignment = MDA_ORIGINAL_ALIGNMENT;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
int noprecommit = 0;
|
int noprecommit = 0;
|
||||||
const char *old_vg_name = NULL;
|
const char *old_vg_name = NULL;
|
||||||
@ -675,6 +683,12 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
|
|||||||
if (!found)
|
if (!found)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is paired with the following closes:
|
||||||
|
* - at the end of this fn if returning 0
|
||||||
|
* - in _vg_commit_raw_rlocn regardless of return code
|
||||||
|
* which handles commit (but not pre-commit) and revert.
|
||||||
|
*/
|
||||||
if (!dev_open(mdac->area.dev))
|
if (!dev_open(mdac->area.dev))
|
||||||
return_0;
|
return_0;
|
||||||
|
|
||||||
@ -692,8 +706,10 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
|
|||||||
|
|
||||||
mdac->rlocn.size = fidtc->raw_metadata_buf_size;
|
mdac->rlocn.size = fidtc->raw_metadata_buf_size;
|
||||||
|
|
||||||
mdac->rlocn.offset = _next_rlocn_offset(rlocn, mdah, mdac->area.start, MDA_ORIGINAL_ALIGNMENT);
|
/* Find where the new metadata would be written with our preferred alignment */
|
||||||
|
mdac->rlocn.offset = _next_rlocn_offset(rlocn, mdah, mdac->area.start, alignment);
|
||||||
|
|
||||||
|
/* Does the new metadata wrap around? */
|
||||||
if (mdac->rlocn.offset + mdac->rlocn.size > mdah->size)
|
if (mdac->rlocn.offset + mdac->rlocn.size > mdah->size)
|
||||||
new_wrap = (mdac->rlocn.offset + mdac->rlocn.size) - mdah->size;
|
new_wrap = (mdac->rlocn.offset + mdac->rlocn.size) - mdah->size;
|
||||||
else
|
else
|
||||||
@ -705,9 +721,9 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_debug_metadata("Writing %s metadata to %s at " FMTu64 " len " FMTu64 " of " FMTu64,
|
log_debug_metadata("Writing %s metadata to %s at " FMTu64 " len " FMTu64 " of " FMTu64 " aligned to " FMTu64,
|
||||||
vg->name, dev_name(mdac->area.dev), mdac->area.start +
|
vg->name, dev_name(mdac->area.dev), mdac->area.start +
|
||||||
mdac->rlocn.offset, mdac->rlocn.size - new_wrap, mdac->rlocn.size);
|
mdac->rlocn.offset, mdac->rlocn.size - new_wrap, mdac->rlocn.size, alignment);
|
||||||
|
|
||||||
/* Write text out, circularly */
|
/* Write text out, circularly */
|
||||||
if (!dev_write(mdac->area.dev, mdac->area.start + mdac->rlocn.offset,
|
if (!dev_write(mdac->area.dev, mdac->area.start + mdac->rlocn.offset,
|
||||||
@ -837,6 +853,7 @@ static int _vg_commit_raw_rlocn(struct format_instance *fid,
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
if (!precommit) {
|
if (!precommit) {
|
||||||
|
/* This is an paired with the open at the start of _vg_write_raw */
|
||||||
if (!dev_close(mdac->area.dev))
|
if (!dev_close(mdac->area.dev))
|
||||||
stack;
|
stack;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user