Implemented the devfs io() hook.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26660 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -36,6 +36,7 @@
|
|||||||
#include <vm.h>
|
#include <vm.h>
|
||||||
|
|
||||||
#include "BaseDevice.h"
|
#include "BaseDevice.h"
|
||||||
|
#include "io_requests.h"
|
||||||
#include "legacy_drivers.h"
|
#include "legacy_drivers.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -113,6 +114,11 @@ struct devfs_cookie {
|
|||||||
void* device_cookie;
|
void* device_cookie;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct synchronous_io_cookie {
|
||||||
|
BaseDevice* device;
|
||||||
|
void* cookie;
|
||||||
|
};
|
||||||
|
|
||||||
// directory iteration states
|
// directory iteration states
|
||||||
enum {
|
enum {
|
||||||
ITERATION_STATE_DOT = 0,
|
ITERATION_STATE_DOT = 0,
|
||||||
@@ -443,6 +449,18 @@ translate_partition_access(devfs_partition* partition, off_t& offset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
translate_partition_access(devfs_partition* partition, io_request* request)
|
||||||
|
{
|
||||||
|
off_t offset = request->Offset();
|
||||||
|
|
||||||
|
ASSERT(offset >= 0);
|
||||||
|
ASSERT(offset + request->Length() <= partition->info.size);
|
||||||
|
|
||||||
|
request->SetOffset(offset + partition->info.offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
get_node_for_path(struct devfs *fs, const char *path,
|
get_node_for_path(struct devfs *fs, const char *path,
|
||||||
struct devfs_vnode **_node)
|
struct devfs_vnode **_node)
|
||||||
@@ -737,6 +755,30 @@ get_device_name(struct devfs_vnode* vnode, char* buffer, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
device_read(void* _cookie, off_t offset, void* buffer, size_t length)
|
||||||
|
{
|
||||||
|
synchronous_io_cookie* cookie = (synchronous_io_cookie*)_cookie;
|
||||||
|
|
||||||
|
size_t transferred = length;
|
||||||
|
status_t error = cookie->device->Read(cookie->cookie, offset, buffer,
|
||||||
|
&transferred);
|
||||||
|
return error == B_OK && transferred != length ? B_FILE_ERROR : error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
device_write(void* _cookie, off_t offset, void* buffer, size_t length)
|
||||||
|
{
|
||||||
|
synchronous_io_cookie* cookie = (synchronous_io_cookie*)_cookie;
|
||||||
|
|
||||||
|
size_t transferred = length;
|
||||||
|
status_t error = cookie->device->Write(cookie->cookie, offset, buffer,
|
||||||
|
&transferred);
|
||||||
|
return error == B_OK && transferred != length ? B_FILE_ERROR : error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
dump_node(int argc, char **argv)
|
dump_node(int argc, char **argv)
|
||||||
{
|
{
|
||||||
@@ -1707,6 +1749,44 @@ devfs_write_pages(fs_volume* _volume, fs_vnode* _vnode, void* _cookie,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
devfs_io(fs_volume *volume, fs_vnode *_vnode, void *_cookie,
|
||||||
|
io_request *request)
|
||||||
|
{
|
||||||
|
devfs_vnode* vnode = (devfs_vnode*)_vnode->private_node;
|
||||||
|
devfs_cookie* cookie = (devfs_cookie*)_cookie;
|
||||||
|
|
||||||
|
bool isWrite = request->IsWrite();
|
||||||
|
|
||||||
|
if (!S_ISCHR(vnode->stream.type)
|
||||||
|
|| ((isWrite && !vnode->stream.u.dev.device->HasWrite()
|
||||||
|
|| !isWrite && !vnode->stream.u.dev.device->HasRead())
|
||||||
|
&& !vnode->stream.u.dev.device->HasIO())
|
||||||
|
|| cookie == NULL) {
|
||||||
|
return B_NOT_ALLOWED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vnode->stream.u.dev.partition) {
|
||||||
|
if (request->Offset() + request->Length()
|
||||||
|
>= vnode->stream.u.dev.partition->info.size) {
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
}
|
||||||
|
translate_partition_access(vnode->stream.u.dev.partition, request);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vnode->stream.u.dev.device->HasIO())
|
||||||
|
return vnode->stream.u.dev.device->IO(cookie->device_cookie, request);
|
||||||
|
|
||||||
|
synchronous_io_cookie synchronousCookie = {
|
||||||
|
vnode->stream.u.dev.device,
|
||||||
|
cookie->device_cookie
|
||||||
|
};
|
||||||
|
|
||||||
|
return vfs_synchronous_io(request,
|
||||||
|
request->IsWrite() ? &device_write : &device_read, &synchronousCookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
devfs_read_stat(fs_volume* _volume, fs_vnode* _vnode, struct stat* stat)
|
devfs_read_stat(fs_volume* _volume, fs_vnode* _vnode, struct stat* stat)
|
||||||
{
|
{
|
||||||
@@ -1836,7 +1916,7 @@ fs_vnode_ops kVnodeOps = {
|
|||||||
&devfs_read_pages,
|
&devfs_read_pages,
|
||||||
&devfs_write_pages,
|
&devfs_write_pages,
|
||||||
|
|
||||||
NULL, // io()
|
&devfs_io,
|
||||||
NULL, // cancel_io()
|
NULL, // cancel_io()
|
||||||
|
|
||||||
NULL, // get_file_map
|
NULL, // get_file_map
|
||||||
|
|||||||
Reference in New Issue
Block a user