[parted-devel] [PATCH] libparted: remove O_DIRECT cruft
Phillip Susi
psusi at ubuntu.com
Tue Jan 13 19:09:20 UTC 2015
linux_read was still allocating an aligned memory buffer and
copying from there to the caller buffer, in order to support
O_DIRECT. This is simply a waste of time now that we don't use
O_DIRECT. This change resulted in nearly 10% less cpu time spent
attempting to rescue a lost filesystem on a scsi_debug disk.
In addition, there was some autoconf machinery to make sure that
the test suite was run in a directory that supports O_DIRECT.
---
configure.ac | 1 -
libparted/arch/linux.c | 11 +--
m4/o-direct.m4 | 252 -------------------------------------------------
3 files changed, 1 insertion(+), 263 deletions(-)
delete mode 100644 m4/o-direct.m4
diff --git a/configure.ac b/configure.ac
index 436d0e2..bef1d83 100644
--- a/configure.ac
+++ b/configure.ac
@@ -170,7 +170,6 @@ AC_PROG_GCC_TRADITIONAL
AM_PROG_CC_C_O
gl_EARLY
-parted_FIND_USABLE_TEST_DIR
dnl This test must come as early as possible after the compiler configuration
dnl tests, because the choice of the file model can (in principle) affect
diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
index 0f18904..da87b4d 100644
--- a/libparted/arch/linux.c
+++ b/libparted/arch/linux.c
@@ -1781,7 +1781,6 @@ linux_read (const PedDevice* dev, void* buffer, PedSector start,
{
LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
PedExceptionOption ex_status;
- void* diobuf = NULL;
PED_ASSERT (dev != NULL);
PED_ASSERT (dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0);
@@ -1824,13 +1823,9 @@ linux_read (const PedDevice* dev, void* buffer, PedSector start,
}
size_t read_length = count * dev->sector_size;
- if (posix_memalign (&diobuf, dev->sector_size, read_length) != 0)
- return 0;
while (1) {
- ssize_t status = read (arch_specific->fd, diobuf, read_length);
- if (status > 0)
- memcpy(buffer, diobuf, status);
+ ssize_t status = read (arch_specific->fd, buffer, read_length);
if (status == (ssize_t) read_length)
break;
if (status > 0) {
@@ -1850,7 +1845,6 @@ linux_read (const PedDevice* dev, void* buffer, PedSector start,
switch (ex_status) {
case PED_EXCEPTION_IGNORE:
- free(diobuf);
return 1;
case PED_EXCEPTION_RETRY:
@@ -1859,7 +1853,6 @@ linux_read (const PedDevice* dev, void* buffer, PedSector start,
case PED_EXCEPTION_UNHANDLED:
ped_exception_catch ();
case PED_EXCEPTION_CANCEL:
- free(diobuf);
return 0;
default:
PED_ASSERT (0);
@@ -1867,8 +1860,6 @@ linux_read (const PedDevice* dev, void* buffer, PedSector start,
}
}
- free (diobuf);
-
return 1;
}
diff --git a/m4/o-direct.m4 b/m4/o-direct.m4
deleted file mode 100644
index 1f0b77a..0000000
--- a/m4/o-direct.m4
+++ /dev/null
@@ -1,252 +0,0 @@
-#serial 2
-# Find a directory in which a disk-simulating file is usable by parted.
-# The problem is that on systems supporting O_DIRECT, open with O_DIRECT
-# fails for some file system types (e.g., tmpfs on linux-2.6.21).
-
-# Copyright (C) 2007-2014 Free Software Foundation, Inc.
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# From Jim Meyering.
-
-# Set PARTED_USABLE_TEST_DIR to the name of the first usable directory
-# from the list below. If none is usable, set it to the empty string.
-# Consider $TMPDIR only if it specifies an absolute name, and that
-# name contains no shell meta-character. Likewise for $HOME.
-
-# This code is pretty picky. The chosen partition must support aligned reads
-# and writes in blocks of size 512B and 4KB to a file descriptor opened with
-# O_RDWR|O_DIRECT. Reiserfs doesn't support 512-byte reads. On tmpfs,
-# the open fails.
-
-# The candidate directories:
-# . $HOME $TMPDIR /tmp /var/tmp /dev/shm
-AC_DEFUN([parted_FIND_USABLE_TEST_DIR],
-[
- AC_CACHE_CHECK([for a usable (O_DIRECT-supporting) temporary dir],
- [parted_cv_func_open_O_DIRECT_temp_dir],
- [
- # First of all, if there is no O_DIRECT definition, use ".",
- # and skip the run-test.
- AC_EGREP_CPP([frobnozzle], [
-#include <fcntl.h>
-#ifdef O_DIRECT
-frobnozzle
-#endif
- ], pe_have_O_DIRECT=yes, pe_have_O_DIRECT=no)
- if test $pe_have_O_DIRECT = no; then
- # With no O_DIRECT definition, "." is fine.
- pe_cand_dirs=.
- else
- pe_cand_dirs=.
- for pe_dir in "$HOME" "$TMPDIR"; do
- case $pe_dir in
- /tmp) ;;
- /var/tmp) ;;
- /dev/shm) ;;
- /*) case $pe_dir in
- # Accept $HOME or $TMP only if the value is nice and boring.
- *[^/a-zA-Z0-9_.-]*) ;;
- *) pe_cand_dirs="$pe_cand_dirs $pe_dir";;
- esac
- esac
- done
-
- case $PARTED_TMPDIR in
- *[^/a-zA-Z0-9_.-]*) ;;
- *) pe_cand_dirs="$PARTED_TMPDIR $pe_cand_dirs";;
- esac
-
- # This is the list of candidate directories.
- pe_cand_dirs="$pe_cand_dirs /tmp /var/tmp /dev/shm"
-
- PARTED_CANDIDATE_DIRS=$pe_cand_dirs
- export PARTED_CANDIDATE_DIRS
-
- AC_RUN_IFELSE(
- [AC_LANG_SOURCE(
- [[
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define MAX_LOGICAL_BLOCK_SIZE 4096
-static char g_buf[2 * MAX_LOGICAL_BLOCK_SIZE];
-
-static inline void *
-ptr_align (void const *ptr, size_t alignment)
-{
- char const *p0 = ptr;
- char const *p1 = p0 + alignment - 1;
- return (void *) (p1 - (size_t) p1 % alignment);
-}
-
-static int
-create_input_file (char const *file, char const *buf, size_t n_bytes)
-{
- int fd = open (file, O_CREAT | O_WRONLY, 0600);
- if (fd < 0)
- return 1;
- if (write (fd, buf, n_bytes) != n_bytes)
- {
- close (fd);
- return 1;
- }
- return !! close (fd);
-}
-
-static int
-try_o_direct (char const *file, size_t block_size)
-{
- char *p = ptr_align (g_buf, MAX_LOGICAL_BLOCK_SIZE);
- int fd;
-
- if (!(p + block_size < g_buf + sizeof g_buf))
- return 4;
-
- fd = open (file, O_RDWR | O_DIRECT);
- if (fd < 0)
- return 1;
-
- if (write (fd, p, block_size) != block_size)
- return 1;
-
- if (lseek (fd, 0, SEEK_SET) != 0)
- return 1;
-
- if (read (fd, p, block_size) != block_size)
- return 1;
-
- return !! close (fd);
-}
-
-#undef stpcpy
-#define stpcpy(a, b) my_stpcpy (a, b)
-static char *
-my_stpcpy (char *dest, const char *src)
-{
- char *d = dest;
- const char *s = src;
- do *d++ = *s; while (*s++ != '\0');
- return d - 1;
-}
-
-/* The base name of the file we'll create in the mkdtemp-returned
- temporary directory. */
-#define BASENAME "x"
-
-/* Return 0 upon failure, else the 1-based index of the first
- useful directory name from PARTED_CANDIDATE_DIRS. */
-int
-main ()
-{
- char const *env_dirs;
- char *dirs;
- char *dir;
- unsigned int n;
- int found = 0;
- size_t dirs_len;
-
- if ((env_dirs = getenv ("PARTED_CANDIDATE_DIRS")) == NULL)
- return 0;
-
- dirs_len = strlen (env_dirs);
- if ((dirs = strndup (env_dirs, dirs_len)) == NULL)
- return 0;
- dir = dirs;
-
- for (n = 1; ; n++)
- {
- size_t dirname_len;
- char *space;
-
- /* Skip any leading spaces. */
- while (*dir == ' ')
- ++dir;
-
- space = strchr (dir, ' ');
- if (space)
- {
- *space = '\0';
- dirname_len = space - dir;
- }
- else
- {
- dirname_len = strlen (dir);
- }
-
- if (dirname_len != 0)
- {
- /* Create an mkdtemp template starting with dir. */
- char *tmp;
- char *endp;
- char const *base = "partedOD.XXXXXX";
- /* Allocate enough space not just for the dir name, but
- also for the name of the file to create within it. */
- char *template = malloc (dirname_len + 1 + strlen (base)
- + 1 + strlen (BASENAME) + 1);
- if (template != NULL
- && (endp = stpcpy (stpcpy (stpcpy (template, dir), "/"), base))
- && (tmp = mkdtemp (template)) != NULL)
- {
- /* Append "/BASENAME" to create the file name. */
- stpcpy (stpcpy (endp, "/"), BASENAME);
-
- if (create_input_file (tmp, g_buf, sizeof g_buf) == 0
- && try_o_direct (tmp, 512) == 0
- && try_o_direct (tmp, MAX_LOGICAL_BLOCK_SIZE) == 0)
- found = 1;
-
- unlink (tmp); /* ignore failure */
- *endp = '\0';
- rmdir (tmp); /* ignore failure */
- }
- free (template);
- }
-
- if (found)
- break;
-
- dir += dirname_len + 1;
- if (dirs + dirs_len < dir)
- {
- n = 0;
- break;
- }
- }
- free (dirs);
-
- return n;
-}
- ]])],
- # If the above program exits with status 0, then
- # there it found no useful directory. Use ".".
- [parted_cv_func_open_O_DIRECT_temp_dir=.],
-
- # It found one. The exit status is an index into the list.
- # We also run this code when the program fails to compile or
- # to link, as will happen on systems without a mkdtemp function.
- [pe_err=$?; set _ $pe_cand_dirs; shift
- eval parted_cv_func_open_O_DIRECT_temp_dir='$'$pe_err],
-
- # When cross-compiling, use ".".
- [parted_cv_func_open_O_DIRECT_temp_dir=.]
- )
- fi
- ])
- PARTED_USABLE_TEST_DIR=$parted_cv_func_open_O_DIRECT_temp_dir
- AC_SUBST([PARTED_USABLE_TEST_DIR])
-
- # If the result is ".", don't cache it. The next user of
- # the cache may well be running from a different file system.
- dnl Here, I'm using "$as_unset", which is a non-published (i.e., internal)
- dnl part of autoconf, but we don't expect its name to change any time soon.
- dnl and by then, it'll probably be ok to use "unset" all by itself.
- if test "$parted_cv_func_open_O_DIRECT_temp_dir" = .; then
- $as_unset parted_cv_func_open_O_DIRECT_temp_dir
- fi
-])
--
1.9.1
More information about the parted-devel
mailing list