diff options
author | Karel Zak <kzak@redhat.com> | 2010-03-16 17:31:39 +0100 |
---|---|---|
committer | Karel Zak <kzak@redhat.com> | 2010-03-16 17:31:39 +0100 |
commit | abbd79ac35ca4ad65f2bba55288652db907a514e (patch) | |
tree | 69fdc8f21d8b9530da05f4cbf704f21657becd68 | |
parent | b8d22034f1b393a48ce7af9e15d910bf0e29df0b (diff) | |
download | util-linux-old-abbd79ac35ca4ad65f2bba55288652db907a514e.tar.gz |
lib: fix blkdev_find_size()
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>
-rw-r--r-- | lib/blkdev.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/lib/blkdev.c b/lib/blkdev.c index 4b9e6fc6..7d00324d 100644 --- a/lib/blkdev.c +++ b/lib/blkdev.c @@ -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); |