150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o/* 250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o * getsize.c --- get the size of a partition. 3efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore 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. 8efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * 919c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * %Begin-Header% 10543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * This file may be redistributed under the terms of the GNU Library 11543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * General Public License, version 2. 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 85efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o dev = CreateFile(file, GENERIC_READ, 86c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o FILE_SHARE_READ | FILE_SHARE_WRITE , 87efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 88efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore 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; 97efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore 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 */ 141beab8de477110970785077fb3204f171d3fcc485Jose R. Santoserrcode_t ext2fs_get_device_size2(const char *file, int blocksize, 142e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall blk64_t *retblocks) 14350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o{ 1449b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger int fd, rc = 0; 14585b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o unsigned long long size64; 14650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o ext2_loff_t high, low; 14750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 148e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall fd = ext2fs_open_file(file, O_RDONLY, 0); 14950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o if (fd < 0) 15050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o return errno; 15150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 15285b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o#ifdef DKIOCGETBLOCKCOUNT /* For Apple Darwin */ 1532c5cfbcb99f70d90f8e679bd2994b263ca6d11d6Theodore Ts'o if (ioctl(fd, DKIOCGETBLOCKCOUNT, &size64) >= 0) { 15485b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o *retblocks = size64 / (blocksize / 512); 1559b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger goto out; 15685b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o } 15785b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o#endif 15885b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o 15985b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o#ifdef BLKGETSIZE64 160e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall { 161e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall int valid_blkgetsize64 = 1; 1622c5cfbcb99f70d90f8e679bd2994b263ca6d11d6Theodore Ts'o#ifdef __linux__ 163e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall struct utsname ut; 164e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 165e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if ((uname(&ut) == 0) && 166e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ((ut.release[0] == '2') && (ut.release[1] == '.') && 167e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall (ut.release[2] < '6') && (ut.release[3] == '.'))) 168e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall valid_blkgetsize64 = 0; 1692c5cfbcb99f70d90f8e679bd2994b263ca6d11d6Theodore Ts'o#endif 170e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (valid_blkgetsize64 && 171e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ioctl(fd, BLKGETSIZE64, &size64) >= 0) { 172e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall *retblocks = size64 / blocksize; 173e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall goto out; 174e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 17585b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o } 176e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#endif /* BLKGETSIZE64 */ 17785b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o 17850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef BLKGETSIZE 179e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall { 180e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall unsigned long size; 181e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 182e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (ioctl(fd, BLKGETSIZE, &size) >= 0) { 183e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall *retblocks = size / (blocksize / 512); 184e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall goto out; 185e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 18650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o } 18750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif 18885b870034437e590e4aca77e325f3f5d6815eb39Theodore Ts'o 18950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef FDGETPRM 190e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall { 191e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall struct floppy_struct this_floppy; 192e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 193e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (ioctl(fd, FDGETPRM, &this_floppy) >= 0) { 194e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall *retblocks = this_floppy.size / (blocksize / 512); 195e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall goto out; 196e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 19750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o } 19850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif 199289e0557c24c68290b6d9b73b09674447801fdacMatthias Andree 20050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef HAVE_SYS_DISKLABEL_H 20165f0aab98b20b5994a726ab90d355248bcddfffdJP Abgrall { 202e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall int part; 203e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall struct disklabel lab; 204e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall struct partition *pp; 205e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall char ch; 206e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 207e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall#if defined(DIOCGMEDIASIZE) 208e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall { 209e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall off_t ms; 210e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall u_int bs; 211e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (ioctl(fd, DIOCGMEDIASIZE, &ms) >= 0) { 212e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall *retblocks = ms / blocksize; 213e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall goto out; 214e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 215e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 216289e0557c24c68290b6d9b73b09674447801fdacMatthias Andree#elif defined(DIOCGDINFO) 217e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall /* old disklabel interface */ 218e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall part = strlen(file) - 1; 219e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (part >= 0) { 220e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ch = file[part]; 221e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (isdigit(ch)) 222e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall part = 0; 223e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall else if (ch >= 'a' && ch <= 'h') 224e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall part = ch - 'a'; 225e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall else 226e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall part = -1; 227e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 228e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (part >= 0 && (ioctl(fd, DIOCGDINFO, (char *)&lab) >= 0)) { 229e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall pp = &lab.d_partitions[part]; 230e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (pp->p_size) { 231e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall *retblocks = pp->p_size / (blocksize / 512); 232e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall goto out; 233e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 23450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o } 23565f0aab98b20b5994a726ab90d355248bcddfffdJP Abgrall#endif /* defined(DIOCG*) */ 236e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } 23750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif /* HAVE_SYS_DISKLABEL_H */ 23850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 2399b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger { 240e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall ext2fs_struct_stat st; 241e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 242e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (ext2fs_fstat(fd, &st) == 0) 2439b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger if (S_ISREG(st.st_mode)) { 2449b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger *retblocks = st.st_size / blocksize; 2459b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger goto out; 2469b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger } 2479b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger } 2489b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger 24950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o /* 25050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o * OK, we couldn't figure it out by using a specialized ioctl, 25119c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * which is generally the best way. So do binary search to 25250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o * find the size of the partition. 25350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o */ 25450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o low = 0; 255e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall for (high = 1024; valid_offset(fd, high); high *= 2) 25650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o low = high; 257e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall while (low < high - 1) { 25850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o const ext2_loff_t mid = (low + high) / 2; 25950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o 26050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o if (valid_offset (fd, mid)) 26150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o low = mid; 26250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o else 26350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o high = mid; 26450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o } 265e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall valid_offset(fd, 0); 266283df83e7e2559f7190bb7a1dab759ccedac27abTheodore Ts'o size64 = low + 1; 267283df83e7e2559f7190bb7a1dab759ccedac27abTheodore Ts'o *retblocks = size64 / blocksize; 2689b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilgerout: 2699b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger close(fd); 2709b7d811ddad946e728d9348a78cb06dee159df96Andreas Dilger return rc; 27150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o} 272abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o 273beab8de477110970785077fb3204f171d3fcc485Jose R. Santoserrcode_t ext2fs_get_device_size(const char *file, int blocksize, 274beab8de477110970785077fb3204f171d3fcc485Jose R. Santos blk_t *retblocks) 275beab8de477110970785077fb3204f171d3fcc485Jose R. Santos{ 276beab8de477110970785077fb3204f171d3fcc485Jose R. Santos errcode_t retval; 277beab8de477110970785077fb3204f171d3fcc485Jose R. Santos blk64_t blocks; 278beab8de477110970785077fb3204f171d3fcc485Jose R. Santos 2799f7a1fc936497d5ab1ebe88baa704e91880849ccTheodore Ts'o retval = ext2fs_get_device_size2(file, blocksize, &blocks); 2809f7a1fc936497d5ab1ebe88baa704e91880849ccTheodore Ts'o if (retval) 281beab8de477110970785077fb3204f171d3fcc485Jose R. Santos return retval; 2829f7a1fc936497d5ab1ebe88baa704e91880849ccTheodore Ts'o if (blocks >= (1ULL << 32)) 2839f7a1fc936497d5ab1ebe88baa704e91880849ccTheodore Ts'o return EFBIG; 2849f7a1fc936497d5ab1ebe88baa704e91880849ccTheodore Ts'o *retblocks = (blk_t) blocks; 2859f7a1fc936497d5ab1ebe88baa704e91880849ccTheodore Ts'o return 0; 286beab8de477110970785077fb3204f171d3fcc485Jose R. Santos} 287beab8de477110970785077fb3204f171d3fcc485Jose R. Santos 288c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o#endif /* WIN32 */ 289c6928406b3d8b1437a379ab66da2b8fa389febbcTheodore Ts'o 290abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o#ifdef DEBUG 291abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'oint main(int argc, char **argv) 292abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o{ 293abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o blk_t blocks; 294abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o int retval; 295efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 296abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o if (argc < 2) { 297abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o fprintf(stderr, "Usage: %s device\n", argv[0]); 298abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o exit(1); 299abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o } 300abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o 301abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o retval = ext2fs_get_device_size(argv[1], 1024, &blocks); 302abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o if (retval) { 303abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o com_err(argv[0], retval, 304abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o "while calling ext2fs_get_device_size"); 305abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o exit(1); 306abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o } 307d0ff90d5202428583c78a60c3042e7b60d88bc45Eric Sandeen printf("Device %s has %u 1k blocks.\n", argv[1], blocks); 308abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o exit(0); 309abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o} 310abf7d3880b84994783437e291bd4e7950c4b0fe7Theodore Ts'o#endif 311