25
42
blkdev_find_size (int fd) {
29
for (high = 1; high > 0 && blkdev_valid_offset (fd, high); high *= 2)
43
uintmax_t high, low = 0;
45
for (high = 1024; blkdev_valid_offset (fd, high); ) {
46
if (high == UINTMAX_MAX)
51
if (high >= UINTMAX_MAX/2)
31
57
while (low < high - 1)
33
const off_t mid = (low + high) / 2;
59
uintmax_t mid = (low + high) / 2;
35
61
if (blkdev_valid_offset (fd, mid))
46
72
blkdev_get_size(int fd, unsigned long long *bytes)
48
/* TODO: use stat as well */
74
#ifdef DKIOCGETBLOCKCOUNT
76
if (ioctl(fd, DKIOCGETBLOCKCOUNT, bytes) >= 0) {
50
82
#ifdef BLKGETSIZE64
52
int ver = get_linux_version();
53
/* kernels 2.4.15-2.4.17, had a broken BLKGETSIZE64 */
54
if (ver >= KERNEL_VERSION (2,6,0) ||
55
(ver >= KERNEL_VERSION (2,4,18) && ver < KERNEL_VERSION (2,5,0)))
85
int ver = get_linux_version();
87
/* kernels 2.4.15-2.4.17, had a broken BLKGETSIZE64 */
88
if (ver >= KERNEL_VERSION (2,6,0) ||
89
(ver >= KERNEL_VERSION (2,4,18) && ver < KERNEL_VERSION (2,5,0)))
57
if (ioctl(fd, BLKGETSIZE64, bytes) >= 0)
91
if (ioctl(fd, BLKGETSIZE64, bytes) >= 0)
59
94
#endif /* BLKGETSIZE64 */
72
106
#endif /* BLKGETSIZE */
74
#ifdef __FreeBSD_kernel__
78
if (ioctl(fd, DIOCGMEDIASIZE, &size) >= 0) {
108
#ifdef DIOCGMEDIASIZE
110
if (ioctl(fd, DIOCGMEDIASIZE, bytes) >= 0)
116
struct floppy_struct this_floppy;
118
if (ioctl(fd, FDGETPRM, &this_floppy) >= 0) {
119
*bytes = this_floppy.size << 9;
123
#endif /* FDGETPRM */
125
#ifdef HAVE_SYS_DISKLABEL_H
128
* This code works for FreeBSD 4.11 i386, except for the full device
129
* (such as /dev/ad0). It doesn't work properly for newer FreeBSD
130
* though. FreeBSD >= 5.0 should be covered by the DIOCGMEDIASIZE
133
* Note that FreeBSD >= 4.0 has disk devices as unbuffered (raw,
134
* character) devices, so we need to check for S_ISCHR, too.
137
struct disklabel lab;
138
struct partition *pp;
142
if ((fstat(fd, &st) >= 0) &&
143
(S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode)))
144
part = st.st_rdev & 7;
146
if (part >= 0 && (ioctl(fd, DIOCGDINFO, (char *)&lab) >= 0)) {
147
pp = &lab.d_partitions[part];
149
*bytes = pp->p_size << 9;
154
#endif /* HAVE_SYS_DISKLABEL_H */
159
if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) {
163
if (!S_ISBLK(st.st_mode))
85
167
*bytes = blkdev_find_size(fd);