getsize.c revision 7270fbe7fa51cbce01a07d031f03872f314206d1
1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * getsize.c --- get the size of a partition. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Copyright (C) 1995, 1995 Theodore Ts'o. 5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) * Copyright (C) 2003 VMware, Inc. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Windows version of ext2fs_get_device_size by Chris Li, VMware. 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * %Begin-Header% 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * This file may be redistributed under the terms of the GNU Library 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * General Public License, version 2. 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * %End-Header% 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) */ 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define _LARGEFILE_SOURCE 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define _LARGEFILE64_SOURCE 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "config.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdio.h> 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if HAVE_UNISTD_H 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h> 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if HAVE_ERRNO_H 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h> 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fcntl.h> 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_SYS_IOCTL_H 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/ioctl.h> 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_LINUX_FD_H 3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include <linux/fd.h> 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_SYS_DISKLABEL_H 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/disklabel.h> 35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_SYS_DISK_H 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_SYS_QUEUE_H 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/queue.h> /* for LIST_HEAD */ 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <sys/disk.h> 415e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#endif 42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#ifdef __linux__ 434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <sys/utsname.h> 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if HAVE_SYS_STAT_H 467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include <sys/stat.h> 47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <ctype.h> 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(__linux__) && defined(_IO) && !defined(BLKGETSIZE) 5190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#define BLKGETSIZE _IO(0x12,96) /* return device size */ 5290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#endif 53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(__linux__) && defined(_IOR) && !defined(BLKGETSIZE64) 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define BLKGETSIZE64 _IOR(0x12,114,size_t) /* return device size in bytes (u64 *arg) */ 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifdef APPLE_DARWIN 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BLKGETSIZE DKIOCGETBLOCKCOUNT32 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif /* APPLE_DARWIN */ 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ext2_fs.h" 638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "ext2fs.h" 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(__CYGWIN__) || defined (WIN32) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "windows.h" 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "winioctl.h" 6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if (_WIN32_WINNT >= 0x0500) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define HAVE_GET_FILE_SIZE_EX 1 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 72bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)errcode_t ext2fs_get_device_size(const char *file, int blocksize, 747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) blk_t *retblocks) 75ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch{ 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HANDLE dev; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PARTITION_INFORMATION pi; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISK_GEOMETRY gi; 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DWORD retbytes; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_GET_FILE_SIZE_EX 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LARGE_INTEGER filesize; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DWORD filesize; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* HAVE_GET_FILE_SIZE_EX */ 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) dev = CreateFile(file, GENERIC_READ, 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FILE_SHARE_READ | FILE_SHARE_WRITE , 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (dev == INVALID_HANDLE_VALUE) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return EBADF; 92effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (DeviceIoControl(dev, IOCTL_DISK_GET_PARTITION_INFO, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &pi, sizeof(PARTITION_INFORMATION), 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &pi, sizeof(PARTITION_INFORMATION), 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &retbytes, NULL)) { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *retblocks = pi.PartitionLength.QuadPart / blocksize; 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (DeviceIoControl(dev, IOCTL_DISK_GET_DRIVE_GEOMETRY, 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &gi, sizeof(DISK_GEOMETRY), 101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) &gi, sizeof(DISK_GEOMETRY), 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &retbytes, NULL)) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *retblocks = gi.BytesPerSector * 105eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch gi.SectorsPerTrack * 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gi.TracksPerCylinder * 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gi.Cylinders.QuadPart / blocksize; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifdef HAVE_GET_FILE_SIZE_EX 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (GetFileSizeEx(dev, &filesize)) { 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *retblocks = filesize.QuadPart / blocksize; 11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#else 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 115bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch filesize = GetFileSize(dev, NULL); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (INVALID_FILE_SIZE != filesize) { 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *retblocks = filesize / blocksize; 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* HAVE_GET_FILE_SIZE_EX */ 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseHandle(dev); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static int valid_offset (int fd, ext2_loff_t offset) 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles){ 130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch char ch; 131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (ext2fs_llseek (fd, offset, 0) < 0) 133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 0; 134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (read (fd, &ch, 1) < 1) 135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return 0; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the number of blocks in a partition 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)errcode_t ext2fs_get_device_size2(const char *file, int blocksize, 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) blk64_t *retblocks) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int fd, rc = 0; 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int valid_blkgetsize64 = 1; 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifdef __linux__ 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct utsname ut; 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 150c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch unsigned long long size64; 151c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch unsigned long size; 152c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ext2_loff_t high, low; 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifdef FDGETPRM 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) struct floppy_struct this_floppy; 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifdef HAVE_SYS_DISKLABEL_H 157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int part; 158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) struct disklabel lab; 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) struct partition *pp; 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) char ch; 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif /* HAVE_SYS_DISKLABEL_H */ 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) fd = ext2fs_open_file(file, O_RDONLY, 0); 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (fd < 0) 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return errno; 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#ifdef DKIOCGETBLOCKCOUNT /* For Apple Darwin */ 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (ioctl(fd, DKIOCGETBLOCKCOUNT, &size64) >= 0) { 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *retblocks = size64 / (blocksize / 512); 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) goto out; 171c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#ifdef BLKGETSIZE64 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#ifdef __linux__ 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if ((uname(&ut) == 0) && 177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ((ut.release[0] == '2') && (ut.release[1] == '.') && 178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (ut.release[2] < '6') && (ut.release[3] == '.'))) 179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) valid_blkgetsize64 = 0; 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif 181c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (valid_blkgetsize64 && 182c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ioctl(fd, BLKGETSIZE64, &size64) >= 0) { 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *retblocks = size64 / blocksize; 184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) goto out; 185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif /* BLKGETSIZE64 */ 187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#ifdef BLKGETSIZE 189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (ioctl(fd, BLKGETSIZE, &size) >= 0) { 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *retblocks = size / (blocksize / 512); 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) goto out; 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#ifdef FDGETPRM 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (ioctl(fd, FDGETPRM, &this_floppy) >= 0) { 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *retblocks = this_floppy.size / (blocksize / 512); 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) goto out; 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef HAVE_SYS_DISKLABEL_H 203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(DIOCGMEDIASIZE) 204c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) off_t ms; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) u_int bs; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ioctl(fd, DIOCGMEDIASIZE, &ms) >= 0) { 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *retblocks = ms / blocksize; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto out; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(DIOCGDINFO) 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /* old disklabel interface */ 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) part = strlen(file) - 1; 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (part >= 0) { 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ch = file[part]; 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (isdigit(ch)) 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) part = 0; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (ch >= 'a' && ch <= 'h') 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) part = ch - 'a'; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 222effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch part = -1; 223effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 224effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (part >= 0 && (ioctl(fd, DIOCGDINFO, (char *)&lab) >= 0)) { 2250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) pp = &lab.d_partitions[part]; 2260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (pp->p_size) { 2273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) *retblocks = pp->p_size / (blocksize / 512); 2283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) goto out; 2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) } 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 231effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#endif /* defined(DIOCG*) */ 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif /* HAVE_SYS_DISKLABEL_H */ 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ext2fs_struct_stat st; 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (ext2fs_fstat(fd, &st) == 0) 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (S_ISREG(st.st_mode)) { 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *retblocks = st.st_size / blocksize; 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) goto out; 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /* 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * OK, we couldn't figure it out by using a specialized ioctl, 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * which is generally the best way. So do binary search to 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * find the size of the partition. 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) low = 0; 250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (high = 1024; valid_offset (fd, high); high *= 2) 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) low = high; 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) while (low < high - 1) 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) { 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ext2_loff_t mid = (low + high) / 2; 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (valid_offset (fd, mid)) 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) low = mid; 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) high = mid; 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) valid_offset (fd, 0); 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) size64 = low + 1; 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *retblocks = size64 / blocksize; 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)out: 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) close(fd); 26690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return rc; 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)errcode_t ext2fs_get_device_size(const char *file, int blocksize, 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) blk_t *retblocks) 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){ 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) errcode_t retval; 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) blk64_t blocks; 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) retval = ext2fs_get_device_size2(file, blocksize, &blocks); 276a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (retval) 277a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return retval; 278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (blocks >= (1ULL << 32)) 279a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return EFBIG; 280a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *retblocks = (blk_t) blocks; 281a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return 0; 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif /* WIN32 */ 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int main(int argc, char **argv) 288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles){ 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) blk_t blocks; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int retval; 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (argc < 2) { 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fprintf(stderr, "Usage: %s device\n", argv[0]); 294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) exit(1); 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 29758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) retval = ext2fs_get_device_size(argv[1], 1024, &blocks); 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (retval) { 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) com_err(argv[0], retval, 300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "while calling ext2fs_get_device_size"); 301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) exit(1); 302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 303a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) printf("Device %s has %u 1k blocks.\n", argv[1], blocks); 304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) exit(0); 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)