diff options
author | David Teigland <teigland@redhat.com> | 2021-06-28 18:10:47 -0500 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2021-07-06 10:10:23 -0500 |
commit | e035e323508383fdcd9df0ef036d276a9c9909ab (patch) | |
tree | e5eb5558f63e2468b457452c6fc48e676e739c7a /lib/label | |
parent | d89942d157e49168d069a65f77a6ecb2c155b3fb (diff) | |
download | lvm2-e035e323508383fdcd9df0ef036d276a9c9909ab.tar.gz |
scan: retry reading metadata on error
If label_scan encounters bad vg metadata, invalidate
bcache data for the device and reread the mda_header
and metadata text back to back. With concurrent commands
modifying large metadata, it's possible that the entire
metadata area can be rewritten in the time between a
command reading the mda_header and reading the metadata
text that the header points to. Since the label_scan
is just assembling an initial overview of devices, it
doesn't use locking to serialize with other commands
that may be modifying the vg metadata at the same time.
Diffstat (limited to 'lib/label')
-rw-r--r-- | lib/label/label.c | 5 | ||||
-rw-r--r-- | lib/label/label.h | 1 |
2 files changed, 6 insertions, 0 deletions
diff --git a/lib/label/label.c b/lib/label/label.c index 50107edc8..ac84b6293 100644 --- a/lib/label/label.c +++ b/lib/label/label.c @@ -1704,6 +1704,11 @@ bool dev_invalidate_bytes(struct device *dev, uint64_t start, size_t len) return bcache_invalidate_bytes(scan_bcache, dev->bcache_di, start, len); } +void dev_invalidate(struct device *dev) +{ + bcache_invalidate_di(scan_bcache, dev->bcache_di); +} + bool dev_write_zeros(struct device *dev, uint64_t start, size_t len) { return dev_set_bytes(dev, start, len, 0); diff --git a/lib/label/label.h b/lib/label/label.h index fcdc309ac..32ceebc34 100644 --- a/lib/label/label.h +++ b/lib/label/label.h @@ -130,6 +130,7 @@ bool dev_write_bytes(struct device *dev, uint64_t start, size_t len, void *data) bool dev_write_zeros(struct device *dev, uint64_t start, size_t len); bool dev_set_bytes(struct device *dev, uint64_t start, size_t len, uint8_t val); bool dev_invalidate_bytes(struct device *dev, uint64_t start, size_t len); +void dev_invalidate(struct device *dev); void dev_set_last_byte(struct device *dev, uint64_t offset); void dev_unset_last_byte(struct device *dev); |