From 77818367d0d98ea9be20061d568461151ec657fa Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Wed, 30 Mar 2016 15:04:47 +0200 Subject: [PATCH] 2.28-0.3: libblkid: bugfix --- 2.28-libblkid-mmap.patch | 160 +++++++++++++++++++++++++++++++++++++++ util-linux.spec | 7 +- 2 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 2.28-libblkid-mmap.patch diff --git a/2.28-libblkid-mmap.patch b/2.28-libblkid-mmap.patch new file mode 100644 index 0000000..e9fbaa8 --- /dev/null +++ b/2.28-libblkid-mmap.patch @@ -0,0 +1,160 @@ +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 + diff --git a/util-linux.spec b/util-linux.spec index 67afb0a..018315c 100644 --- a/util-linux.spec +++ b/util-linux.spec @@ -2,7 +2,7 @@ Summary: A collection of basic system utilities Name: util-linux Version: 2.28 -Release: 0.2%{?dist} +Release: 0.3%{?dist} License: GPLv2 and GPLv2+ and LGPLv2+ and BSD with advertising and Public Domain Group: System Environment/Base URL: http://en.wikipedia.org/wiki/Util-linux @@ -88,6 +88,8 @@ Requires: libfdisk = %{version}-%{release} ### # 151635 - makeing /var/log/lastlog Patch0: 2.23-login-lastlog-create.patch +# upstream patch, revert mmap() based probing +Patch1: 2.28-libblkid-mmap.patch %description The util-linux package contains a large variety of low-level system @@ -919,6 +921,9 @@ exit 0 %{_libdir}/python*/site-packages/libmount/* %changelog +* Wed Mar 30 2016 Karel Zak - 2.28-0.3 +- fix libblkid + * Tue Mar 29 2016 Karel Zak - 2.28-0.2 - upgrade to v2.28-rc2