mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
lib: reduce parsing in vgname_from_mda
Use similar logic as with text_vg_import_fd() and avoid repeated parsing of same mda and its config tree for vgname_from_mda(). Remember last parsed vgname, vgid and creation_host in labeller structure and if the metadata have the same size and checksum, return this stored info. TODO: The reuse of labeller struct is not ideal, some lvmcache API for this functionality would be nicer.
This commit is contained in:
parent
7e7411966a
commit
a9b28a4f21
@ -1,5 +1,6 @@
|
|||||||
Version 2.02.118 -
|
Version 2.02.118 -
|
||||||
=================================
|
=================================
|
||||||
|
Reduce number of VG metadata parsing when looking for vgname on a PV.
|
||||||
Avoid reparsing same metadata when reading same metadata from multiple PVs.
|
Avoid reparsing same metadata when reading same metadata from multiple PVs.
|
||||||
Save extra device open/close when scanning device for size.
|
Save extra device open/close when scanning device for size.
|
||||||
Fix seg_monitor field to report status also for mirrors and thick snapshots.
|
Fix seg_monitor field to report status also for mirrors and thick snapshots.
|
||||||
|
@ -1124,14 +1124,14 @@ static int _scan_file(const struct format_type *fmt, const char *vgname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char *vgname_from_mda(const struct format_type *fmt,
|
const char *vgname_from_mda(const struct format_type *fmt,
|
||||||
struct mda_header *mdah,
|
struct mda_header *mdah, struct device_area *dev_area,
|
||||||
struct device_area *dev_area, struct id *vgid,
|
uint32_t *mda_checksum, size_t *mda_size,
|
||||||
|
const char *vgname, struct id *vgid,
|
||||||
uint64_t *vgstatus, char **creation_host,
|
uint64_t *vgstatus, char **creation_host,
|
||||||
uint64_t *mda_free_sectors)
|
uint64_t *mda_free_sectors)
|
||||||
{
|
{
|
||||||
struct raw_locn *rlocn;
|
struct raw_locn *rlocn;
|
||||||
uint32_t wrap = 0;
|
uint32_t wrap = 0;
|
||||||
const char *vgname = NULL;
|
|
||||||
unsigned int len = 0;
|
unsigned int len = 0;
|
||||||
char buf[NAME_LEN + 1] __attribute__((aligned(8)));
|
char buf[NAME_LEN + 1] __attribute__((aligned(8)));
|
||||||
char uuid[64] __attribute__((aligned(8)));
|
char uuid[64] __attribute__((aligned(8)));
|
||||||
@ -1182,6 +1182,10 @@ const char *vgname_from_mda(const struct format_type *fmt,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if it could be the same VG */
|
||||||
|
if ((rlocn->checksum != *mda_checksum) || (rlocn->size != *mda_size))
|
||||||
|
vgname = NULL; /* nope, reset to NULL */
|
||||||
|
|
||||||
/* FIXME 64-bit */
|
/* FIXME 64-bit */
|
||||||
if (!(vgname = text_vgname_import(fmt, dev_area->dev,
|
if (!(vgname = text_vgname_import(fmt, dev_area->dev,
|
||||||
(off_t) (dev_area->start +
|
(off_t) (dev_area->start +
|
||||||
@ -1190,6 +1194,7 @@ const char *vgname_from_mda(const struct format_type *fmt,
|
|||||||
(off_t) (dev_area->start +
|
(off_t) (dev_area->start +
|
||||||
MDA_HEADER_SIZE),
|
MDA_HEADER_SIZE),
|
||||||
wrap, calc_crc, rlocn->checksum,
|
wrap, calc_crc, rlocn->checksum,
|
||||||
|
vgname,
|
||||||
vgid, vgstatus, creation_host)))
|
vgid, vgstatus, creation_host)))
|
||||||
return_NULL;
|
return_NULL;
|
||||||
|
|
||||||
@ -1217,6 +1222,9 @@ const char *vgname_from_mda(const struct format_type *fmt,
|
|||||||
*mda_free_sectors = ((buffer_size - 2 * current_usage) / 2) >> SECTOR_SHIFT;
|
*mda_free_sectors = ((buffer_size - 2 * current_usage) / 2) >> SECTOR_SHIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*mda_checksum = rlocn->checksum;
|
||||||
|
*mda_size = rlocn->size;
|
||||||
|
|
||||||
return vgname;
|
return vgname;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1230,6 +1238,8 @@ static int _scan_raw(const struct format_type *fmt, const char *vgname __attribu
|
|||||||
struct id vgid;
|
struct id vgid;
|
||||||
uint64_t vgstatus;
|
uint64_t vgstatus;
|
||||||
struct mda_header *mdah;
|
struct mda_header *mdah;
|
||||||
|
uint32_t mda_checksum = 0;
|
||||||
|
size_t mda_size = 0;
|
||||||
|
|
||||||
raw_list = &((struct mda_lists *) fmt->private)->raws;
|
raw_list = &((struct mda_lists *) fmt->private)->raws;
|
||||||
|
|
||||||
@ -1249,9 +1259,12 @@ static int _scan_raw(const struct format_type *fmt, const char *vgname __attribu
|
|||||||
goto close_dev;
|
goto close_dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: caching as in vgname_from_mda() (trigger this code?) */
|
||||||
if ((scanned_vgname = vgname_from_mda(fmt, mdah,
|
if ((scanned_vgname = vgname_from_mda(fmt, mdah,
|
||||||
&rl->dev_area, &vgid, &vgstatus,
|
&rl->dev_area,
|
||||||
NULL, NULL))) {
|
&mda_checksum, &mda_size, NULL,
|
||||||
|
&vgid, &vgstatus,
|
||||||
|
NULL, NULL))) {
|
||||||
vg = _vg_read_raw_area(&fid, scanned_vgname, &rl->dev_area, 0, 0);
|
vg = _vg_read_raw_area(&fid, scanned_vgname, &rl->dev_area, 0, 0);
|
||||||
if (vg)
|
if (vg)
|
||||||
lvmcache_update_vg(vg, 0);
|
lvmcache_update_vg(vg, 0);
|
||||||
|
@ -79,10 +79,11 @@ struct volume_group *text_vg_import_fd(struct format_instance *fid,
|
|||||||
time_t *when, char **desc);
|
time_t *when, char **desc);
|
||||||
const char *text_vgname_import(const struct format_type *fmt,
|
const char *text_vgname_import(const struct format_type *fmt,
|
||||||
struct device *dev,
|
struct device *dev,
|
||||||
off_t offset, uint32_t size,
|
off_t offset, uint32_t size,
|
||||||
off_t offset2, uint32_t size2,
|
off_t offset2, uint32_t size2,
|
||||||
checksum_fn_t checksum_fn, uint32_t checksum,
|
checksum_fn_t checksum_fn, uint32_t checksum,
|
||||||
struct id *vgid, uint64_t *vgstatus,
|
const char *vgname,
|
||||||
|
struct id *vgid, uint64_t *vgstatus,
|
||||||
char **creation_host);
|
char **creation_host);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -32,17 +32,22 @@ static void _init_text_import(void)
|
|||||||
_text_import_initialised = 1;
|
_text_import_initialised = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find out vgname on a given device.
|
||||||
|
* If the checksum and metadata size is matching the vgname discovered in last read
|
||||||
|
* (multi PVs VG) could be passed back and it may skip parsing of such metadata.
|
||||||
|
*/
|
||||||
const char *text_vgname_import(const struct format_type *fmt,
|
const char *text_vgname_import(const struct format_type *fmt,
|
||||||
struct device *dev,
|
struct device *dev,
|
||||||
off_t offset, uint32_t size,
|
off_t offset, uint32_t size,
|
||||||
off_t offset2, uint32_t size2,
|
off_t offset2, uint32_t size2,
|
||||||
checksum_fn_t checksum_fn, uint32_t checksum,
|
checksum_fn_t checksum_fn, uint32_t checksum,
|
||||||
|
const char *vgname,
|
||||||
struct id *vgid, uint64_t *vgstatus,
|
struct id *vgid, uint64_t *vgstatus,
|
||||||
char **creation_host)
|
char **creation_host)
|
||||||
{
|
{
|
||||||
struct dm_config_tree *cft;
|
struct dm_config_tree *cft;
|
||||||
struct text_vg_version_ops **vsn;
|
struct text_vg_version_ops **vsn;
|
||||||
const char *vgname = NULL;
|
|
||||||
|
|
||||||
_init_text_import();
|
_init_text_import();
|
||||||
|
|
||||||
@ -51,11 +56,15 @@ const char *text_vgname_import(const struct format_type *fmt,
|
|||||||
|
|
||||||
if ((!dev && !config_file_read(cft)) ||
|
if ((!dev && !config_file_read(cft)) ||
|
||||||
(dev && !config_file_read_fd(cft, dev, offset, size,
|
(dev && !config_file_read_fd(cft, dev, offset, size,
|
||||||
offset2, size2, checksum_fn, checksum, 0))) {
|
offset2, size2, checksum_fn, checksum,
|
||||||
|
(vgname != NULL)))) {
|
||||||
log_error("Couldn't read volume group metadata.");
|
log_error("Couldn't read volume group metadata.");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vgname)
|
||||||
|
goto out; /* Everything is matching from the last call */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find a set of version functions that can read this file
|
* Find a set of version functions that can read this file
|
||||||
*/
|
*/
|
||||||
|
@ -100,7 +100,9 @@ struct mda_context {
|
|||||||
|
|
||||||
const char *vgname_from_mda(const struct format_type *fmt,
|
const char *vgname_from_mda(const struct format_type *fmt,
|
||||||
struct mda_header *mdah,
|
struct mda_header *mdah,
|
||||||
struct device_area *dev_area, struct id *vgid,
|
struct device_area *dev_area,
|
||||||
|
uint32_t *mda_checksum, size_t *mda_size,
|
||||||
|
const char *vgname, struct id *vgid,
|
||||||
uint64_t *vgstatus, char **creation_host,
|
uint64_t *vgstatus, char **creation_host,
|
||||||
uint64_t *mda_free_sectors);
|
uint64_t *mda_free_sectors);
|
||||||
|
|
||||||
|
@ -319,10 +319,14 @@ static int _update_mda(struct metadata_area *mda, void *baton)
|
|||||||
const struct format_type *fmt = p->label->labeller->fmt;
|
const struct format_type *fmt = p->label->labeller->fmt;
|
||||||
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
|
struct mda_context *mdac = (struct mda_context *) mda->metadata_locn;
|
||||||
struct mda_header *mdah;
|
struct mda_header *mdah;
|
||||||
const char *vgname = NULL;
|
struct labeller *l = p->label->labeller;
|
||||||
struct id vgid;
|
|
||||||
uint64_t vgstatus;
|
/*
|
||||||
char *creation_host;
|
* Using the labeller struct to preserve info about
|
||||||
|
* the last parsed vgname, vgid, creation host
|
||||||
|
*
|
||||||
|
* TODO: make lvmcache smarter and move this cache logic there
|
||||||
|
*/
|
||||||
|
|
||||||
if (!dev_open_readonly(mdac->area.dev)) {
|
if (!dev_open_readonly(mdac->area.dev)) {
|
||||||
mda_set_ignored(mda, 1);
|
mda_set_ignored(mda, 1);
|
||||||
@ -346,17 +350,18 @@ static int _update_mda(struct metadata_area *mda, void *baton)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((vgname = vgname_from_mda(fmt, mdah,
|
if ((l->vgname = vgname_from_mda(fmt, mdah, &mdac->area,
|
||||||
&mdac->area,
|
&l->mda_checksum, &l->mda_size, l->vgname,
|
||||||
&vgid, &vgstatus, &creation_host,
|
&l->vgid, &l->vgstatus, &l->creation_host,
|
||||||
&mdac->free_sectors)) &&
|
&mdac->free_sectors)) &&
|
||||||
!lvmcache_update_vgname_and_id(p->info, vgname,
|
!lvmcache_update_vgname_and_id(p->info, l->vgname,
|
||||||
(char *) &vgid, vgstatus,
|
(char *) &l->vgid, l->vgstatus,
|
||||||
creation_host)) {
|
l->creation_host)) {
|
||||||
if (!dev_close(mdac->area.dev))
|
if (!dev_close(mdac->area.dev))
|
||||||
stack;
|
stack;
|
||||||
return_0;
|
return_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
close_dev:
|
close_dev:
|
||||||
if (!dev_close(mdac->area.dev))
|
if (!dev_close(mdac->area.dev))
|
||||||
stack;
|
stack;
|
||||||
|
@ -89,6 +89,14 @@ struct label_ops {
|
|||||||
struct labeller {
|
struct labeller {
|
||||||
struct label_ops *ops;
|
struct label_ops *ops;
|
||||||
const struct format_type *fmt;
|
const struct format_type *fmt;
|
||||||
|
|
||||||
|
/* Caching info */
|
||||||
|
const char *vgname;
|
||||||
|
struct id vgid;
|
||||||
|
uint64_t vgstatus;
|
||||||
|
char *creation_host;
|
||||||
|
uint32_t mda_checksum;
|
||||||
|
size_t mda_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
int label_init(void);
|
int label_init(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user