From e04f386084c72df17e1d1e7d7d3e1e420a198442 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Wed, 30 Mar 2016 14:53:33 +0200 Subject: [PATCH] libblkid: revert mmap usage The implementation has not been ready for I/O errors and it seems that there is no elegant way how to resolve this issue. Linux returns SIGBUS on mmap errors and play with signals (or longjumps) in shared library is really bad idea. It also seems that mmaped devices have some unexpected side-effects with page-cache where for example dd returns old data for already modified device etc. Signed-off-by: Karel Zak --- libblkid/src/blkidP.h | 1 - libblkid/src/probe.c | 90 ++------------------------------------------------- 2 files changed, 2 insertions(+), 89 deletions(-) diff --git a/libblkid/src/blkidP.h b/libblkid/src/blkidP.h index 916deb0..e9a267e 100644 --- a/libblkid/src/blkidP.h +++ b/libblkid/src/blkidP.h @@ -180,7 +180,6 @@ struct blkid_struct_probe int fd; /* device file descriptor */ uint64_t off; /* begin of data on the device */ uint64_t size; /* end of data on the device */ - size_t mmap_granularity; /* minimal size of mmaped buffer (PAGE_SIZE) */ dev_t devno; /* device number (st.st_rdev) */ dev_t disk_devno; /* devno of the whole-disk or 0 */ diff --git a/libblkid/src/probe.c b/libblkid/src/probe.c index 9c48462..34d97b8 100644 --- a/libblkid/src/probe.c +++ b/libblkid/src/probe.c @@ -104,7 +104,6 @@ #include #include #include -#include #ifdef HAVE_LIBUUID # include @@ -581,85 +580,6 @@ int __blkid_probe_filter_types(blkid_probe pr, int chain, int flag, char *names[ return 0; } -/* align to mmap granularity */ -#define PROBE_ALIGN_OFF(p, o) ((o) & ~((p)->mmap_granularity - 1ULL)) -/* default buffer sizes */ -#define PROBE_MMAP_BEGINSIZ (1024ULL * 1024ULL * 2ULL) /* begin of the device */ -#define PROBE_MMAP_ENDSIZ (1024ULL * 1024ULL * 2ULL) /* end of the device */ -#define PROBE_MMAP_MIDSIZ (1024ULL * 1024ULL) /* middle of the device */ - -#define probe_is_mmap_wanted(p) (!S_ISCHR((p)->mode)) - -static struct blkid_bufinfo *mmap_buffer(blkid_probe pr, uint64_t real_off, uint64_t len) -{ - uint64_t map_len; - uint64_t map_off = 0; - struct blkid_bufinfo *bf = NULL; - - /* - * libblkid heavily reads begin and end of the device, so it seems - * better to mmap ~2MiB from the begin and end of the device to reduces - * number of syscalls and necessary buffers. For random accees - * somewhere in the middle of the device we use 1MiB buffers. - */ - if (!pr->mmap_granularity) - pr->mmap_granularity = getpagesize(); - - /* begin of the device */ - if (real_off == 0 || real_off + len < PROBE_MMAP_BEGINSIZ) { - DBG(BUFFER, ul_debug("\tmapping begin of the device (max size: %"PRIu64")", pr->size)); - map_off = 0; - map_len = PROBE_MMAP_BEGINSIZ > pr->size ? pr->size : PROBE_MMAP_BEGINSIZ; - - - /* end of the device */ - } else if (real_off > pr->off + pr->size - PROBE_MMAP_ENDSIZ) { - DBG(BUFFER, ul_debug("\tmapping end of the device (probing area: " - "off=%"PRIu64", size=%"PRIu64")", pr->off, pr->size)); - - map_off = PROBE_ALIGN_OFF(pr, pr->off + pr->size - PROBE_MMAP_ENDSIZ); - map_len = pr->off + pr->size - map_off; - - /* middle of the device */ - } else { - uint64_t minlen; - - map_off = PROBE_ALIGN_OFF(pr, real_off); - minlen = real_off + len - map_off; - - map_len = minlen > PROBE_MMAP_MIDSIZ ? minlen : PROBE_MMAP_MIDSIZ; - - if (map_off + map_len > pr->off + pr->size) - map_len = pr->size - map_off; - } - - assert(map_off <= real_off); - assert(map_off + map_len >= real_off + len); - - /* allocate buffer handler */ - bf = malloc(sizeof(*bf)); - if (!bf) { - errno = ENOMEM; - return NULL; - } - - /* mmap into memmory */ - bf->data = mmap(NULL, map_len, PROT_READ, MAP_SHARED, pr->fd, map_off); - if (bf->data == MAP_FAILED) { - DBG(BUFFER, ul_debug("\tmmap failed: %m")); - free(bf); - return NULL; - } - - bf->off = map_off; - bf->len = map_len; - INIT_LIST_HEAD(&bf->bufs); - - DBG(BUFFER, ul_debug("\tmmap %p: off=%"PRIu64", len=%"PRIu64" (%"PRIu64" pages)", - bf->data, map_off, map_len, map_len / pr->mmap_granularity)); - return bf; -} - static struct blkid_bufinfo *read_buffer(blkid_probe pr, uint64_t real_off, uint64_t len) { ssize_t ret; @@ -759,10 +679,7 @@ unsigned char *blkid_probe_get_buffer(blkid_probe pr, uint64_t off, uint64_t len /* not found; read from disk */ if (!bf) { - if (probe_is_mmap_wanted(pr)) - bf = mmap_buffer(pr, real_off, len); - else - bf = read_buffer(pr, real_off, len); + bf = read_buffer(pr, real_off, len); if (!bf) return NULL; @@ -794,13 +711,10 @@ static void blkid_probe_reset_buffer(blkid_probe pr) DBG(BUFFER, ul_debug(" remove buffer: %p [off=%"PRIu64", len=%"PRIu64"]", bf->data, bf->off, bf->len)); - - if (probe_is_mmap_wanted(pr)) - munmap(bf->data, bf->len); free(bf); } - DBG(LOWPROBE, ul_debug(" buffers summary: %"PRIu64" bytes by %"PRIu64" read/mmap() calls", + DBG(LOWPROBE, ul_debug(" buffers summary: %"PRIu64" bytes by %"PRIu64" read() calls", len, ct)); INIT_LIST_HEAD(&pr->buffers); -- 2.4.3