Whamcloud - gitweb
This patch adds a check to use fstat or fstat64 in getsize.c if the
authorAndreas Dilger <adilger@clusterfs.com>
Sun, 10 Jul 2005 03:06:59 +0000 (22:06 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Sun, 10 Jul 2005 03:06:59 +0000 (22:06 -0500)
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>
configure
configure.in
lib/blkid/ChangeLog
lib/blkid/getsize.c
lib/ext2fs/ChangeLog
lib/ext2fs/getsize.c

index 9b267e2..b22a201 100755 (executable)
--- a/configure
+++ b/configure
@@ -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
index c9600f0..1c1351a 100644 (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
index 5f77116..767f11e 100644 (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
index d45e1c2..75bec52 100644 (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
 #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,
index aeb8dce..58e29a9 100644 (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
index 0c7355f..d59a893 100644 (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 */