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
This commit is contained in:
Axel Dörfler
2007-12-05 18:33:58 +00:00
parent ebe41f1a76
commit d3a580d2e0
+23 -2
View File
@@ -29,6 +29,7 @@
# if defined(HAIKU_HOST_PLATFORM_LINUX) # if defined(HAIKU_HOST_PLATFORM_LINUX)
# include <linux/hdreg.h> # include <linux/hdreg.h>
# include <linux/fs.h>
# endif # endif
#endif #endif
@@ -155,6 +156,23 @@ fssh_ioctl(int fd, unsigned long op, ...)
// to be HDIO_GETGEO, which is kind of obsolete, BTW), and // to be HDIO_GETGEO, which is kind of obsolete, BTW), and
// get the partition size via binary search. // get the partition size via binary search.
if (ioctl(fd, HDIO_GETGEO, &hdGeometry) == 0) { if (ioctl(fd, HDIO_GETGEO, &hdGeometry) == 0) {
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 = 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 off_t bytesPerCylinder = (off_t)hdGeometry.heads
* hdGeometry.sectors * 512; * hdGeometry.sectors * 512;
off_t deviceSize = bytesPerCylinder * hdGeometry.cylinders; off_t deviceSize = bytesPerCylinder * hdGeometry.cylinders;
@@ -163,14 +181,17 @@ fssh_ioctl(int fd, unsigned long op, ...)
geometry->head_count = hdGeometry.heads; geometry->head_count = hdGeometry.heads;
geometry->cylinder_count = partitionSize / bytesPerCylinder; geometry->cylinder_count = partitionSize / bytesPerCylinder;
geometry->sectors_per_track = hdGeometry.sectors; geometry->sectors_per_track = hdGeometry.sectors;
error = B_OK;
}
if (error == B_OK) {
// TODO: Get the real values... // TODO: Get the real values...
geometry->bytes_per_sector = 512; geometry->bytes_per_sector = blockSize;
geometry->device_type = FSSH_B_DISK; geometry->device_type = FSSH_B_DISK;
geometry->removable = false; geometry->removable = false;
geometry->read_only = false; geometry->read_only = false;
geometry->write_once = false; geometry->write_once = false;
error = B_OK; }
} else } else
error = errno; error = errno;