diff --git a/headers/private/kernel/vfs.h b/headers/private/kernel/vfs.h index 621b8e4afb..fe0968cd96 100755 --- a/headers/private/kernel/vfs.h +++ b/headers/private/kernel/vfs.h @@ -87,6 +87,10 @@ status_t vfs_get_module_path(const char *basePath, const char *moduleName, char status_t vfs_normalize_path(const char *path, char *buffer, size_t bufferSize, bool kernel); +/* service call for the node monitor */ +status_t resolve_mount_point_to_volume_root(mount_id mountID, vnode_id nodeID, + mount_id *resolvedMountID, vnode_id *resolvedNodeID); + /* calls the syscall dispatcher should use for user file I/O */ status_t _user_mount(const char *path, const char *device, const char *fs_name, uint32 flags, const char *args); diff --git a/src/kernel/core/fs/vfs.cpp b/src/kernel/core/fs/vfs.cpp index f917301da9..8f629eeaa3 100755 --- a/src/kernel/core/fs/vfs.cpp +++ b/src/kernel/core/fs/vfs.cpp @@ -110,24 +110,6 @@ struct fs_mount { bool owns_file_device; }; -// RecursiveLockLocking -class RecursiveLockLocking { -public: - inline bool Lock(recursive_lock *lockable) - { - recursive_lock_lock(lockable); - return true; - } - - inline void Unlock(recursive_lock *lockable) - { - recursive_lock_unlock(lockable); - } -}; - -// RecursiveLocker -typedef AutoLocker RecursiveLocker; - static mutex sFileSystemsMutex; @@ -837,7 +819,6 @@ put_vnode(struct vnode *vnode) * \return The volume root vnode the vnode cover is covered by, if it is * indeed a mount point, or \c NULL otherwise. */ - static struct vnode * resolve_mount_point_to_volume_root(struct vnode *vnode) { @@ -857,6 +838,54 @@ resolve_mount_point_to_volume_root(struct vnode *vnode) } +/** \brief Resolves a mount point vnode to the volume root vnode it is covered + * by. + * + * Given an arbitrary vnode (identified by mount and node ID), the function + * checks, whether the node is covered by the root of a volume. If it is the + * function returns the mount and node ID of the volume root node. Otherwise + * it simply returns the supplied mount and node ID. + * + * In case of error (e.g. the supplied node could not be found) the variables + * for storing the resolved mount and node ID remain untouched and an error + * code is returned. + * + * \param mountID The mount ID of the vnode in question. + * \param nodeID The node ID of the vnode in question. + * \param resolvedMountID Pointer to storage for the resolved mount ID. + * \param resolvedNodeID Pointer to storage for the resolved node ID. + * \return + * - \c B_OK, if everything went fine, + * - another error code, if something went wrong. + */ +status_t +resolve_mount_point_to_volume_root(mount_id mountID, vnode_id nodeID, + mount_id *resolvedMountID, vnode_id *resolvedNodeID) +{ + // get the node + struct vnode *node; + status_t error = get_vnode(mountID, nodeID, &node, false); + if (error != B_OK) + return error; + + + // resolve the node + struct vnode *resolvedNode = resolve_mount_point_to_volume_root(node); + if (resolvedNode) { + put_vnode(node); + node = resolvedNode; + } + + // set the return values + *resolvedMountID = node->device; + *resolvedNodeID = node->id; + + put_vnode(node); + + return B_OK; +} + + /** \brief Resolves a volume root vnode to the underlying mount point vnode. * * Given an arbitrary vnode, the function checks, whether the node is the