From cbc6d404f9cf85f3b5c63217b514744413564fd4 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Thu, 17 Mar 2005 21:04:25 +0000 Subject: [PATCH] Added missing select()/deselect() Hooks to the file system interface and made sure they are called by the VFS, if existent. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@11884 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/drivers/fs_interface.h | 5 +++ .../file_systems/bfs/kernel_interface.cpp | 2 + src/kernel/core/fs/bootfs.c | 2 + src/kernel/core/fs/devfs.cpp | 40 +++++++++++++++++++ src/kernel/core/fs/pipefs.cpp | 20 ++++++++++ src/kernel/core/fs/rootfs.c | 2 + src/kernel/core/fs/vfs.cpp | 39 +++++++++++++++++- 7 files changed, 108 insertions(+), 2 deletions(-) diff --git a/headers/os/drivers/fs_interface.h b/headers/os/drivers/fs_interface.h index e6309b5241..b94ce09284 100644 --- a/headers/os/drivers/fs_interface.h +++ b/headers/os/drivers/fs_interface.h @@ -17,6 +17,7 @@ struct dirent; struct stat; struct fs_info; +struct select_sync; typedef dev_t mount_id; typedef ino_t vnode_id; @@ -83,6 +84,10 @@ typedef struct file_system_info { /* common operations */ status_t (*ioctl)(fs_volume fs, fs_vnode v, fs_cookie cookie, ulong op, void *buffer, size_t length); status_t (*set_flags)(fs_volume fs, fs_vnode v, fs_cookie cookie, int flags); + status_t (*select)(fs_volume fs, fs_vnode v, fs_cookie cookie, uint8 event, + uint32 ref, selectsync *sync); + status_t (*deselect)(fs_volume fs, fs_vnode v, fs_cookie cookie, + uint8 event, selectsync *sync); status_t (*fsync)(fs_volume fs, fs_vnode v); status_t (*read_link)(fs_volume fs, fs_vnode link, char *buffer, size_t bufferSize); diff --git a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp index 28cc8717a2..47f3dd2b4e 100644 --- a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp @@ -2027,6 +2027,8 @@ static file_system_info sBeFileSystem = { &bfs_ioctl, &bfs_set_flags, + NULL, // &bfs_select + NULL, // &bfs_deselect &bfs_fsync, &bfs_read_link, diff --git a/src/kernel/core/fs/bootfs.c b/src/kernel/core/fs/bootfs.c index e72d2b19a7..a9732b00ae 100755 --- a/src/kernel/core/fs/bootfs.c +++ b/src/kernel/core/fs/bootfs.c @@ -979,6 +979,8 @@ file_system_info gBootFileSystem = { /* common */ &bootfs_ioctl, NULL, // set_flags + NULL, // select + NULL, // deselect &bootfs_fsync, NULL, // read_link diff --git a/src/kernel/core/fs/devfs.cpp b/src/kernel/core/fs/devfs.cpp index 36001730f3..4bb87fda33 100644 --- a/src/kernel/core/fs/devfs.cpp +++ b/src/kernel/core/fs/devfs.cpp @@ -1364,6 +1364,44 @@ devfs_set_flags(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, int flags) } +static status_t +devfs_select(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, uint8 event, + uint32 ref, selectsync *sync) +{ + struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode; + struct devfs_cookie *cookie = (struct devfs_cookie *)_cookie; + + if (!S_ISCHR(vnode->stream.type)) + return B_NOT_ALLOWED; + + // If the device has no select() hook, notify select() now. + if (!vnode->stream.u.dev.info->select) + return notify_select_event((selectsync*)sync, ref, event); + + return vnode->stream.u.dev.info->select(cookie->u.dev.dcookie, event, ref, + (selectsync*)sync); +} + + +static status_t +devfs_deselect(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, uint8 event, + selectsync *sync) +{ + struct devfs_vnode *vnode = (struct devfs_vnode *)_vnode; + struct devfs_cookie *cookie = (struct devfs_cookie *)_cookie; + + if (!S_ISCHR(vnode->stream.type)) + return B_NOT_ALLOWED; + + // If the device has no select() hook, notify select() now. + if (!vnode->stream.u.dev.info->deselect) + return B_OK; + + return vnode->stream.u.dev.info->deselect(cookie->u.dev.dcookie, event, + (selectsync*)sync); +} + + static bool devfs_can_page(fs_volume _fs, fs_vnode _vnode, fs_cookie cookie) { @@ -1545,6 +1583,8 @@ file_system_info gDeviceFileSystem = { /* common */ &devfs_ioctl, &devfs_set_flags, + &devfs_select, + &devfs_deselect, &devfs_fsync, &devfs_read_link, diff --git a/src/kernel/core/fs/pipefs.cpp b/src/kernel/core/fs/pipefs.cpp index d1b2b2267d..9b8405a110 100644 --- a/src/kernel/core/fs/pipefs.cpp +++ b/src/kernel/core/fs/pipefs.cpp @@ -1439,6 +1439,24 @@ pipefs_set_flags(fs_volume _volume, fs_vnode _vnode, fs_cookie _cookie, int flag } +static status_t +pipefs_select(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, uint8 event, + uint32 ref, selectsync *sync) +{ + // ToDo: Implement! + return notify_select_event(sync, ref, event); +} + + +static status_t +pipefs_deselect(fs_volume _fs, fs_vnode _vnode, fs_cookie _cookie, uint8 event, + selectsync *sync) +{ + // ToDo: Implement! + return B_OK; +} + + static bool pipefs_can_page(fs_volume _volume, fs_vnode _v, fs_cookie cookie) { @@ -1587,6 +1605,8 @@ file_system_info gPipeFileSystem = { /* common */ &pipefs_ioctl, &pipefs_set_flags, + &pipefs_select, + &pipefs_deselect, &pipefs_fsync, NULL, // fs_read_link() diff --git a/src/kernel/core/fs/rootfs.c b/src/kernel/core/fs/rootfs.c index 6429718b23..23eecd3603 100755 --- a/src/kernel/core/fs/rootfs.c +++ b/src/kernel/core/fs/rootfs.c @@ -1056,6 +1056,8 @@ file_system_info gRootFileSystem = { /* common */ &rootfs_ioctl, NULL, // fs_set_flags() + NULL, // select + NULL, // deselect &rootfs_fsync, &rootfs_read_link, diff --git a/src/kernel/core/fs/vfs.cpp b/src/kernel/core/fs/vfs.cpp index 0fff20394f..c4c5436d55 100755 --- a/src/kernel/core/fs/vfs.cpp +++ b/src/kernel/core/fs/vfs.cpp @@ -187,6 +187,10 @@ static status_t file_write(struct file_descriptor *, off_t pos, const void *buff static off_t file_seek(struct file_descriptor *, off_t pos, int seek_type); static void file_free_fd(struct file_descriptor *); static status_t file_close(struct file_descriptor *); +static status_t file_select(struct file_descriptor *, uint8 event, uint32 ref, + struct select_sync *sync); +static status_t file_deselect(struct file_descriptor *, uint8 event, + struct select_sync *sync); static status_t dir_read(struct file_descriptor *, struct dirent *buffer, size_t bufferSize, uint32 *_count); static status_t dir_read(struct vnode *vnode, fs_cookie cookie, struct dirent *buffer, size_t bufferSize, uint32 *_count); static status_t dir_rewind(struct file_descriptor *); @@ -230,8 +234,8 @@ static struct fd_ops sFileOps = { file_write, file_seek, common_ioctl, - NULL, // select() - NULL, // deselect() + file_select, + file_deselect, NULL, // read_dir() NULL, // rewind_dir() common_read_stat, @@ -3148,6 +3152,37 @@ file_seek(struct file_descriptor *descriptor, off_t pos, int seekType) } +static status_t +file_select(struct file_descriptor *descriptor, uint8 event, uint32 ref, + struct select_sync *sync) +{ + FUNCTION(("file_select(%p, %u, %lu, %p)\n", descriptor, event, ref, sync)); + + struct vnode *vnode = descriptor->u.vnode; + + // If the FS has no select() hook, notify select() now. + if (FS_CALL(vnode, select) == NULL) + return notify_select_event((selectsync*)sync, ref, event); + + return FS_CALL(vnode, select)(vnode->mount->cookie, vnode->private_node, + descriptor->cookie, event, ref, (selectsync*)sync); +} + + +static status_t +file_deselect(struct file_descriptor *descriptor, uint8 event, + struct select_sync *sync) +{ + struct vnode *vnode = descriptor->u.vnode; + + if (FS_CALL(vnode, deselect) == NULL) + return B_OK; + + return FS_CALL(vnode, deselect)(vnode->mount->cookie, vnode->private_node, + descriptor->cookie, event, (selectsync*)sync); +} + + static status_t dir_create_entry_ref(mount_id mountID, vnode_id parentID, const char *name, int perms, bool kernel) {