2 * getsize.c --- get the size of a partition.
4 * Copyright (C) 1995, 1995 Theodore Ts'o.
7 * This file may be redistributed under the terms of the GNU Public
12 #define _LARGEFILE_SOURCE
13 #define _LARGEFILE64_SOURCE
23 #ifdef HAVE_LINUX_FD_H
24 #include <sys/ioctl.h>
27 #ifdef HAVE_SYS_DISKLABEL_H
28 #include <sys/ioctl.h>
29 #include <sys/disklabel.h>
30 #endif /* HAVE_SYS_DISKLABEL_H */
32 #if defined(__linux__) && defined(_IO) && !defined(BLKGETSIZE)
33 #define BLKGETSIZE _IO(0x12,96) /* return device size */
36 #if EXT2_FLAT_INCLUDES
39 #include <linux/ext2_fs.h>
44 static int valid_offset (int fd
, ext2_loff_t offset
)
48 if (ext2fs_llseek (fd
, offset
, 0) < 0)
50 if (read (fd
, &ch
, 1) < 1)
56 * Returns the number of blocks in a partition
58 errcode_t
ext2fs_get_device_size(const char *file
, int blocksize
,
65 ext2_loff_t high
, low
;
67 struct floppy_struct this_floppy
;
69 #ifdef HAVE_SYS_DISKLABEL_H
74 #endif /* HAVE_SYS_DISKLABEL_H */
77 fd
= open64(file
, O_RDONLY
);
79 fd
= open(file
, O_RDONLY
);
85 if (ioctl(fd
, BLKGETSIZE
, &size
) >= 0) {
87 *retblocks
= size
/ (blocksize
/ 512);
92 if (ioctl(fd
, FDGETPRM
, &this_floppy
) >= 0) {
94 *retblocks
= this_floppy
.size
/ (blocksize
/ 512);
98 #ifdef HAVE_SYS_DISKLABEL_H
99 part
= strlen(file
) - 1;
104 else if (ch
>= 'a' && ch
<= 'h')
109 if (part
>= 0 && (ioctl(fd
, DIOCGDINFO
, (char *)&lab
) >= 0)) {
110 pp
= &lab
.d_partitions
[part
];
113 *retblocks
= pp
->p_size
/ (blocksize
/ 512);
117 #endif /* HAVE_SYS_DISKLABEL_H */
120 * OK, we couldn't figure it out by using a specialized ioctl,
121 * which is generally the best way. So do binary search to
122 * find the size of the partition.
125 for (high
= 1024; valid_offset (fd
, high
); high
*= 2)
127 while (low
< high
- 1)
129 const ext2_loff_t mid
= (low
+ high
) / 2;
131 if (valid_offset (fd
, mid
))
136 valid_offset (fd
, 0);
138 *retblocks
= (low
+ 1) / blocksize
;