]> err.no Git - util-linux/commitdiff
lib: fix blkdev_find_size()
authorKarel Zak <kzak@redhat.com>
Tue, 16 Mar 2010 16:31:39 +0000 (17:31 +0100)
committerKarel Zak <kzak@redhat.com>
Tue, 16 Mar 2010 16:31:39 +0000 (17:31 +0100)
echo l | fdisk/fdisk /dev/zero

FYI that however now spins forever doing:

offset=3074457345618258603)
    at ../lib/blkdev.c:31
    at ../lib/blkdev.c:151
    at ../lib/blkdev.c:161

Reported-by: Pádraig Brady <P@draigBrady.com>
Signed-off-by: Karel Zak <kzak@redhat.com>
lib/blkdev.c

index 4b9e6fc672fceb037012c30f93275b36dfcf4c59..7d00324dafd3fb2decfa5bc110d2e57fb066d0d7 100644 (file)
@@ -3,6 +3,7 @@
 #include <sys/stat.h>
 #include <sys/ioctl.h>
 #include <unistd.h>
+#include <stdint.h>
 
 #ifdef HAVE_LINUX_FD_H
 #include <linux/fd.h>
@@ -35,14 +36,23 @@ blkdev_valid_offset (int fd, off_t offset) {
 
 off_t
 blkdev_find_size (int fd) {
-       off_t high, low;
+       uintmax_t high, low = 0;
+
+       for (high = 1024; blkdev_valid_offset (fd, high); ) {
+               if (high == UINTMAX_MAX)
+                       return -1;
 
-       low = 0;
-       for (high = 1; high > 0 && blkdev_valid_offset (fd, high); high *= 2)
                low = high;
+
+               if (high >= UINTMAX_MAX/2)
+                       high = UINTMAX_MAX;
+               else
+                       high *= 2;
+       }
+
        while (low < high - 1)
        {
-               const off_t mid = (low + high) / 2;
+               uintmax_t mid = (low + high) / 2;
 
                if (blkdev_valid_offset (fd, mid))
                        low = mid;
@@ -146,6 +156,8 @@ blkdev_get_size(int fd, unsigned long long *bytes)
                        *bytes = st.st_size;
                        return 0;
                }
+               if (!S_ISBLK(st.st_mode))
+                       return -1;
        }
 
        *bytes = blkdev_find_size(fd);