* The fs_shell is now always using BLKGETSIZE64 on Linux, and only if that fails

it will fall back to HDIO_GETGEO.
* This fixes incorrectly reported disk sizes for a number of disks I have here.
  Please open a bug report if this change causes problems for you (we would then
  have to check the kernel version to choose the preferred method).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31332 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2009-06-30 15:16:50 +00:00
parent 7413cddee6
commit b6fffec7e1
2 changed files with 26 additions and 29 deletions

View File

@ -26,11 +26,12 @@ namespace FSShell {
struct FileRestriction {
FileRestriction(fssh_dev_t device, fssh_ino_t node, fssh_off_t startOffset,
fssh_off_t endOffset)
: device(device),
node(node),
startOffset(startOffset),
endOffset(endOffset)
fssh_off_t endOffset)
:
device(device),
node(node),
startOffset(startOffset),
endOffset(endOffset)
{
}
@ -50,8 +51,7 @@ static FileRestriction*
find_file_restriction(fssh_dev_t device, fssh_ino_t node)
{
for (FileRestrictionList::iterator it = sFileRestrictions.begin();
it != sFileRestrictions.end();
++it) {
it != sFileRestrictions.end(); ++it) {
FileRestriction* restriction = *it;
if (restriction->device == device && restriction->node == node)
return restriction;

View File

@ -164,28 +164,26 @@ fssh_ioctl(int fd, unsigned long op, ...)
error = errno;
#elif defined(HAIKU_HOST_PLATFORM_LINUX)
struct hd_geometry hdGeometry;
// BLKGETSIZE and BLKGETSIZE64 don't seem to work for
// partitions. So we get the device geometry (there only seems
// to be HDIO_GETGEO, which is kind of obsolete, BTW), and
// If BLKGETSIZE64 don't work for us, we will fall back to
// HDIO_GETGEO (which is kind of obsolete, BTW), and
// get the partition size via binary search.
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;
struct hd_geometry hdGeometry;
int blockSize = 512;
off_t size;
if (ioctl(fd, BLKGETSIZE64, &size) == 0 && 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;
geometry->head_count = heads;
geometry->cylinder_count = blocks / heads;
geometry->sectors_per_track = 1;
error = B_OK;
} else if (ioctl(fd, HDIO_GETGEO, &hdGeometry) == 0) {
if (hdGeometry.heads == 0) {
error = B_ERROR;
} else {
off_t bytesPerCylinder = (off_t)hdGeometry.heads
* hdGeometry.sectors * 512;
@ -240,8 +238,7 @@ fssh_ioctl(int fd, unsigned long op, ...)
disklabel.d_secperunit = mediaSize / disklabel.d_secsize;
disklabel.d_ncylinders = mediaSize / disklabel.d_secsize
/ disklabel.d_nsectors
/ disklabel.d_ntracks;
/ disklabel.d_nsectors / disklabel.d_ntracks;
geometry->head_count = disklabel.d_ntracks;
geometry->cylinder_count = disklabel.d_ncylinders;