* We map ioctl() to the build platform manually now. For Linux we
implement the B_GET_GEOMETRY command in a usable way. The bfs_shell is able to play with partition devices under Linux, now. * Fixed two warnings. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16146 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
51855db4b0
commit
4b0e1b9bda
@ -53,6 +53,7 @@ SYSHDRS = $(HAIKU_HDRS) ;
|
||||
close=build_platform_close
|
||||
fstat=build_platform_fstat
|
||||
read_pos=build_platform_read_pos
|
||||
ioctl=build_platform_ioctl
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -15,13 +15,20 @@
|
||||
*/
|
||||
#include "compat.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "stat_util.h"
|
||||
|
||||
// Linux support
|
||||
#ifdef HAIKU_HOST_PLATFORM_LINUX
|
||||
# include <linux/hdreg.h>
|
||||
#endif // HAIKU_HOST_PLATFORM_LINUX
|
||||
|
||||
|
||||
// Let the FS think, we are the root user.
|
||||
uid_t
|
||||
@ -200,7 +207,7 @@ readv_pos(int fd, fs_off_t _pos, const struct iovec *iov, int count)
|
||||
off_t pos = (off_t)_pos;
|
||||
size_t amt = 0;
|
||||
ssize_t ret;
|
||||
struct iovec *tmpiov;
|
||||
const struct iovec *tmpiov;
|
||||
int i, n;
|
||||
|
||||
if (lseek(fd, pos, SEEK_SET) < 0) {
|
||||
@ -235,7 +242,7 @@ writev_pos(int fd, fs_off_t _pos, const struct iovec *iov, int count)
|
||||
off_t pos = (off_t)_pos;
|
||||
size_t amt = 0;
|
||||
ssize_t ret;
|
||||
struct iovec *tmpiov;
|
||||
const struct iovec *tmpiov;
|
||||
int i, n;
|
||||
|
||||
if (lseek(fd, pos, SEEK_SET) < 0) {
|
||||
@ -333,6 +340,110 @@ build_platform_read_pos(int fd, fs_off_t pos, void *buf, size_t count)
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAIKU_HOST_PLATFORM_LINUX
|
||||
|
||||
static bool
|
||||
test_size(int fd, off_t size)
|
||||
{
|
||||
char buffer[1];
|
||||
|
||||
if (size == 0)
|
||||
return true;
|
||||
|
||||
if (lseek(fd, size - 1, SEEK_SET) < 0)
|
||||
return false;
|
||||
|
||||
return (read(fd, &buffer, 1) == 1);
|
||||
}
|
||||
|
||||
|
||||
static off_t
|
||||
get_partition_size(int fd, off_t maxSize)
|
||||
{
|
||||
// binary search
|
||||
off_t lower = 0;
|
||||
off_t upper = maxSize;
|
||||
while (lower < upper) {
|
||||
off_t mid = (lower + upper + 1) / 2;
|
||||
if (test_size(fd, mid))
|
||||
lower = mid;
|
||||
else
|
||||
upper = mid - 1;
|
||||
}
|
||||
|
||||
return lower;
|
||||
}
|
||||
|
||||
#endif // HAIKU_HOST_PLATFORM_LINUX
|
||||
|
||||
|
||||
extern int build_platform_ioctl(int fd, unsigned long op, ...);
|
||||
|
||||
int
|
||||
build_platform_ioctl(int fd, unsigned long op, ...)
|
||||
{
|
||||
status_t error = FS_BAD_VALUE;
|
||||
va_list list;
|
||||
|
||||
// count arguments
|
||||
|
||||
va_start(list, op);
|
||||
|
||||
switch (op) {
|
||||
case 7: // B_GET_GEOMETRY
|
||||
{
|
||||
#ifdef HAIKU_HOST_PLATFORM_LINUX
|
||||
{
|
||||
device_geometry *geometry = va_arg(list, device_geometry*);
|
||||
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
|
||||
// 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);
|
||||
|
||||
geometry->head_count = hdGeometry.heads;
|
||||
geometry->cylinder_count = partitionSize / bytesPerCylinder;
|
||||
geometry->sectors_per_track = hdGeometry.sectors;
|
||||
|
||||
// TODO: Get the real values...
|
||||
geometry->bytes_per_sector = 512;
|
||||
geometry->device_type = B_DISK;
|
||||
geometry->removable = false;
|
||||
geometry->read_only = false;
|
||||
geometry->write_once = false;
|
||||
error = FS_OK;
|
||||
} else
|
||||
error = from_platform_error(errno);
|
||||
}
|
||||
#endif // HAIKU_HOST_PLATFORM_LINUX
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 20: // B_FLUSH_DRIVE_CACHE
|
||||
error = FS_OK;
|
||||
break;
|
||||
|
||||
case 10000: // IOCTL_FILE_UNCACHED_IO
|
||||
error = FS_OK;
|
||||
break;
|
||||
}
|
||||
|
||||
va_end(list);
|
||||
|
||||
if (error != FS_OK) {
|
||||
errno = error;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif /* ! __BEOS__ */
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user