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:
Ingo Weinhold
2008-07-28 14:29:49 +00:00
parent 0ff0056d54
commit bb94d91d07
+81 -1
View File
@@ -36,6 +36,7 @@
#include <vm.h>
#include "BaseDevice.h"
#include "io_requests.h"
#include "legacy_drivers.h"
@@ -113,6 +114,11 @@ struct devfs_cookie {
void* device_cookie;
};
struct synchronous_io_cookie {
BaseDevice* device;
void* cookie;
};
// directory iteration states
enum {
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
get_node_for_path(struct devfs *fs, const char *path,
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
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
devfs_read_stat(fs_volume* _volume, fs_vnode* _vnode, struct stat* stat)
{
@@ -1836,7 +1916,7 @@ fs_vnode_ops kVnodeOps = {
&devfs_read_pages,
&devfs_write_pages,
NULL, // io()
&devfs_io,
NULL, // cancel_io()
NULL, // get_file_map