1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-22 17:35:59 +03:00

format_text: Split vgname_from_mda into three pieces.

This commit is contained in:
Alasdair G Kergon 2018-01-04 21:13:44 +00:00
parent d61b1369d0
commit c70c9f6565

View File

@ -1328,16 +1328,118 @@ static int _scan_file(const struct format_type *fmt, const char *vgname)
return 1; return 1;
} }
struct vgname_from_mda_params{
const struct format_type *fmt;
struct mda_header *mdah;
struct device_area *dev_area;
int primary_mda;
struct lvmcache_vgsummary *vgsummary;
uint64_t *mda_free_sectors;
uint32_t wrap;
unsigned used_cached_metadata;
};
static int _vgname_from_mda_process(struct vgname_from_mda_params *vfmp)
{
struct mda_header *mdah = vfmp->mdah;
struct device_area *dev_area = vfmp->dev_area;
struct lvmcache_vgsummary *vgsummary = vfmp->vgsummary;
uint64_t *mda_free_sectors = vfmp->mda_free_sectors;
struct raw_locn *rlocn = mdah->raw_locns;
uint64_t buffer_size, current_usage;
int r = 0;
/* Ignore this entry if the characters aren't permissible */
if (!validate_name(vgsummary->vgname))
goto_out;
log_debug_metadata("%s: %s metadata at " FMTu64 " size " FMTu64 " with wrap " FMTu32
" (in area at " FMTu64 " size " FMTu64
") for %s (" FMTVGID ")",
dev_name(dev_area->dev),
vfmp->used_cached_metadata ? "Using cached" : "Found",
dev_area->start + rlocn->offset,
rlocn->size, vfmp->wrap, dev_area->start, dev_area->size, vgsummary->vgname,
(char *)&vgsummary->vgid);
if (mda_free_sectors) {
current_usage = ALIGN_ABSOLUTE(rlocn->size, dev_area->start + rlocn->offset, MDA_ALIGNMENT);
buffer_size = mdah->size - MDA_HEADER_SIZE;
if (current_usage * 2 >= buffer_size)
*mda_free_sectors = UINT64_C(0);
else
*mda_free_sectors = ((buffer_size - 2 * current_usage) / 2) >> SECTOR_SHIFT;
}
r = 1;
out:
return r;
}
static int _vgname_from_mda_validate(struct vgname_from_mda_params *vfmp, char *buffer)
{
const struct format_type *fmt = vfmp->fmt;
struct mda_header *mdah = vfmp->mdah;
struct device_area *dev_area = vfmp->dev_area;
struct lvmcache_vgsummary *vgsummary = vfmp->vgsummary;
struct raw_locn *rlocn = mdah->raw_locns;
unsigned len = 0;
char buf[NAME_LEN + 1] __attribute__((aligned(8)));
memcpy(buf, buffer, NAME_LEN + 1);
while (buf[len] && !isspace(buf[len]) && buf[len] != '{' &&
len < (NAME_LEN - 1))
len++;
buf[len] = '\0';
/* Ignore this entry if the characters aren't permissible */
if (!validate_name(buf))
goto_out;
/* We found a VG - now check the metadata */
if (rlocn->offset + rlocn->size > mdah->size)
vfmp->wrap = (uint32_t) ((rlocn->offset + rlocn->size) - mdah->size);
if (vfmp->wrap > rlocn->offset) {
log_error("%s: metadata (" FMTu64 " bytes) too large for circular buffer (" FMTu64 " bytes)",
dev_name(dev_area->dev), rlocn->size, mdah->size - MDA_HEADER_SIZE);
goto out;
}
/* Did we see this metadata before? */
vgsummary->mda_checksum = rlocn->checksum;
vgsummary->mda_size = rlocn->size;
if (lvmcache_lookup_mda(vgsummary))
vfmp->used_cached_metadata = 1;
/* FIXME 64-bit */
if (!text_vgsummary_import(fmt, dev_area->dev, MDA_CONTENT_REASON(vfmp->primary_mda),
(off_t) (dev_area->start + rlocn->offset),
(uint32_t) (rlocn->size - vfmp->wrap),
(off_t) (dev_area->start + MDA_HEADER_SIZE),
vfmp->wrap, calc_crc, vgsummary->vgname ? 1 : 0,
vgsummary))
goto_out;
return _vgname_from_mda_process(vfmp);
out:
return 0;
}
int vgname_from_mda(const struct format_type *fmt, int vgname_from_mda(const struct format_type *fmt,
struct mda_header *mdah, int primary_mda, struct device_area *dev_area, struct mda_header *mdah, int primary_mda, struct device_area *dev_area,
struct lvmcache_vgsummary *vgsummary, uint64_t *mda_free_sectors) struct lvmcache_vgsummary *vgsummary, uint64_t *mda_free_sectors)
{ {
struct raw_locn *rlocn; struct raw_locn *rlocn;
uint32_t wrap = 0;
unsigned int len = 0;
char buf[NAME_LEN + 1] __attribute__((aligned(8))); char buf[NAME_LEN + 1] __attribute__((aligned(8)));
uint64_t buffer_size, current_usage; struct vgname_from_mda_params *vfmp;
unsigned used_cached_metadata = 0;
if (mda_free_sectors) if (mda_free_sectors)
*mda_free_sectors = ((dev_area->size - MDA_HEADER_SIZE) / 2) >> SECTOR_SHIFT; *mda_free_sectors = ((dev_area->size - MDA_HEADER_SIZE) / 2) >> SECTOR_SHIFT;
@ -1359,72 +1461,25 @@ int vgname_from_mda(const struct format_type *fmt,
return 0; return 0;
} }
if (!(vfmp = dm_pool_zalloc(fmt->cmd->mem, sizeof(*vfmp)))) {
log_error("vgname_from_mda_params allocation failed");
return 0;
}
vfmp->fmt = fmt;
vfmp->mdah = mdah;
vfmp->dev_area = dev_area;
vfmp->vgsummary = vgsummary;
vfmp->primary_mda = primary_mda;
vfmp->mda_free_sectors = mda_free_sectors;
/* Do quick check for a vgname */ /* Do quick check for a vgname */
/* We cannot read the full metadata here because the name has to be validated before we use the size field */
if (!dev_read_buf(dev_area->dev, dev_area->start + rlocn->offset, if (!dev_read_buf(dev_area->dev, dev_area->start + rlocn->offset,
NAME_LEN, MDA_CONTENT_REASON(primary_mda), buf)) NAME_LEN, MDA_CONTENT_REASON(primary_mda), buf))
return_0; return_0;
while (buf[len] && !isspace(buf[len]) && buf[len] != '{' && return _vgname_from_mda_validate(vfmp, buf);
len < (NAME_LEN - 1))
len++;
buf[len] = '\0';
/* Ignore this entry if the characters aren't permissible */
if (!validate_name(buf))
return_0;
/* We found a VG - now check the metadata */
if (rlocn->offset + rlocn->size > mdah->size)
wrap = (uint32_t) ((rlocn->offset + rlocn->size) - mdah->size);
if (wrap > rlocn->offset) {
log_error("%s: metadata (" FMTu64 " bytes) too large for circular buffer (" FMTu64 " bytes)",
dev_name(dev_area->dev), rlocn->size, mdah->size - MDA_HEADER_SIZE);
return 0;
}
/* Did we see this metadata before? */
vgsummary->mda_checksum = rlocn->checksum;
vgsummary->mda_size = rlocn->size;
if (lvmcache_lookup_mda(vgsummary))
used_cached_metadata = 1;
/* FIXME 64-bit */
if (!text_vgsummary_import(fmt, dev_area->dev, MDA_CONTENT_REASON(primary_mda),
(off_t) (dev_area->start + rlocn->offset),
(uint32_t) (rlocn->size - wrap),
(off_t) (dev_area->start + MDA_HEADER_SIZE),
wrap, calc_crc, vgsummary->vgname ? 1 : 0,
vgsummary))
return_0;
/* Ignore this entry if the characters aren't permissible */
if (!validate_name(vgsummary->vgname))
return_0;
log_debug_metadata("%s: %s metadata at " FMTu64 " size " FMTu64 " with wrap " FMTu32
" (in area at " FMTu64 " size " FMTu64
") for %s (" FMTVGID ")",
dev_name(dev_area->dev),
used_cached_metadata ? "Using cached" : "Found",
dev_area->start + rlocn->offset,
rlocn->size, wrap, dev_area->start, dev_area->size, vgsummary->vgname,
(char *)&vgsummary->vgid);
if (mda_free_sectors) {
current_usage = ALIGN_ABSOLUTE(rlocn->size, dev_area->start + rlocn->offset, MDA_ALIGNMENT);
buffer_size = mdah->size - MDA_HEADER_SIZE;
if (current_usage * 2 >= buffer_size)
*mda_free_sectors = UINT64_C(0);
else
*mda_free_sectors = ((buffer_size - 2 * current_usage) / 2) >> SECTOR_SHIFT;
}
return 1;
} }
static int _scan_raw(const struct format_type *fmt, const char *vgname __attribute__((unused))) static int _scan_raw(const struct format_type *fmt, const char *vgname __attribute__((unused)))