161 lines
5.1 KiB
Diff
161 lines
5.1 KiB
Diff
From e04f386084c72df17e1d1e7d7d3e1e420a198442 Mon Sep 17 00:00:00 2001
|
|
From: Karel Zak <kzak@redhat.com>
|
|
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 <kzak@redhat.com>
|
|
---
|
|
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 <stdint.h>
|
|
#include <stdarg.h>
|
|
#include <limits.h>
|
|
-#include <sys/mman.h>
|
|
|
|
#ifdef HAVE_LIBUUID
|
|
# include <uuid.h>
|
|
@@ -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
|
|
|