mirror of https://github.com/vitalif/e2fsprogs
libext2fs: fix ext2fs_llseek on i386
ext2fs_llseek() was using lseek instead of lseek64. The only time it would use lseek64 is if passed an offset that overflowed 32 bits. This works for SEEK_SET, but not SEEK_CUR, which can apply a small offset to move the file pointer past the 32 bit limit. The code has been changed to instead try lseek64 first, and fall back to lseek if that fails. It also was doing a runtime check of the size of off_t. This has been moved to compile time. This fixes a problem which would cause e2image when built for x86-32 to bomb out when used with large file systems. Signed-off-by: Phillip Susi <psusi@ubuntu.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>debian-1.42.9
parent
511ba985c0
commit
274d46e1d3
|
@ -916,14 +916,17 @@ AC_CHECK_SIZEOF(short)
|
|||
AC_CHECK_SIZEOF(int)
|
||||
AC_CHECK_SIZEOF(long)
|
||||
AC_CHECK_SIZEOF(long long)
|
||||
AC_CHECK_SIZEOF(off_t)
|
||||
SIZEOF_SHORT=$ac_cv_sizeof_short
|
||||
SIZEOF_INT=$ac_cv_sizeof_int
|
||||
SIZEOF_LONG=$ac_cv_sizeof_long
|
||||
SIZEOF_LONG_LONG=$ac_cv_sizeof_long_long
|
||||
SIZEOF_OFF_T=$ac_cv_sizeof_off_t
|
||||
AC_SUBST(SIZEOF_SHORT)
|
||||
AC_SUBST(SIZEOF_INT)
|
||||
AC_SUBST(SIZEOF_LONG)
|
||||
AC_SUBST(SIZEOF_LONG_LONG)
|
||||
AC_SUBST(SIZEOF_OFF_T)
|
||||
AC_C_BIGENDIAN
|
||||
BUILD_CC="$BUILD_CC" CPP="$CPP" /bin/sh $ac_aux_dir/parse-types.sh
|
||||
ASM_TYPES_HEADER=./asm_types.h
|
||||
|
|
|
@ -543,6 +543,9 @@
|
|||
/* The size of `long long', as computed by sizeof. */
|
||||
#undef SIZEOF_LONG_LONG
|
||||
|
||||
/* The size of `off_t', as computed by sizeof. */
|
||||
#undef SIZEOF_OFF_T
|
||||
|
||||
/* The size of `short', as computed by sizeof. */
|
||||
#undef SIZEOF_SHORT
|
||||
|
||||
|
|
|
@ -90,17 +90,14 @@ static ext2_loff_t my_llseek (int fd, ext2_loff_t offset, int origin)
|
|||
|
||||
ext2_loff_t ext2fs_llseek (int fd, ext2_loff_t offset, int origin)
|
||||
{
|
||||
#if SIZEOF_OFF_T >= SIZEOF_LONG_LONG
|
||||
return lseek (fd, offset, origin);
|
||||
#else
|
||||
ext2_loff_t result;
|
||||
static int do_compat = 0;
|
||||
|
||||
if ((sizeof(off_t) >= sizeof(ext2_loff_t)) ||
|
||||
(offset < ((ext2_loff_t) 1 << ((sizeof(off_t)*8) -1))))
|
||||
return lseek(fd, (off_t) offset, origin);
|
||||
|
||||
if (do_compat) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (do_compat)
|
||||
goto fallback;
|
||||
|
||||
result = my_llseek (fd, offset, origin);
|
||||
if (result == -1 && errno == ENOSYS) {
|
||||
|
@ -109,9 +106,14 @@ ext2_loff_t ext2fs_llseek (int fd, ext2_loff_t offset, int origin)
|
|||
* which does not support the llseek system call
|
||||
*/
|
||||
do_compat++;
|
||||
fallback:
|
||||
if (offset < ((ext2_loff_t) 1 << ((sizeof(off_t)*8) -1)))
|
||||
return lseek(fd, (off_t) offset, origin);
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
#else /* !linux */
|
||||
|
|
Loading…
Reference in New Issue