This patch adds a check to use fstat or fstat64 in getsize.c if the

target is a regular file, instead of doing binary searching.  It also
fixes a couple of cases where a file descriptor is leaked in the
ext2fs_getsize() routine on error.

Signed-off-by: Andreas Dilger <adilger@clusterfs.com>
bitmap-optimize
Andreas Dilger 2005-07-09 22:06:59 -05:00 committed by Theodore Ts'o
parent 2524785d5d
commit 9b7d811dda
6 changed files with 62 additions and 20 deletions

3
configure vendored
View File

@ -13819,7 +13819,8 @@ fi
for ac_func in chflags getrusage llseek lseek64 open64 getmntinfo strtoull strcasecmp srandom fchown mallinfo fdatasync strnlen strptime sysconf pathconf posix_memalign memalign valloc __secure_getenv prctl
for ac_func in chflags getrusage llseek lseek64 open64 fstat64 getmntinfo strtoull strcasecmp srandom fchown mallinfo fdatasync strnlen strptime sysconf pathconf posix_memalign memalign valloc __secure_getenv prctl
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5

View File

@ -628,7 +628,7 @@ AC_CHECK_MEMBER(struct sockaddr.sa_len,
[#include <sys/types.h>
#include <sys/socket.h>])
dnl
AC_CHECK_FUNCS(chflags getrusage llseek lseek64 open64 getmntinfo strtoull strcasecmp srandom fchown mallinfo fdatasync strnlen strptime sysconf pathconf posix_memalign memalign valloc __secure_getenv prctl)
AC_CHECK_FUNCS(chflags getrusage llseek lseek64 open64 fstat64 getmntinfo strtoull strcasecmp srandom fchown mallinfo fdatasync strnlen strptime sysconf pathconf posix_memalign memalign valloc __secure_getenv prctl)
dnl
dnl Check to see if -lsocket is required (solaris) to make something
dnl that uses socket() to compile; this is needed for the UUID library

View File

@ -1,3 +1,8 @@
2005-07-09 Andreas Dilger <adilger@clusterfs.com>
* getsize.c (blkid_get_dev_size): Use fstat/fstat64 to get size of
regular files.
2006-06-30 Theodore Ts'o <tytso@mit.edu>
* Release of E2fsprogs 1.38

View File

@ -31,7 +31,6 @@
#endif
#ifdef HAVE_SYS_DISKLABEL_H
#include <sys/disklabel.h>
#include <sys/stat.h>
#endif
#ifdef HAVE_SYS_DISK_H
#ifdef HAVE_SYS_QUEUE_H
@ -42,6 +41,10 @@
#ifdef __linux__
#include <sys/utsname.h>
#endif
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if defined(__linux__) && defined(_IO) && !defined(BLKGETSIZE)
#define BLKGETSIZE _IO(0x12,96) /* return device size */
@ -139,6 +142,18 @@ blkid_loff_t blkid_get_dev_size(int fd)
}
#endif
#endif /* HAVE_SYS_DISKLABEL_H */
{
#ifdef HAVE_FSTAT64
struct stat64 st;
if (fstat64(fd, &st) == 0)
#else
struct stat st;
if (fstat(fd, &st) == 0)
#endif
if (S_ISREG(st.st_mode))
return st.st_size;
}
/*
* OK, we couldn't figure it out by using a specialized ioctl,

View File

@ -1,3 +1,9 @@
2005-07-09 Andreas Dilger <adilger@clusterfs.com>
* getsize.c (ext2fs_get_device_size): Use fstat/fstat64 to get
size of regular files. Fix file descriptor leaks in error
paths.
2006-06-30 Theodore Ts'o <tytso@mit.edu>
* Release of E2fsprogs 1.38

View File

@ -41,6 +41,9 @@
#ifdef __linux__
#include <sys/utsname.h>
#endif
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if defined(__linux__) && defined(_IO) && !defined(BLKGETSIZE)
#define BLKGETSIZE _IO(0x12,96) /* return device size */
@ -137,7 +140,7 @@ static int valid_offset (int fd, ext2_loff_t offset)
errcode_t ext2fs_get_device_size(const char *file, int blocksize,
blk_t *retblocks)
{
int fd;
int fd, rc = 0;
int valid_blkgetsize64 = 1;
#ifdef __linux__
struct utsname ut;
@ -168,9 +171,8 @@ errcode_t ext2fs_get_device_size(const char *file, int blocksize,
if ((sizeof(*retblocks) < sizeof(unsigned long long))
&& ((size64 / (blocksize / 512)) > 0xFFFFFFFF))
return EFBIG;
close(fd);
*retblocks = size64 / (blocksize / 512);
return 0;
goto out;
}
#endif
@ -183,28 +185,27 @@ errcode_t ext2fs_get_device_size(const char *file, int blocksize,
#endif
if (valid_blkgetsize64 &&
ioctl(fd, BLKGETSIZE64, &size64) >= 0) {
if ((sizeof(*retblocks) < sizeof(unsigned long long))
&& ((size64 / blocksize) > 0xFFFFFFFF))
return EFBIG;
close(fd);
if ((sizeof(*retblocks) < sizeof(unsigned long long)) &&
((size64 / blocksize) > 0xFFFFFFFF)) {
rc = EFBIG;
goto out;
}
*retblocks = size64 / blocksize;
return 0;
goto out;
}
#endif
#ifdef BLKGETSIZE
if (ioctl(fd, BLKGETSIZE, &size) >= 0) {
close(fd);
*retblocks = size / (blocksize / 512);
return 0;
goto out;
}
#endif
#ifdef FDGETPRM
if (ioctl(fd, FDGETPRM, &this_floppy) >= 0) {
close(fd);
*retblocks = this_floppy.size / (blocksize / 512);
return 0;
goto out;
}
#endif
@ -215,7 +216,7 @@ errcode_t ext2fs_get_device_size(const char *file, int blocksize,
u_int bs;
if (ioctl(fd, DIOCGMEDIASIZE, &ms) >= 0) {
*retblocks = ms / blocksize;
return 0;
goto out;
}
}
#elif defined(DIOCGDINFO)
@ -233,14 +234,27 @@ errcode_t ext2fs_get_device_size(const char *file, int blocksize,
if (part >= 0 && (ioctl(fd, DIOCGDINFO, (char *)&lab) >= 0)) {
pp = &lab.d_partitions[part];
if (pp->p_size) {
close(fd);
*retblocks = pp->p_size / (blocksize / 512);
return 0;
goto out;
}
}
#endif /* defined(DIOCG*) */
#endif /* HAVE_SYS_DISKLABEL_H */
{
#ifdef HAVE_FSTAT64
struct stat64 st;
if (fstat64(fd, &st) == 0)
#else
struct stat st;
if (fstat(fd, &st) == 0)
#endif
if (S_ISREG(st.st_mode)) {
*retblocks = st.st_size / blocksize;
goto out;
}
}
/*
* OK, we couldn't figure it out by using a specialized ioctl,
* which is generally the best way. So do binary search to
@ -259,13 +273,14 @@ errcode_t ext2fs_get_device_size(const char *file, int blocksize,
high = mid;
}
valid_offset (fd, 0);
close(fd);
size64 = low + 1;
if ((sizeof(*retblocks) < sizeof(unsigned long long))
&& ((size64 / blocksize) > 0xFFFFFFFF))
return EFBIG;
*retblocks = size64 / blocksize;
return 0;
out:
close(fd);
return rc;
}
#endif /* WIN32 */