2.28-0.3: libblkid: bugfix

This commit is contained in:
Karel Zak 2016-03-30 15:04:47 +02:00
parent e466e3cc2f
commit 77818367d0
2 changed files with 166 additions and 1 deletions

160
2.28-libblkid-mmap.patch Normal file
View File

@ -0,0 +1,160 @@
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

View File

@ -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 <kzak@redhat.com> - 2.28-0.3
- fix libblkid
* Tue Mar 29 2016 Karel Zak <kzak@redhat.com> - 2.28-0.2
- upgrade to v2.28-rc2