OSDN Git Service

libext2fs: have UNIX IO manager use pread64/pwrite64
authorTheodore Ts'o <tytso@mit.edu>
Fri, 8 Aug 2014 20:42:05 +0000 (16:42 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Fri, 8 Aug 2014 20:42:05 +0000 (16:42 -0400)
Commit baa3544609da3c ("libext2fs: have UNIX IO manager use
pread/pwrite) causes a breakage on 32-bit systems where off_t is
32-bits for file systems larger than 4GB.  Fix this by using
pread64/pwrite64 if possible, and if pread64/pwrite64 is not present,
using pread/pwrite only if the size of off_t is at least as big as
ext2_loff_t.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
configure
configure.in
lib/config.h.in
lib/ext2fs/unix_io.c

index f0af1d5..b9ce43d 100755 (executable)
--- a/configure
+++ b/configure
@@ -12994,7 +12994,7 @@ if test "$ac_res" != no; then :
 fi
 
 fi
-for ac_func in         __secure_getenv         backtrace       blkid_probe_get_topology        blkid_probe_enable_partitions   chflags         fadvise64       fallocate       fallocate64     fchown  fdatasync       fstat64         ftruncate64     futimes         getcwd  getdtablesize   getmntinfo      getpwuid_r      getrlimit       getrusage       jrand48         llseek  lseek64         mallinfo        mbstowcs        memalign        mempcpy         mmap    msync   nanosleep       open64  pathconf        posix_fadvise   posix_fadvise64         posix_memalign  prctl   pread   pwrite  secure_getenv   setmntent       setresgid       setresuid       snprintf        srandom         stpcpy  strcasecmp      strdup  strnlen         strptime        strtoull        sync_file_range         sysconf         usleep  utime   valloc
+for ac_func in         __secure_getenv         backtrace       blkid_probe_get_topology        blkid_probe_enable_partitions   chflags         fadvise64       fallocate       fallocate64     fchown  fdatasync       fstat64         ftruncate64     futimes         getcwd  getdtablesize   getmntinfo      getpwuid_r      getrlimit       getrusage       jrand48         llseek  lseek64         mallinfo        mbstowcs        memalign        mempcpy         mmap    msync   nanosleep       open64  pathconf        posix_fadvise   posix_fadvise64         posix_memalign  prctl   pread   pwrite  pread64         pwrite64        secure_getenv   setmntent       setresgid       setresuid       snprintf        srandom         stpcpy  strcasecmp      strdup  strnlen         strptime        strtoull        sync_file_range         sysconf         usleep  utime   valloc
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
index b825f3d..2e59fde 100644 (file)
@@ -1061,6 +1061,8 @@ AC_CHECK_FUNCS(m4_flatten([
        prctl
        pread
        pwrite
+       pread64
+       pwrite64
        secure_getenv
        setmntent
        setresgid
index 34fb0cc..50cf312 100644 (file)
 /* Define to 1 if you have the `pread' function. */
 #undef HAVE_PREAD
 
+/* Define to 1 if you have the `pread64' function. */
+#undef HAVE_PREAD64
+
 /* Define if the <pthread.h> defines PTHREAD_MUTEX_RECURSIVE. */
 #undef HAVE_PTHREAD_MUTEX_RECURSIVE
 
 /* Define to 1 if you have the `pwrite' function. */
 #undef HAVE_PWRITE
 
+/* Define to 1 if you have the `pwrite64' function. */
+#undef HAVE_PWRITE64
+
 /* Define to 1 if dirent has d_reclen */
 #undef HAVE_RECLEN_DIRENT
 
index 0dd1490..eb39b28 100644 (file)
@@ -131,11 +131,21 @@ static errcode_t raw_read_blk(io_channel channel,
        data->io_stats.bytes_read += size;
        location = ((ext2_loff_t) block * channel->block_size) + data->offset;
 
-#ifdef HAVE_PREAD
+#ifdef HAVE_PREAD64
        /* Try an aligned pread */
        if ((channel->align == 0) ||
            (IS_ALIGNED(buf, channel->align) &&
             IS_ALIGNED(size, channel->align))) {
+               actual = pread64(data->dev, buf, size, location);
+               if (actual == size)
+                       return 0;
+       }
+#elif HAVE_PREAD
+       /* Try an aligned pread */
+       if ((sizeof(off_t) >= sizeof(ext2_loff_t)) &&
+           ((channel->align == 0) ||
+            (IS_ALIGNED(buf, channel->align) &&
+             IS_ALIGNED(size, channel->align)))) {
                actual = pread(data->dev, buf, size, location);
                if (actual == size)
                        return 0;
@@ -213,11 +223,21 @@ static errcode_t raw_write_blk(io_channel channel,
 
        location = ((ext2_loff_t) block * channel->block_size) + data->offset;
 
-#ifdef HAVE_PWRITE
+#ifdef HAVE_PWRITE64
        /* Try an aligned pwrite */
        if ((channel->align == 0) ||
            (IS_ALIGNED(buf, channel->align) &&
             IS_ALIGNED(size, channel->align))) {
+               actual = pwrite64(data->dev, buf, size, location);
+               if (actual == size)
+                       return 0;
+       }
+#elif HAVE_PWRITE
+       /* Try an aligned pwrite */
+       if ((sizeof(off_t) >= sizeof(ext2_loff_t)) &&
+           ((channel->align == 0) ||
+            (IS_ALIGNED(buf, channel->align) &&
+             IS_ALIGNED(size, channel->align)))) {
                actual = pwrite(data->dev, buf, size, location);
                if (actual == size)
                        return 0;