From d3a580d2e08269c7d26523d1b926b18796ea2682 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 5 Dec 2007 18:33:58 +0000 Subject: [PATCH] The fs_shell now also works with devices that don't return a correct hd_geometry, but do support the BLKGETSIZE64 ioctl (it just crashed before). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23064 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/tools/fs_shell/unistd.cpp | 51 ++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/src/tools/fs_shell/unistd.cpp b/src/tools/fs_shell/unistd.cpp index 2559a19bde..b77af0fe6b 100644 --- a/src/tools/fs_shell/unistd.cpp +++ b/src/tools/fs_shell/unistd.cpp @@ -28,7 +28,8 @@ # endif # if defined(HAIKU_HOST_PLATFORM_LINUX) -# include +# include +# include # endif #endif @@ -155,22 +156,42 @@ fssh_ioctl(int fd, unsigned long op, ...) // to be HDIO_GETGEO, which is kind of obsolete, BTW), and // get the partition size via binary search. if (ioctl(fd, HDIO_GETGEO, &hdGeometry) == 0) { - off_t bytesPerCylinder = (off_t)hdGeometry.heads - * hdGeometry.sectors * 512; - off_t deviceSize = bytesPerCylinder * hdGeometry.cylinders; - off_t partitionSize = get_partition_size(fd, deviceSize); + int blockSize = 512; + if (hdGeometry.heads == 0) { + off_t size; + if (ioctl(fd, BLKGETSIZE64, &size) == 0) { + off_t blocks = size / blockSize; + uint32_t heads = (blocks + ULONG_MAX - 1) + / ULONG_MAX; + if (heads == 0) + heads = 1; - geometry->head_count = hdGeometry.heads; - geometry->cylinder_count = partitionSize / bytesPerCylinder; - geometry->sectors_per_track = hdGeometry.sectors; + geometry->head_count = heads; + geometry->cylinder_count = blocks / heads; + geometry->sectors_per_track = 1; + error = B_OK; + } else + error = errno; + } else { + off_t bytesPerCylinder = (off_t)hdGeometry.heads + * hdGeometry.sectors * 512; + off_t deviceSize = bytesPerCylinder * hdGeometry.cylinders; + off_t partitionSize = get_partition_size(fd, deviceSize); - // TODO: Get the real values... - geometry->bytes_per_sector = 512; - geometry->device_type = FSSH_B_DISK; - geometry->removable = false; - geometry->read_only = false; - geometry->write_once = false; - error = B_OK; + geometry->head_count = hdGeometry.heads; + geometry->cylinder_count = partitionSize / bytesPerCylinder; + geometry->sectors_per_track = hdGeometry.sectors; + error = B_OK; + } + + if (error == B_OK) { + // TODO: Get the real values... + geometry->bytes_per_sector = blockSize; + geometry->device_type = FSSH_B_DISK; + geometry->removable = false; + geometry->read_only = false; + geometry->write_once = false; + } } else error = errno;