diff options
author | David Teigland <teigland@redhat.com> | 2019-02-05 12:39:08 -0600 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2019-04-09 13:29:36 -0500 |
commit | d92eb8c3d29c13e2f68bde1fdce57a5076272f1c (patch) | |
tree | 6432aa6b7811c1c538b4bf28a16e4b0157f2a373 | |
parent | 937f414f6b8e78ca5bae9ead71aa0fee3b783b90 (diff) | |
download | lvm2-d92eb8c3d29c13e2f68bde1fdce57a5076272f1c.tar.gz |
ability to keep track of bad mdas in lvmcache
mda's that cannot be processed by lvm because of
some corruption can be kept on a separate list.
These will be used for more advanced repair in a
subsequent commit.
-rw-r--r-- | lib/cache/lvmcache.c | 52 | ||||
-rw-r--r-- | lib/cache/lvmcache.h | 9 | ||||
-rw-r--r-- | lib/metadata/metadata.h | 1 |
3 files changed, 62 insertions, 0 deletions
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c index 8aed59ba9..8a8a2c867 100644 --- a/lib/cache/lvmcache.c +++ b/lib/cache/lvmcache.c @@ -31,6 +31,7 @@ struct lvmcache_info { struct dm_list mdas; /* list head for metadata areas */ struct dm_list das; /* list head for data areas */ struct dm_list bas; /* list head for bootloader areas */ + struct dm_list bad_mdas;/* list head for bad metadata areas */ struct lvmcache_vginfo *vginfo; /* NULL == unknown */ struct label *label; const struct format_type *fmt; @@ -39,6 +40,8 @@ struct lvmcache_info { uint32_t ext_version; /* Extension version */ uint32_t ext_flags; /* Extension flags */ uint32_t status; + unsigned mda1_bad:1; /* label scan found bad metadata in mda1 */ + unsigned mda2_bad:1; /* label scan found bad metadata in mda2 */ }; /* One per VG */ @@ -175,6 +178,51 @@ static void _destroy_duplicate_device_list(struct dm_list *head) dm_list_init(head); } +int lvmcache_has_bad_metadata(struct device *dev) +{ + struct lvmcache_info *info; + + if (!(info = lvmcache_info_from_pvid(dev->pvid, dev, 0))) { + /* shouldn't happen */ + log_error("No lvmcache info for checking bad metadata on %s", dev_name(dev)); + return 0; + } + + if (info->mda1_bad || info->mda2_bad) + return 1; + return 0; +} + +void lvmcache_save_bad_mda(struct lvmcache_info *info, struct metadata_area *mda) +{ + if (mda->mda_num == 1) + info->mda1_bad = 1; + else if (mda->mda_num == 2) + info->mda2_bad = 1; + dm_list_add(&info->bad_mdas, &mda->list); +} + +void lvmcache_get_bad_mdas(struct cmd_context *cmd, + const char *vgname, const char *vgid, + struct dm_list *bad_mdas) +{ + struct lvmcache_vginfo *vginfo; + struct lvmcache_info *info; + struct metadata_area *mda, *mda2; + + if (!(vginfo = lvmcache_vginfo_from_vgname(vgname, vgid))) { + log_error(INTERNAL_ERROR "lvmcache_get_bad_mdas no vginfo %s", vgname); + return; + } + + dm_list_iterate_items(info, &vginfo->infos) { + dm_list_iterate_items_safe(mda, mda2, &info->bad_mdas) { + dm_list_del(&mda->list); + dm_list_add(bad_mdas, &mda->list); + } + } +} + static void _vginfo_attach_info(struct lvmcache_vginfo *vginfo, struct lvmcache_info *info) { @@ -1950,6 +1998,10 @@ void lvmcache_del_mdas(struct lvmcache_info *info) if (info->mdas.n) del_mdas(&info->mdas); dm_list_init(&info->mdas); + + if (info->bad_mdas.n) + del_mdas(&info->bad_mdas); + dm_list_init(&info->bad_mdas); } void lvmcache_del_das(struct lvmcache_info *info) diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h index 26e09535e..fe91159ff 100644 --- a/lib/cache/lvmcache.h +++ b/lib/cache/lvmcache.h @@ -215,4 +215,13 @@ void lvmcache_save_metadata_size(uint64_t val); int dev_in_device_list(struct device *dev, struct dm_list *head); +int lvmcache_has_bad_metadata(struct device *dev); + +void lvmcache_save_bad_mda(struct lvmcache_info *info, struct metadata_area *mda); + +void lvmcache_get_bad_mdas(struct cmd_context *cmd, + const char *vgname, const char *vgid, + struct dm_list *bad_mdas); + + #endif diff --git a/lib/metadata/metadata.h b/lib/metadata/metadata.h index d904aa642..07ae29f8b 100644 --- a/lib/metadata/metadata.h +++ b/lib/metadata/metadata.h @@ -185,6 +185,7 @@ struct metadata_area { struct metadata_area_ops *ops; void *metadata_locn; uint32_t status; + int mda_num; uint32_t bad_fields; /* BAD_MDA_ flags are set to indicate errors found when reading */ uint32_t ignore_bad_fields; /* BAD_MDA_ flags are set to indicate errors to ignore */ }; |