diff options
author | Samuel Thibault | 2008-07-24 00:30:21 +0200 |
---|---|---|
committer | Karel Zak | 2008-07-24 00:52:52 +0200 |
commit | 268cefe6cb34fb8799b34187677154071ad45eb7 (patch) | |
tree | 7a98c7f45eae4ec54f6a150b0eaf3eb6d5c3abea /lib | |
parent | mount: s/MOUNTED/_PATH_MOUNTED/ (diff) | |
download | kernel-qcow2-util-linux-268cefe6cb34fb8799b34187677154071ad45eb7.tar.gz kernel-qcow2-util-linux-268cefe6cb34fb8799b34187677154071ad45eb7.tar.xz kernel-qcow2-util-linux-268cefe6cb34fb8799b34187677154071ad45eb7.zip |
lib: blkdev.c clean up, non-linux support
[kzak@redhat.com: split the original patch to small patches]
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/blkdev.c | 67 |
1 files changed, 59 insertions, 8 deletions
diff --git a/lib/blkdev.c b/lib/blkdev.c index 29c5d0bd4..79a366ca9 100644 --- a/lib/blkdev.c +++ b/lib/blkdev.c @@ -1,30 +1,74 @@ #include <sys/types.h> #include <sys/ioctl.h> +#include <unistd.h> #include "blkdev.h" #include "linux_version.h" +static long +blkdev_valid_offset (int fd, off_t offset) { + char ch; + + if (lseek (fd, offset, 0) < 0) + return 0; + if (read (fd, &ch, 1) < 1) + return 0; + return 1; +} + +off_t +blkdev_find_size (int fd) { + off_t high, low; + + low = 0; + for (high = 1; high > 0 && blkdev_valid_offset (fd, high); high *= 2) + low = high; + while (low < high - 1) + { + const off_t mid = (low + high) / 2; + + if (blkdev_valid_offset (fd, mid)) + low = mid; + else + high = mid; + } + blkdev_valid_offset (fd, 0); + return (low + 1); +} + /* get size in bytes */ int blkdev_get_size(int fd, unsigned long long *bytes) { - unsigned long size; - int ver = get_linux_version(); + /* TODO: use stat as well */ +#ifdef BLKGETSIZE64 +#ifdef __linux__ + int ver = get_linux_version(); /* kernels 2.4.15-2.4.17, had a broken BLKGETSIZE64 */ if (ver >= KERNEL_VERSION (2,6,0) || - (ver >= KERNEL_VERSION (2,4,18) && ver < KERNEL_VERSION (2,5,0))) { - + (ver >= KERNEL_VERSION (2,4,18) && ver < KERNEL_VERSION (2,5,0))) +#endif if (ioctl(fd, BLKGETSIZE64, bytes) >= 0) return 0; - } - if (ioctl(fd, BLKGETSIZE, &size) >= 0) { - *bytes = ((unsigned long long)size << 9); - return 0; +#endif /* BLKGETSIZE64 */ + +#ifdef BLKGETSIZE + { + unsigned long size; + + if (ioctl(fd, BLKGETSIZE, &size) >= 0) { + *bytes = ((unsigned long long)size << 9); + return 0; + } } return -1; +#endif /* BLKGETSIZE */ + + *bytes = blkdev_find_size(fd); + return 0; } /* get 512-byte sector count */ @@ -45,14 +89,21 @@ blkdev_get_sectors(int fd, unsigned long long *sectors) int blkdev_get_sector_size(int fd, int *sector_size) { +#ifdef BLKSSZGET +#ifdef __linux__ if (get_linux_version() < KERNEL_VERSION(2,3,3)) { *sector_size = DEFAULT_SECTOR_SIZE; return 0; } +#endif if (ioctl(fd, BLKSSZGET, sector_size) >= 0) return 0; return -1; +#else + *sector_size = DEFAULT_SECTOR_SIZE; + return 0; +#endif } |