mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
scan: work around udev problems by avoiding open RDWR
udev creates a train wreck of events if we open devices with RDWR. Until we can fix/disable/scrap udev, work around this by opening RDONLY and then closing/reopening RDWR when a write is needed. This invalidates the bcache blocks for the device before writing so it can trigger unnecessary rereading.
This commit is contained in:
parent
76075ff55d
commit
a30e622279
@ -35,6 +35,7 @@
|
|||||||
#define DEV_BCACHE_EXCL 0x00001000 /* bcache_fd should be open EXCL */
|
#define DEV_BCACHE_EXCL 0x00001000 /* bcache_fd should be open EXCL */
|
||||||
#define DEV_FILTER_AFTER_SCAN 0x00002000 /* apply filter after bcache has data */
|
#define DEV_FILTER_AFTER_SCAN 0x00002000 /* apply filter after bcache has data */
|
||||||
#define DEV_FILTER_OUT_SCAN 0x00004000 /* filtered out during label scan */
|
#define DEV_FILTER_OUT_SCAN 0x00004000 /* filtered out during label scan */
|
||||||
|
#define DEV_BCACHE_WRITE 0x00008000 /* bcache_fd is open with RDWR */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Support for external device info.
|
* Support for external device info.
|
||||||
|
@ -464,12 +464,24 @@ static int _scan_dev_open(struct device *dev)
|
|||||||
name_sl = dm_list_item(name_list, struct dm_str_list);
|
name_sl = dm_list_item(name_list, struct dm_str_list);
|
||||||
name = name_sl->str;
|
name = name_sl->str;
|
||||||
|
|
||||||
flags |= O_RDWR;
|
|
||||||
flags |= O_DIRECT;
|
flags |= O_DIRECT;
|
||||||
flags |= O_NOATIME;
|
flags |= O_NOATIME;
|
||||||
|
|
||||||
if (dev->flags & DEV_BCACHE_EXCL)
|
/*
|
||||||
|
* FIXME: udev is a train wreck when we open RDWR and close, so we
|
||||||
|
* need to only use RDWR when we actually need to write, and use
|
||||||
|
* RDONLY otherwise. Fix, disable or scrap udev nonsense so we can
|
||||||
|
* just open with RDWR by default.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (dev->flags & DEV_BCACHE_EXCL) {
|
||||||
flags |= O_EXCL;
|
flags |= O_EXCL;
|
||||||
|
flags |= O_RDWR;
|
||||||
|
} else if (dev->flags & DEV_BCACHE_WRITE) {
|
||||||
|
flags |= O_RDWR;
|
||||||
|
} else {
|
||||||
|
flags |= O_RDONLY;
|
||||||
|
}
|
||||||
|
|
||||||
retry_open:
|
retry_open:
|
||||||
|
|
||||||
@ -1107,7 +1119,14 @@ int label_scan_open(struct device *dev)
|
|||||||
|
|
||||||
int label_scan_open_excl(struct device *dev)
|
int label_scan_open_excl(struct device *dev)
|
||||||
{
|
{
|
||||||
|
if (_in_bcache(dev) && !(dev->flags & DEV_BCACHE_EXCL)) {
|
||||||
|
/* FIXME: avoid tossing out bcache blocks just to replace fd. */
|
||||||
|
log_debug("Close and reopen excl %s", dev_name(dev));
|
||||||
|
bcache_invalidate_fd(scan_bcache, dev->bcache_fd);
|
||||||
|
_scan_dev_close(dev);
|
||||||
|
}
|
||||||
dev->flags |= DEV_BCACHE_EXCL;
|
dev->flags |= DEV_BCACHE_EXCL;
|
||||||
|
dev->flags |= DEV_BCACHE_WRITE;
|
||||||
return label_scan_open(dev);
|
return label_scan_open(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1149,8 +1168,19 @@ bool dev_write_bytes(struct device *dev, uint64_t start, size_t len, void *data)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(dev->flags & DEV_BCACHE_WRITE)) {
|
||||||
|
/* FIXME: avoid tossing out bcache blocks just to replace fd. */
|
||||||
|
log_debug("Close and reopen to write %s", dev_name(dev));
|
||||||
|
bcache_invalidate_fd(scan_bcache, dev->bcache_fd);
|
||||||
|
_scan_dev_close(dev);
|
||||||
|
|
||||||
|
dev->flags |= DEV_BCACHE_WRITE;
|
||||||
|
label_scan_open(dev);
|
||||||
|
}
|
||||||
|
|
||||||
if (dev->bcache_fd <= 0) {
|
if (dev->bcache_fd <= 0) {
|
||||||
/* This is not often needed, perhaps only with lvmetad. */
|
/* This is not often needed, perhaps only with lvmetad. */
|
||||||
|
dev->flags |= DEV_BCACHE_WRITE;
|
||||||
if (!label_scan_open(dev)) {
|
if (!label_scan_open(dev)) {
|
||||||
log_error("Error opening device %s for writing at %llu length %u.",
|
log_error("Error opening device %s for writing at %llu length %u.",
|
||||||
dev_name(dev), (unsigned long long)start, (uint32_t)len);
|
dev_name(dev), (unsigned long long)start, (uint32_t)len);
|
||||||
@ -1184,8 +1214,19 @@ bool dev_write_zeros(struct device *dev, uint64_t start, size_t len)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(dev->flags & DEV_BCACHE_WRITE)) {
|
||||||
|
/* FIXME: avoid tossing out bcache blocks just to replace fd. */
|
||||||
|
log_debug("Close and reopen to write %s", dev_name(dev));
|
||||||
|
bcache_invalidate_fd(scan_bcache, dev->bcache_fd);
|
||||||
|
_scan_dev_close(dev);
|
||||||
|
|
||||||
|
dev->flags |= DEV_BCACHE_WRITE;
|
||||||
|
label_scan_open(dev);
|
||||||
|
}
|
||||||
|
|
||||||
if (dev->bcache_fd <= 0) {
|
if (dev->bcache_fd <= 0) {
|
||||||
/* This is not often needed, perhaps only with lvmetad. */
|
/* This is not often needed, perhaps only with lvmetad. */
|
||||||
|
dev->flags |= DEV_BCACHE_WRITE;
|
||||||
if (!label_scan_open(dev)) {
|
if (!label_scan_open(dev)) {
|
||||||
log_error("Error opening device %s for writing at %llu length %u.",
|
log_error("Error opening device %s for writing at %llu length %u.",
|
||||||
dev_name(dev), (unsigned long long)start, (uint32_t)len);
|
dev_name(dev), (unsigned long long)start, (uint32_t)len);
|
||||||
@ -1219,8 +1260,19 @@ bool dev_set_bytes(struct device *dev, uint64_t start, size_t len, uint8_t val)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(dev->flags & DEV_BCACHE_WRITE)) {
|
||||||
|
/* FIXME: avoid tossing out bcache blocks just to replace fd. */
|
||||||
|
log_debug("Close and reopen to write %s", dev_name(dev));
|
||||||
|
bcache_invalidate_fd(scan_bcache, dev->bcache_fd);
|
||||||
|
_scan_dev_close(dev);
|
||||||
|
|
||||||
|
dev->flags |= DEV_BCACHE_WRITE;
|
||||||
|
label_scan_open(dev);
|
||||||
|
}
|
||||||
|
|
||||||
if (dev->bcache_fd <= 0) {
|
if (dev->bcache_fd <= 0) {
|
||||||
/* This is not often needed, perhaps only with lvmetad. */
|
/* This is not often needed, perhaps only with lvmetad. */
|
||||||
|
dev->flags |= DEV_BCACHE_WRITE;
|
||||||
if (!label_scan_open(dev)) {
|
if (!label_scan_open(dev)) {
|
||||||
log_error("Error opening device %s for writing at %llu length %u.",
|
log_error("Error opening device %s for writing at %llu length %u.",
|
||||||
dev_name(dev), (unsigned long long)start, (uint32_t)len);
|
dev_name(dev), (unsigned long long)start, (uint32_t)len);
|
||||||
|
Loading…
Reference in New Issue
Block a user