summaryrefslogtreecommitdiff
path: root/lib/format_text/import.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/format_text/import.c')
-rw-r--r--lib/format_text/import.c86
1 files changed, 24 insertions, 62 deletions
diff --git a/lib/format_text/import.c b/lib/format_text/import.c
index 2ff061f40..565604400 100644
--- a/lib/format_text/import.c
+++ b/lib/format_text/import.c
@@ -40,7 +40,7 @@ int text_read_metadata_summary(const struct format_type *fmt,
checksum_fn_t checksum_fn,
int checksum_only,
struct lvmcache_vgsummary *vgsummary,
- uint32_t *failed_flags)
+ uint64_t *failed_flags)
{
struct dm_config_tree *cft;
struct text_vg_version_ops **vsn;
@@ -121,57 +121,25 @@ int text_read_metadata_summary(const struct format_type *fmt,
return r;
}
-struct cached_vg_fmtdata {
- uint32_t cached_mda_checksum;
- size_t cached_mda_size;
-};
-
-/*
- * FIXME: this function's results / return values are very
- * badly defined. It returns NULL both on an error, and
- * when it skips parsing because of an optimization. The
- * use_previous_vg might help except that the way it's used
- * means it won't tell you the result of each call. So,
- * failed_flags being returned as non-zero ends up being
- * the only way to tell if a particular call to this
- * function failed or not. Toss out the whole mess and
- * rewrite it sanely.
- */
-
struct volume_group *text_read_metadata_vg(struct format_instance *fid,
struct device *dev,
const char *file,
struct label_read_data *ld,
- struct cached_vg_fmtdata **vg_fmtdata,
- unsigned *use_previous_vg,
off_t offset, uint32_t size,
off_t offset2, uint32_t size2,
+ uint32_t last_meta_checksum,
+ size_t last_meta_size,
+ unsigned *last_meta_matches,
checksum_fn_t checksum_fn,
uint32_t checksum,
time_t *when, char **desc,
- uint32_t *failed_flags)
+ uint64_t *failed_flags)
{
struct volume_group *vg = NULL;
struct dm_config_tree *cft;
struct text_vg_version_ops **vsn;
char *buf = NULL;
- int skip_parse;
-
- /*
- * This struct holds the checksum and size of the VG metadata
- * that was read from a previous device. When we read the VG
- * metadata from this device, we can skip parsing it into a
- * cft (saving time) if the checksum of the metadata buffer
- * we read from this device matches the size/checksum saved in
- * the mda_header/rlocn struct on this device, and matches the
- * size/checksum from the previous device.
- */
- if (vg_fmtdata && !*vg_fmtdata &&
- !(*vg_fmtdata = dm_pool_zalloc(fid->mem, sizeof(**vg_fmtdata)))) {
- log_error("Failed to allocate VG fmtdata for text format.");
- *failed_flags |= FAILED_INTERNAL;
- return NULL;
- }
+ unsigned last_matches;
_init_text_import();
@@ -183,10 +151,14 @@ struct volume_group *text_read_metadata_vg(struct format_instance *fid,
return_NULL;
}
- /* Does the metadata match the already-cached VG? */
- skip_parse = vg_fmtdata &&
- ((*vg_fmtdata)->cached_mda_checksum == checksum) &&
- ((*vg_fmtdata)->cached_mda_size == (size + size2));
+ if (last_meta_checksum && last_meta_size &&
+ (checksum == last_meta_checksum) && ((size + size2) == last_meta_size))
+ last_matches = 1;
+ else
+ last_matches = 0;
+
+ if (last_meta_matches)
+ *last_meta_matches = last_matches;
if (ld) {
if (ld->buf_len >= (offset + size))
@@ -215,7 +187,7 @@ struct volume_group *text_read_metadata_vg(struct format_instance *fid,
if (!config_file_read_fd(cft, dev, buf, offset, size,
offset2, size2, checksum_fn, checksum,
- skip_parse, 1, failed_flags)) {
+ last_matches, 1, failed_flags)) {
log_error("Couldn't read volume group metadata from %s.", dev_name(dev));
/* We have to be certain this has been set since it's the
@@ -234,10 +206,9 @@ struct volume_group *text_read_metadata_vg(struct format_instance *fid,
}
}
- if (skip_parse) {
- if (use_previous_vg)
- *use_previous_vg = 1;
- log_debug_metadata("Skipped parsing metadata on %s", dev_name(dev));
+ if (last_matches) {
+ log_debug_metadata("Skipped parsing metadata on %s with matching checksum 0x%x size %zu.",
+ dev_name(dev), last_meta_checksum, last_meta_size);
goto out;
}
@@ -258,14 +229,6 @@ struct volume_group *text_read_metadata_vg(struct format_instance *fid,
break;
}
- if (vg && vg_fmtdata && *vg_fmtdata) {
- (*vg_fmtdata)->cached_mda_size = (size + size2);
- (*vg_fmtdata)->cached_mda_checksum = checksum;
- }
-
- if (use_previous_vg)
- *use_previous_vg = 0;
-
out:
config_destroy(cft);
return vg;
@@ -275,13 +238,12 @@ struct volume_group *text_read_metadata_file(struct format_instance *fid,
const char *file,
time_t *when, char **desc)
{
- uint32_t failed_flags = 0;
+ uint64_t failed_flags = 0;
- return text_read_metadata_vg(fid, NULL, file, NULL, NULL, NULL,
- (off_t)0, 0, (off_t)0, 0,
- NULL,
- 0,
- when, desc, &failed_flags);
+ return text_read_metadata_vg(fid, NULL, file, NULL,
+ (off_t)0, 0, (off_t)0, 0,
+ 0, 0, NULL, NULL, 0,
+ when, desc, &failed_flags);
}
static struct volume_group *_import_vg_from_config_tree(const struct dm_config_tree *cft,
@@ -290,7 +252,7 @@ static struct volume_group *_import_vg_from_config_tree(const struct dm_config_t
{
struct volume_group *vg = NULL;
struct text_vg_version_ops **vsn;
- uint32_t failed_flags = 0;
+ uint64_t failed_flags = 0;
int vg_missing;
_init_text_import();