1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-30 17:18:21 +03:00

lib: avoid reparsing same metadata

When reading VG mda from multiple PVs - do all the validation only
when mda is seen for the first time and  when mda checksum and length
is same just return already existing VG pointer.

(i.e. using 300PVs for a VG would lead to create and destroy 300 config trees....)
This commit is contained in:
Zdenek Kabelac 2012-03-26 13:35:26 +02:00
parent 6a2ae250ff
commit 7e7411966a
6 changed files with 44 additions and 8 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.118 -
=================================
Avoid reparsing same metadata when reading same metadata from multiple PVs.
Save extra device open/close when scanning device for size.
Fix seg_monitor field to report status also for mirrors and thick snapshots.

View File

@ -478,9 +478,15 @@ int override_config_tree_from_profile(struct cmd_context *cmd,
return 0;
}
/*
* When skip_parse is set, the checksum of buffer is only matched
* and function avoids parsing of mda into config tree which
* remains unmodified and should not be used.
*/
int config_file_read_fd(struct dm_config_tree *cft, struct device *dev,
off_t offset, size_t size, off_t offset2, size_t size2,
checksum_fn_t checksum_fn, uint32_t checksum)
checksum_fn_t checksum_fn, uint32_t checksum,
int skip_parse)
{
char *fb, *fe;
int r = 0;
@ -529,9 +535,11 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev,
goto out;
}
fe = fb + size + size2;
if (!dm_config_parse(cft, fb, fe))
goto_out;
if (!skip_parse) {
fe = fb + size + size2;
if (!dm_config_parse(cft, fb, fe))
goto_out;
}
r = 1;
@ -575,7 +583,7 @@ int config_file_read(struct dm_config_tree *cft)
}
r = config_file_read_fd(cft, cf->dev, 0, (size_t) info.st_size, 0, 0,
(checksum_fn_t) NULL, 0);
(checksum_fn_t) NULL, 0, 0);
if (!cf->keep_open) {
if (!dev_close(cf->dev))

View File

@ -205,7 +205,8 @@ typedef uint32_t (*checksum_fn_t) (uint32_t initial, const uint8_t *buf, uint32_
struct dm_config_tree *config_open(config_source_t source, const char *filename, int keep_open);
int config_file_read_fd(struct dm_config_tree *cft, struct device *dev,
off_t offset, size_t size, off_t offset2, size_t size2,
checksum_fn_t checksum_fn, uint32_t checksum);
checksum_fn_t checksum_fn, uint32_t checksum,
int skip_parse);
int config_file_read(struct dm_config_tree *cft);
struct dm_config_tree *config_file_open_and_read(const char *config_file, config_source_t source,
struct cmd_context *cmd);

View File

@ -51,7 +51,7 @@ const char *text_vgname_import(const struct format_type *fmt,
if ((!dev && !config_file_read(cft)) ||
(dev && !config_file_read_fd(cft, dev, offset, size,
offset2, size2, checksum_fn, checksum))) {
offset2, size2, checksum_fn, checksum, 0))) {
log_error("Couldn't read volume group metadata.");
goto out;
}
@ -88,6 +88,7 @@ struct volume_group *text_vg_import_fd(struct format_instance *fid,
struct volume_group *vg = NULL;
struct dm_config_tree *cft;
struct text_vg_version_ops **vsn;
int skip_parse;
_init_text_import();
@ -97,11 +98,20 @@ struct volume_group *text_vg_import_fd(struct format_instance *fid,
if (!(cft = config_open(CONFIG_FILE_SPECIAL, file, 0)))
return_NULL;
skip_parse = fid->vg && (fid->mda_checksum == checksum) &&
(fid->mda_size == (size + size2));
if ((!dev && !config_file_read(cft)) ||
(dev && !config_file_read_fd(cft, dev, offset, size,
offset2, size2, checksum_fn, checksum)))
offset2, size2, checksum_fn, checksum,
skip_parse)))
goto_out;
if (skip_parse) {
vg = fid->vg;
goto out;
}
/*
* Find a set of version functions that can read this file
*/
@ -116,6 +126,16 @@ struct volume_group *text_vg_import_fd(struct format_instance *fid,
break;
}
if (vg && (!fid->vg || (vg->seqno > fid->vg->seqno))) {
/*
* Remember vg pointer to newest VG for reuse.
* NOTE: _vg_read() will not release same VG
*/
fid->vg = vg;
fid->mda_size = (size + size2);
fid->mda_checksum = checksum;
}
out:
config_destroy(cft);
return vg;

View File

@ -324,6 +324,11 @@ struct format_instance {
struct dm_list metadata_areas_ignored;
struct dm_hash_table *metadata_areas_index;
/* Remember last vg to avoid parsing same mda content for multiple PVs */
struct volume_group *vg;
uint32_t mda_checksum;
size_t mda_size;
void *private;
};

View File

@ -3365,6 +3365,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
}
if (vg != correct_vg)
/* NOTE: tied to fid->vg logic in text_vg_import_fd() */
release_vg(vg);
}
fid->ref_count--;