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)
|
||||
{
|
||||
@ -484,7 +486,7 @@ static uint64_t _next_rlocn_offset(struct raw_locn *rlocn, struct mda_header *md
|
||||
|
||||
if (!rlocn)
|
||||
/* Find an empty slot */
|
||||
/* FIXME Assume only one VG per mdah for now */
|
||||
/* FIXME Assumes only one VG per mdah for now */
|
||||
return 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 new_end; /* The end location of the new metadata */
|
||||
|
||||
/* Do we have existing metadata that ends beyond the end of the buffer? */
|
||||
if (rlocn && (rlocn->offset + rlocn->size > mdah->size))
|
||||
old_wrap = (rlocn->offset + rlocn->size) - mdah->size;
|
||||
/* Does the total amount of metadata, old and new, fit inside the buffer? */
|
||||
if (MDA_HEADER_SIZE + (rlocn ? rlocn->size : 0) + mdac->rlocn.size >= mdah->size)
|
||||
return_0;
|
||||
|
||||
new_end = new_wrap ? new_wrap + MDA_HEADER_SIZE :
|
||||
mdac->rlocn.offset + mdac->rlocn.size;
|
||||
/* Does the existing metadata wrap around the end of the buffer? */
|
||||
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 (new_wrap && old_wrap)
|
||||
return_0;
|
||||
|
||||
/* If either wraps around, does the new end fall beyond the old start? */
|
||||
if (rlocn && (new_wrap || old_wrap) && (new_end > rlocn->offset))
|
||||
return_0;
|
||||
/* If there's no existing metadata, we're OK */
|
||||
if (!rlocn)
|
||||
return 1;
|
||||
|
||||
/* Does the total amount of metadata, old and new, fit inside the buffer? */
|
||||
if (MDA_HEADER_SIZE + (rlocn ? rlocn->size : 0) + mdac->rlocn.size >= mdah->size)
|
||||
/* If either wraps around, there's overlap if the new end falls beyond the old start */
|
||||
if ((new_wrap || old_wrap) && (new_end > rlocn->offset))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
@ -658,6 +665,7 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
|
||||
struct pv_list *pvl;
|
||||
int r = 0;
|
||||
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 noprecommit = 0;
|
||||
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)
|
||||
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))
|
||||
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.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)
|
||||
new_wrap = (mdac->rlocn.offset + mdac->rlocn.size) - mdah->size;
|
||||
else
|
||||
@ -705,9 +721,9 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
|
||||
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 +
|
||||
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 */
|
||||
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:
|
||||
if (!precommit) {
|
||||
/* This is an paired with the open at the start of _vg_write_raw */
|
||||
if (!dev_close(mdac->area.dev))
|
||||
stack;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user