|
|
e1e9d4 |
lib/config/config.c | 54 ++++++++++++++++++++++++-----------------------------
|
|
|
e1e9d4 |
1 file changed, 24 insertions(+), 30 deletions(-)
|
|
|
e1e9d4 |
|
|
|
e1e9d4 |
diff --git a/lib/config/config.c b/lib/config/config.c
|
|
|
e1e9d4 |
index ad816c2..96fdac5 100644
|
|
|
e1e9d4 |
--- a/lib/config/config.c
|
|
|
e1e9d4 |
+++ b/lib/config/config.c
|
|
|
e1e9d4 |
@@ -502,10 +502,10 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r
|
|
|
e1e9d4 |
{
|
|
|
e1e9d4 |
char *fb, *fe;
|
|
|
e1e9d4 |
int r = 0;
|
|
|
e1e9d4 |
- int use_mmap = 1;
|
|
|
e1e9d4 |
- off_t mmap_offset = 0;
|
|
|
e1e9d4 |
+ int sz, use_plain_read = 1;
|
|
|
e1e9d4 |
char *buf = NULL;
|
|
|
e1e9d4 |
struct config_source *cs = dm_config_get_custom(cft);
|
|
|
e1e9d4 |
+ size_t rsize;
|
|
|
e1e9d4 |
|
|
|
e1e9d4 |
if (!_is_file_based_config_source(cs->type)) {
|
|
|
e1e9d4 |
log_error(INTERNAL_ERROR "config_file_read_fd: expected file, special file "
|
|
|
e1e9d4 |
@@ -514,26 +514,28 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r
|
|
|
e1e9d4 |
return 0;
|
|
|
e1e9d4 |
}
|
|
|
e1e9d4 |
|
|
|
e1e9d4 |
- /* Only use mmap with regular files */
|
|
|
e1e9d4 |
+ /* Only use plain read with regular files */
|
|
|
e1e9d4 |
if (!(dev->flags & DEV_REGULAR) || size2)
|
|
|
e1e9d4 |
- use_mmap = 0;
|
|
|
e1e9d4 |
-
|
|
|
e1e9d4 |
- if (use_mmap) {
|
|
|
e1e9d4 |
- mmap_offset = offset % lvm_getpagesize();
|
|
|
e1e9d4 |
- /* memory map the file */
|
|
|
e1e9d4 |
- fb = mmap((caddr_t) 0, size + mmap_offset, PROT_READ,
|
|
|
e1e9d4 |
- MAP_PRIVATE, dev_fd(dev), offset - mmap_offset);
|
|
|
e1e9d4 |
- if (fb == (caddr_t) (-1)) {
|
|
|
e1e9d4 |
- log_sys_error("mmap", dev_name(dev));
|
|
|
e1e9d4 |
- goto out;
|
|
|
e1e9d4 |
+ use_plain_read = 0;
|
|
|
e1e9d4 |
+
|
|
|
e1e9d4 |
+ if (!(buf = dm_malloc(size + size2))) {
|
|
|
e1e9d4 |
+ log_error("Failed to allocate circular buffer.");
|
|
|
e1e9d4 |
+ return 0;
|
|
|
e1e9d4 |
+ }
|
|
|
e1e9d4 |
+
|
|
|
e1e9d4 |
+ if (use_plain_read) {
|
|
|
e1e9d4 |
+ /* Note: also used for lvm.conf to read all settings */
|
|
|
e1e9d4 |
+ for (rsize = 0; rsize < size; rsize += sz) {
|
|
|
e1e9d4 |
+ do {
|
|
|
e1e9d4 |
+ sz = read(dev_fd(dev), buf + rsize, size - rsize);
|
|
|
e1e9d4 |
+ } while ((sz < 0) && ((errno == EINTR) || (errno == EAGAIN)));
|
|
|
e1e9d4 |
+
|
|
|
e1e9d4 |
+ if (sz < 0) {
|
|
|
e1e9d4 |
+ log_sys_error("read", dev_name(dev));
|
|
|
e1e9d4 |
+ goto out;
|
|
|
e1e9d4 |
+ }
|
|
|
e1e9d4 |
}
|
|
|
e1e9d4 |
- fb = fb + mmap_offset;
|
|
|
e1e9d4 |
} else {
|
|
|
e1e9d4 |
- if (!(buf = dm_malloc(size + size2))) {
|
|
|
e1e9d4 |
- log_error("Failed to allocate circular buffer.");
|
|
|
e1e9d4 |
- return 0;
|
|
|
e1e9d4 |
- }
|
|
|
e1e9d4 |
-
|
|
|
e1e9d4 |
if (!dev_read_bytes(dev, offset, size, buf))
|
|
|
e1e9d4 |
goto out;
|
|
|
e1e9d4 |
|
|
|
e1e9d4 |
@@ -541,10 +543,10 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r
|
|
|
e1e9d4 |
if (!dev_read_bytes(dev, offset2, size2, buf + size))
|
|
|
e1e9d4 |
goto out;
|
|
|
e1e9d4 |
}
|
|
|
e1e9d4 |
-
|
|
|
e1e9d4 |
- fb = buf;
|
|
|
e1e9d4 |
}
|
|
|
e1e9d4 |
|
|
|
e1e9d4 |
+ fb = buf;
|
|
|
e1e9d4 |
+
|
|
|
e1e9d4 |
/*
|
|
|
e1e9d4 |
* The checksum passed in is the checksum from the mda_header
|
|
|
e1e9d4 |
* preceding this metadata. They should always match.
|
|
|
e1e9d4 |
@@ -572,15 +574,7 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r
|
|
|
e1e9d4 |
r = 1;
|
|
|
e1e9d4 |
|
|
|
e1e9d4 |
out:
|
|
|
e1e9d4 |
- if (!use_mmap)
|
|
|
e1e9d4 |
- dm_free(buf);
|
|
|
e1e9d4 |
- else {
|
|
|
e1e9d4 |
- /* unmap the file */
|
|
|
e1e9d4 |
- if (munmap(fb - mmap_offset, size + mmap_offset)) {
|
|
|
e1e9d4 |
- log_sys_error("munmap", dev_name(dev));
|
|
|
e1e9d4 |
- r = 0;
|
|
|
e1e9d4 |
- }
|
|
|
e1e9d4 |
- }
|
|
|
e1e9d4 |
+ dm_free(buf);
|
|
|
e1e9d4 |
|
|
|
e1e9d4 |
return r;
|
|
|
e1e9d4 |
}
|