Introduce vnode op supports_operation(), fix devfs_io()

devfs_io() can't fall back to calling vfs_synchronous_io(), if the
device driver doesn't support handling requests asynchronously. The
presence of the io() hook leads the VFS (do_iterative_fd_io()) to
believe that asynchronous handling is supported and set a
finished-callback on the request which calls the io() hook to start the
next chunk. Thus, instead of iterating through the request in a loop
the iteration happens recursively. For sufficiently fragmented requests
the stack may overflow (ticket #9900).

* Introduce a new vnode operation supports_operation(). It can be called
  by the VFS to determine whether a present hook is actually currently
  supported for a given vnode.
* devfs: implement the new hook and remove the fallback handling in
  devfs_io().
* vfs_request_io.cpp: use the new hook to determine whether the io()
  hook is really supported.
This commit is contained in:
Ingo Weinhold
2013-07-27 17:45:59 +02:00
parent b8130cf32d
commit 98a5231fe5
4 changed files with 105 additions and 49 deletions
+35
View File
@@ -92,6 +92,16 @@
*/
/*!
\enum BVnodeOperation
Enumeration type for specifying vnode operations.
*/
/*!
\var BVnodeOperation B_VNODE_OPERATION_IO
Refers to the fs_vnode_ops::io operation.
*/
///// file_system_module_info /////
@@ -1698,6 +1708,31 @@
\brief TODO: Document!
*/
/* TODO: test_lock(), acquire_lock(), release_lock() */
/*!
\fn bool (*fs_vnode_ops::supports_operation)(fs_volume* volume,
fs_vnode* vnode, BVnodeOperation operation)
\brief Returns whether the specified vnode operation is supported for the
specified vnode.
For most vnode operations the FS can simply indicate that it doesn't support
it by setting the respective attribute in the fs_vnode_ops structure to
\c NULL. For certain nodes the support of an operation may change over the
life time of the node. While in most cases the implementation of the
operation can then simply return an error (\c B_NOT_SUPPORTED), for some
operations, however, the VFS has to know beforehand whether to call it at
all or resort to a different handling. It calls this hook only for
operations that aren't set to \c NULL in the fs_vnode_ops structure. If this
hook is not present, the VFS behaves as if it was present always returned
\c true.
\param volume The volume object.
\param vnode The node object.
\param operation The enum value identifying the operation.
\return \c true, if the specified operation is currently supported, \c false
otherwise.
*/
//! @}