getsize.c revision df3e159870beae4b02f1f59bf2a28e3e0fdd6519
150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o/* 250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o * getsize.c --- get the size of a partition. 350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o * 419c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * Copyright (C) 1995, 1995 Theodore Ts'o. 5c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o * Copyright (C) 2003 VMware, Inc. 619c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * 7c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o * Windows version of ext2fs_get_device_size by Chris Li, VMware. 8c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o * 919c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * %Begin-Header% 1019c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * This file may be redistributed under the terms of the GNU Public 1119c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * License. 1219c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * %End-Header% 1350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o */ 1450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 15dc5f68cad3c8ee4c583acf9afbfdb7354cd3d6afTheodore Ts'o#define _LARGEFILE_SOURCE 16dc5f68cad3c8ee4c583acf9afbfdb7354cd3d6afTheodore Ts'o#define _LARGEFILE64_SOURCE 17dc5f68cad3c8ee4c583acf9afbfdb7354cd3d6afTheodore Ts'o 1850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <stdio.h> 1950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#if HAVE_UNISTD_H 2050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <unistd.h> 2150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif 22c4e749abd8451f02418fe552b2af14f226f7bd1eTheodore Ts'o#if HAVE_ERRNO_H 23c4e749abd8451f02418fe552b2af14f226f7bd1eTheodore Ts'o#include <errno.h> 24c4e749abd8451f02418fe552b2af14f226f7bd1eTheodore Ts'o#endif 2550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <fcntl.h> 269845cf5dbd4d06ebc1fe0db99078d7a0be641e0aTheodore Ts'o#ifdef HAVE_SYS_IOCTL_H 2750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <sys/ioctl.h> 289845cf5dbd4d06ebc1fe0db99078d7a0be641e0aTheodore Ts'o#endif 299845cf5dbd4d06ebc1fe0db99078d7a0be641e0aTheodore Ts'o#ifdef HAVE_LINUX_FD_H 3050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <linux/fd.h> 3150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif 3250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef HAVE_SYS_DISKLABEL_H 3350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <sys/disklabel.h> 349845cf5dbd4d06ebc1fe0db99078d7a0be641e0aTheodore Ts'o#endif 35b34cbddbd66baedc163d36dd281b63ef478f547aMatthias Andree#ifdef HAVE_SYS_DISK_H 369845cf5dbd4d06ebc1fe0db99078d7a0be641e0aTheodore Ts'o#ifdef HAVE_SYS_QUEUE_H 37b34cbddbd66baedc163d36dd281b63ef478f547aMatthias Andree#include <sys/queue.h> /* for LIST_HEAD */ 389845cf5dbd4d06ebc1fe0db99078d7a0be641e0aTheodore Ts'o#endif 39b34cbddbd66baedc163d36dd281b63ef478f547aMatthias Andree#include <sys/disk.h> 409845cf5dbd4d06ebc1fe0db99078d7a0be641e0aTheodore Ts'o#endif 412c5cfbcb99f70d90f8e679bd2994b263ca6d11d6Theodore Ts'o#ifdef __linux__ 422c5cfbcb99f70d90f8e679bd2994b263ca6d11d6Theodore Ts'o#include <sys/utsname.h> 432c5cfbcb99f70d90f8e679bd2994b263ca6d11d6Theodore Ts'o#endif 449b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger#if HAVE_SYS_STAT_H 459b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger#include <sys/stat.h> 469b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger#endif 47df3e159870beae4b02f1f59bf2a28e3e0fdd6519Matthias Andree#include <ctype.h> 4850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 497fd86d396745cf38ed5a3b91d1570440a8e770a1Theodore Ts'o#if defined(__linux__) && defined(_IO) && !defined(BLKGETSIZE) 507fd86d396745cf38ed5a3b91d1570440a8e770a1Theodore Ts'o#define BLKGETSIZE _IO(0x12,96) /* return device size */ 517fd86d396745cf38ed5a3b91d1570440a8e770a1Theodore Ts'o#endif 527fd86d396745cf38ed5a3b91d1570440a8e770a1Theodore Ts'o 5385b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o#if defined(__linux__) && defined(_IOR) && !defined(BLKGETSIZE64) 5485b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o#define BLKGETSIZE64 _IOR(0x12,114,size_t) /* return device size in bytes (u64 *arg) */ 5585b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o#endif 5685b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o 57e71d87317ac095fa08079f0cc9040da16952eb93Theodore Ts'o#ifdef APPLE_DARWIN 58e71d87317ac095fa08079f0cc9040da16952eb93Theodore Ts'o#define BLKGETSIZE DKIOCGETBLOCKCOUNT32 59e71d87317ac095fa08079f0cc9040da16952eb93Theodore Ts'o#endif /* APPLE_DARWIN */ 60e71d87317ac095fa08079f0cc9040da16952eb93Theodore Ts'o 61b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o#include "ext2_fs.h" 6250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include "ext2fs.h" 6350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 64c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o#if defined(__CYGWIN__) || defined (WIN32) 65c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o#include "windows.h" 66c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o#include "winioctl.h" 67c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o 681a9c8c35ba148e55039bd04e0237085f7a3625d1Theodore Ts'o#if (_WIN32_WINNT >= 0x0500) 691a9c8c35ba148e55039bd04e0237085f7a3625d1Theodore Ts'o#define HAVE_GET_FILE_SIZE_EX 1 701a9c8c35ba148e55039bd04e0237085f7a3625d1Theodore Ts'o#endif 711a9c8c35ba148e55039bd04e0237085f7a3625d1Theodore Ts'o 72c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'oerrcode_t ext2fs_get_device_size(const char *file, int blocksize, 73c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o blk_t *retblocks) 74c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o{ 75c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o HANDLE dev; 76c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o PARTITION_INFORMATION pi; 77c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o DISK_GEOMETRY gi; 78c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o DWORD retbytes; 791a9c8c35ba148e55039bd04e0237085f7a3625d1Theodore Ts'o#ifdef HAVE_GET_FILE_SIZE_EX 8005a27b1d34fc566a3f11b086a4f6e7b7888b5406Theodore Ts'o LARGE_INTEGER filesize; 811a9c8c35ba148e55039bd04e0237085f7a3625d1Theodore Ts'o#else 821a9c8c35ba148e55039bd04e0237085f7a3625d1Theodore Ts'o DWORD filesize; 831a9c8c35ba148e55039bd04e0237085f7a3625d1Theodore Ts'o#endif /* HAVE_GET_FILE_SIZE_EX */ 84c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o 85c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o dev = CreateFile(file, GENERIC_READ, 86c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o FILE_SHARE_READ | FILE_SHARE_WRITE , 87c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 88c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o 89c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o if (dev == INVALID_HANDLE_VALUE) 90c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o return EBADF; 91c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o if (DeviceIoControl(dev, IOCTL_DISK_GET_PARTITION_INFO, 92c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o &pi, sizeof(PARTITION_INFORMATION), 93c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o &pi, sizeof(PARTITION_INFORMATION), 94c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o &retbytes, NULL)) { 95c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o 96c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o *retblocks = pi.PartitionLength.QuadPart / blocksize; 97c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o 98c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o } else if (DeviceIoControl(dev, IOCTL_DISK_GET_DRIVE_GEOMETRY, 99c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o &gi, sizeof(DISK_GEOMETRY), 100c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o &gi, sizeof(DISK_GEOMETRY), 101c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o &retbytes, NULL)) { 102c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o 103c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o *retblocks = gi.BytesPerSector * 104c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o gi.SectorsPerTrack * 105c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o gi.TracksPerCylinder * 106c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o gi.Cylinders.QuadPart / blocksize; 10705a27b1d34fc566a3f11b086a4f6e7b7888b5406Theodore Ts'o 1081a9c8c35ba148e55039bd04e0237085f7a3625d1Theodore Ts'o#ifdef HAVE_GET_FILE_SIZE_EX 10905a27b1d34fc566a3f11b086a4f6e7b7888b5406Theodore Ts'o } else if (GetFileSizeEx(dev, &filesize)) { 11005a27b1d34fc566a3f11b086a4f6e7b7888b5406Theodore Ts'o *retblocks = filesize.QuadPart / blocksize; 111c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o } 1121a9c8c35ba148e55039bd04e0237085f7a3625d1Theodore Ts'o#else 1131a9c8c35ba148e55039bd04e0237085f7a3625d1Theodore Ts'o } else { 1141a9c8c35ba148e55039bd04e0237085f7a3625d1Theodore Ts'o filesize = GetFileSize(dev, NULL); 1151a9c8c35ba148e55039bd04e0237085f7a3625d1Theodore Ts'o if (INVALID_FILE_SIZE != filesize) { 1161a9c8c35ba148e55039bd04e0237085f7a3625d1Theodore Ts'o *retblocks = filesize / blocksize; 1171a9c8c35ba148e55039bd04e0237085f7a3625d1Theodore Ts'o } 1181a9c8c35ba148e55039bd04e0237085f7a3625d1Theodore Ts'o } 1191a9c8c35ba148e55039bd04e0237085f7a3625d1Theodore Ts'o#endif /* HAVE_GET_FILE_SIZE_EX */ 120c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o 121c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o CloseHandle(dev); 122c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o return 0; 123c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o} 124c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o 125c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o#else 126c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o 12750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'ostatic int valid_offset (int fd, ext2_loff_t offset) 12850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o{ 12950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o char ch; 13050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 13119c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o if (ext2fs_llseek (fd, offset, 0) < 0) 13250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o return 0; 13350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o if (read (fd, &ch, 1) < 1) 13450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o return 0; 13550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o return 1; 13650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o} 13750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 13850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o/* 13950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o * Returns the number of blocks in a partition 14050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o */ 14150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'oerrcode_t ext2fs_get_device_size(const char *file, int blocksize, 14250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o blk_t *retblocks) 14350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o{ 1449b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger int fd, rc = 0; 1452c5cfbcb99f70d90f8e679bd2994b263ca6d11d6Theodore Ts'o int valid_blkgetsize64 = 1; 1462c5cfbcb99f70d90f8e679bd2994b263ca6d11d6Theodore Ts'o#ifdef __linux__ 1472c5cfbcb99f70d90f8e679bd2994b263ca6d11d6Theodore Ts'o struct utsname ut; 1482c5cfbcb99f70d90f8e679bd2994b263ca6d11d6Theodore Ts'o#endif 14985b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o unsigned long long size64; 150954a683dd0353d280d56b3d70b5e8f24e88b3d2fTheodore Ts'o unsigned long size; 15150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o ext2_loff_t high, low; 15250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef FDGETPRM 15350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o struct floppy_struct this_floppy; 15450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif 15550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef HAVE_SYS_DISKLABEL_H 15619c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o int part; 15750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o struct disklabel lab; 15850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o struct partition *pp; 15950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o char ch; 16050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif /* HAVE_SYS_DISKLABEL_H */ 16150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 162dc5f68cad3c8ee4c583acf9afbfdb7354cd3d6afTheodore Ts'o#ifdef HAVE_OPEN64 163dc5f68cad3c8ee4c583acf9afbfdb7354cd3d6afTheodore Ts'o fd = open64(file, O_RDONLY); 164dc5f68cad3c8ee4c583acf9afbfdb7354cd3d6afTheodore Ts'o#else 1657f88b04341d88c5df0360d930832c38040303b61Theodore Ts'o fd = open(file, O_RDONLY); 166dc5f68cad3c8ee4c583acf9afbfdb7354cd3d6afTheodore Ts'o#endif 16750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o if (fd < 0) 16850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o return errno; 16950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 17085b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o#ifdef DKIOCGETBLOCKCOUNT /* For Apple Darwin */ 1712c5cfbcb99f70d90f8e679bd2994b263ca6d11d6Theodore Ts'o if (ioctl(fd, DKIOCGETBLOCKCOUNT, &size64) >= 0) { 17285b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o if ((sizeof(*retblocks) < sizeof(unsigned long long)) 17385b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o && ((size64 / (blocksize / 512)) > 0xFFFFFFFF)) 17485b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o return EFBIG; 17585b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o *retblocks = size64 / (blocksize / 512); 1769b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger goto out; 17785b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o } 17885b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o#endif 17985b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o 18085b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o#ifdef BLKGETSIZE64 1812c5cfbcb99f70d90f8e679bd2994b263ca6d11d6Theodore Ts'o#ifdef __linux__ 1822c5cfbcb99f70d90f8e679bd2994b263ca6d11d6Theodore Ts'o if ((uname(&ut) == 0) && 1832c5cfbcb99f70d90f8e679bd2994b263ca6d11d6Theodore Ts'o ((ut.release[0] == '2') && (ut.release[1] == '.') && 1842c5cfbcb99f70d90f8e679bd2994b263ca6d11d6Theodore Ts'o (ut.release[2] < '6') && (ut.release[3] == '.'))) 1852c5cfbcb99f70d90f8e679bd2994b263ca6d11d6Theodore Ts'o valid_blkgetsize64 = 0; 1862c5cfbcb99f70d90f8e679bd2994b263ca6d11d6Theodore Ts'o#endif 1872c5cfbcb99f70d90f8e679bd2994b263ca6d11d6Theodore Ts'o if (valid_blkgetsize64 && 1882c5cfbcb99f70d90f8e679bd2994b263ca6d11d6Theodore Ts'o ioctl(fd, BLKGETSIZE64, &size64) >= 0) { 1899b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger if ((sizeof(*retblocks) < sizeof(unsigned long long)) && 1909b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger ((size64 / blocksize) > 0xFFFFFFFF)) { 1919b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger rc = EFBIG; 1929b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger goto out; 1939b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger } 19485b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o *retblocks = size64 / blocksize; 1959b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger goto out; 19685b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o } 19785b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o#endif 19885b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o 19950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef BLKGETSIZE 20050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o if (ioctl(fd, BLKGETSIZE, &size) >= 0) { 20150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o *retblocks = size / (blocksize / 512); 2029b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger goto out; 20350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o } 20450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif 20585b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o 20650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef FDGETPRM 20750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o if (ioctl(fd, FDGETPRM, &this_floppy) >= 0) { 20850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o *retblocks = this_floppy.size / (blocksize / 512); 2099b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger goto out; 21050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o } 21150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif 212289e0557c24c68290b6d9b73b09674447801fdacMatthias Andree 21350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef HAVE_SYS_DISKLABEL_H 214289e0557c24c68290b6d9b73b09674447801fdacMatthias Andree#if defined(DIOCGMEDIASIZE) 215289e0557c24c68290b6d9b73b09674447801fdacMatthias Andree { 216289e0557c24c68290b6d9b73b09674447801fdacMatthias Andree off_t ms; 217289e0557c24c68290b6d9b73b09674447801fdacMatthias Andree u_int bs; 218289e0557c24c68290b6d9b73b09674447801fdacMatthias Andree if (ioctl(fd, DIOCGMEDIASIZE, &ms) >= 0) { 219289e0557c24c68290b6d9b73b09674447801fdacMatthias Andree *retblocks = ms / blocksize; 2209b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger goto out; 221289e0557c24c68290b6d9b73b09674447801fdacMatthias Andree } 222289e0557c24c68290b6d9b73b09674447801fdacMatthias Andree } 223289e0557c24c68290b6d9b73b09674447801fdacMatthias Andree#elif defined(DIOCGDINFO) 224b34cbddbd66baedc163d36dd281b63ef478f547aMatthias Andree /* old disklabel interface */ 22519c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o part = strlen(file) - 1; 22619c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o if (part >= 0) { 22719c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o ch = file[part]; 22850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o if (isdigit(ch)) 22919c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o part = 0; 23050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o else if (ch >= 'a' && ch <= 'h') 23119c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o part = ch - 'a'; 23250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o else 23319c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o part = -1; 23450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o } 23519c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o if (part >= 0 && (ioctl(fd, DIOCGDINFO, (char *)&lab) >= 0)) { 23619c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o pp = &lab.d_partitions[part]; 23750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o if (pp->p_size) { 23850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o *retblocks = pp->p_size / (blocksize / 512); 2399b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger goto out; 24050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o } 24150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o } 242289e0557c24c68290b6d9b73b09674447801fdacMatthias Andree#endif /* defined(DIOCG*) */ 24350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif /* HAVE_SYS_DISKLABEL_H */ 24450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 2459b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger { 2469b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger#ifdef HAVE_FSTAT64 2479b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger struct stat64 st; 2489b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger if (fstat64(fd, &st) == 0) 2499b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger#else 2509b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger struct stat st; 2519b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger if (fstat(fd, &st) == 0) 2529b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger#endif 2539b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger if (S_ISREG(st.st_mode)) { 2549b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger *retblocks = st.st_size / blocksize; 2559b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger goto out; 2569b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger } 2579b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger } 2589b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger 25950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o /* 26050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o * OK, we couldn't figure it out by using a specialized ioctl, 26119c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * which is generally the best way. So do binary search to 26250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o * find the size of the partition. 26350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o */ 26450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o low = 0; 26550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o for (high = 1024; valid_offset (fd, high); high *= 2) 26650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o low = high; 26750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o while (low < high - 1) 26850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o { 26950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o const ext2_loff_t mid = (low + high) / 2; 27050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 27150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o if (valid_offset (fd, mid)) 27250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o low = mid; 27350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o else 27450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o high = mid; 27550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o } 27650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o valid_offset (fd, 0); 277283df83e7e2559f7190bb7a1dab759ccedac27abTheodore Ts'o size64 = low + 1; 278283df83e7e2559f7190bb7a1dab759ccedac27abTheodore Ts'o if ((sizeof(*retblocks) < sizeof(unsigned long long)) 279283df83e7e2559f7190bb7a1dab759ccedac27abTheodore Ts'o && ((size64 / blocksize) > 0xFFFFFFFF)) 280283df83e7e2559f7190bb7a1dab759ccedac27abTheodore Ts'o return EFBIG; 281283df83e7e2559f7190bb7a1dab759ccedac27abTheodore Ts'o *retblocks = size64 / blocksize; 2829b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilgerout: 2839b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger close(fd); 2849b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger return rc; 28550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o} 286abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o 287c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o#endif /* WIN32 */ 288c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o 289abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o#ifdef DEBUG 290abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'oint main(int argc, char **argv) 291abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o{ 292abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o blk_t blocks; 293abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o int retval; 294abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o 295abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o if (argc < 2) { 296abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o fprintf(stderr, "Usage: %s device\n", argv[0]); 297abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o exit(1); 298abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o } 299abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o 300abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o retval = ext2fs_get_device_size(argv[1], 1024, &blocks); 301abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o if (retval) { 302abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o com_err(argv[0], retval, 303abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o "while calling ext2fs_get_device_size"); 304abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o exit(1); 305abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o } 306abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o printf("Device %s has %d 1k blocks.\n", argv[1], blocks); 307abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o exit(0); 308abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o} 309abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o#endif 310