mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
config: drop reading file with mmap
While normally the 'mmap' file reading is better utilizing resources, it has also its odd side with handling errors - so while we normally use the mmap only for reading regular files from root filesystem (i.e. lvm.conf) we can't prevent error to happen during the read of these file - and such error unfortunately ends with SIGBUS error. Maintaing signal handler would be compilated - so switch to slightly less effiecient but more error resistant read() functinality.
This commit is contained in:
parent
9a88a9c4ce
commit
e3e04b99f2
@ -503,10 +503,10 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r
|
|||||||
{
|
{
|
||||||
char *fb, *fe;
|
char *fb, *fe;
|
||||||
int r = 0;
|
int r = 0;
|
||||||
int use_mmap = 1;
|
int sz, use_plain_read = 1;
|
||||||
off_t mmap_offset = 0;
|
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
struct config_source *cs = dm_config_get_custom(cft);
|
struct config_source *cs = dm_config_get_custom(cft);
|
||||||
|
size_t rsize;
|
||||||
|
|
||||||
if (!_is_file_based_config_source(cs->type)) {
|
if (!_is_file_based_config_source(cs->type)) {
|
||||||
log_error(INTERNAL_ERROR "config_file_read_fd: expected file, special file "
|
log_error(INTERNAL_ERROR "config_file_read_fd: expected file, special file "
|
||||||
@ -515,26 +515,28 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only use mmap with regular files */
|
/* Only use plain read with regular files */
|
||||||
if (!(dev->flags & DEV_REGULAR) || size2)
|
if (!(dev->flags & DEV_REGULAR) || size2)
|
||||||
use_mmap = 0;
|
use_plain_read = 0;
|
||||||
|
|
||||||
if (use_mmap) {
|
|
||||||
mmap_offset = offset % lvm_getpagesize();
|
|
||||||
/* memory map the file */
|
|
||||||
fb = mmap((caddr_t) 0, size + mmap_offset, PROT_READ,
|
|
||||||
MAP_PRIVATE, dev_fd(dev), offset - mmap_offset);
|
|
||||||
if (fb == (caddr_t) (-1)) {
|
|
||||||
log_sys_error("mmap", dev_name(dev));
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
fb = fb + mmap_offset;
|
|
||||||
} else {
|
|
||||||
if (!(buf = malloc(size + size2))) {
|
if (!(buf = malloc(size + size2))) {
|
||||||
log_error("Failed to allocate circular buffer.");
|
log_error("Failed to allocate circular buffer.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (use_plain_read) {
|
||||||
|
/* Note: also used for lvm.conf to read all settings */
|
||||||
|
for (rsize = 0; rsize < size; rsize += sz) {
|
||||||
|
do {
|
||||||
|
sz = read(dev_fd(dev), buf + rsize, size - rsize);
|
||||||
|
} while ((sz < 0) && ((errno == EINTR) || (errno == EAGAIN)));
|
||||||
|
|
||||||
|
if (sz < 0) {
|
||||||
|
log_sys_error("read", dev_name(dev));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (!dev_read_bytes(dev, offset, size, buf))
|
if (!dev_read_bytes(dev, offset, size, buf))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -542,9 +544,9 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r
|
|||||||
if (!dev_read_bytes(dev, offset2, size2, buf + size))
|
if (!dev_read_bytes(dev, offset2, size2, buf + size))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fb = buf;
|
fb = buf;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The checksum passed in is the checksum from the mda_header
|
* The checksum passed in is the checksum from the mda_header
|
||||||
@ -573,15 +575,7 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev, dev_io_r
|
|||||||
r = 1;
|
r = 1;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (!use_mmap)
|
|
||||||
free(buf);
|
free(buf);
|
||||||
else {
|
|
||||||
/* unmap the file */
|
|
||||||
if (munmap(fb - mmap_offset, size + mmap_offset)) {
|
|
||||||
log_sys_error("munmap", dev_name(dev));
|
|
||||||
r = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user