diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c index a5d839762..f33451fb9 100644 --- a/lib/format_text/format-text.c +++ b/lib/format_text/format-text.c @@ -320,6 +320,8 @@ static int _raw_read_mda_header(struct mda_header *mdah, struct device_area *dev log_debug_metadata("Reading mda header sector from %s at %llu", dev_name(dev_area->dev), (unsigned long long)dev_area->start); + label_scan_confirm(dev_area->dev); /* FIXME: remove this, ensures dev is in bcache */ + if (!bcache_read_bytes(scan_bcache, dev_area->dev->bcache_fd, dev_area->start, MDA_HEADER_SIZE, mdah)) { log_error("Failed to read metadata area header on %s at %llu", dev_name(dev_area->dev), (unsigned long long)dev_area->start); @@ -462,6 +464,8 @@ static struct raw_locn *_read_metadata_location_vg(struct device_area *dev_area, */ memset(vgnamebuf, 0, sizeof(vgnamebuf)); + label_scan_confirm(dev_area->dev); /* FIXME: remove this, ensures dev is in bcache */ + bcache_read_bytes(scan_bcache, dev_area->dev->bcache_fd, dev_area->start + rlocn->offset, NAME_LEN, vgnamebuf); if (!strncmp(vgnamebuf, vgname, len = strlen(vgname)) && @@ -1209,6 +1213,8 @@ int read_metadata_location_summary(const struct format_type *fmt, return 0; } + label_scan_confirm(dev_area->dev); /* FIXME: remove this, ensures dev is in bcache */ + bcache_read_bytes(scan_bcache, dev_area->dev->bcache_fd, dev_area->start + rlocn->offset, NAME_LEN, buf); while (buf[len] && !isspace(buf[len]) && buf[len] != '{' && diff --git a/lib/label/label.c b/lib/label/label.c index 2ec187c81..5da781ec4 100644 --- a/lib/label/label.c +++ b/lib/label/label.c @@ -786,3 +786,21 @@ int label_read_sector(struct device *dev, struct label **labelp, uint64_t scan_s return label_read(dev, labelp, 0); } +/* + * FIXME: remove this. It should not be needed once writes are going through + * bcache. As it is now, the write path involves multiple writes to a device, + * and later writes want to read previous writes from disk. They do these + * reads using the standard read paths which require the devs to be in bcache, + * but the bcache reads do not find the dev because the writes have gone around + * bcache. To work around this for now, check if each dev is in bcache before + * reading it, and if not add it first. + */ + +void label_scan_confirm(struct device *dev) +{ + if (!_in_bcache(dev)) { + log_warn("add dev %s to bcache", dev_name(dev)); + label_read(dev, NULL, 0); + } +} + diff --git a/lib/label/label.h b/lib/label/label.h index eb62f6452..e265a6b9b 100644 --- a/lib/label/label.h +++ b/lib/label/label.h @@ -109,5 +109,6 @@ void label_scan_invalidate(struct device *dev); void label_scan_destroy(struct cmd_context *cmd); int label_read(struct device *dev, struct label **labelp, uint64_t unused_sector); int label_read_sector(struct device *dev, struct label **labelp, uint64_t scan_sector); +void label_scan_confirm(struct device *dev); #endif