New service function vfs_create_special_node() to create special nodes.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24883 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2008-04-10 03:07:07 +00:00
parent ef7cb2253b
commit f8b4d83f2f
2 changed files with 86 additions and 0 deletions

View File

@ -128,6 +128,11 @@ status_t vfs_get_module_path(const char *basePath, const char *moduleName,
status_t vfs_normalize_path(const char *path, char *buffer, size_t bufferSize,
bool kernel);
/* service call for whoever wants to create a special node */
status_t vfs_create_special_node(const char *path, fs_vnode *subVnode,
mode_t mode, uint32 flags, bool kernel, fs_vnode *_superVnode,
struct vnode **_createdVnode);
/* service call for the node monitor */
status_t resolve_mount_point_to_volume_root(dev_t mountID, ino_t nodeID,
dev_t *resolvedMountID, ino_t *resolvedNodeID);

View File

@ -3737,6 +3737,87 @@ vfs_normalize_path(const char *path, char *buffer, size_t bufferSize,
}
/*! \brief Creates a special node in the file system.
The caller gets a reference to the newly created node (which is passed
back through \a _createdVnode) and is responsible for releasing it.
\param path The path where to create the entry for the node. Can be \c NULL,
in which case the node is created without an entry in the root FS -- it
will automatically be deleted when the last reference has been released.
\param subVnode The definition of the subnode. Can be \c NULL, in which case
the target file system will just create the node with its standard
operations. Depending on the type of the node a subnode might be created
automatically, though.
\param mode The type and permissions for the node to be created.
\param flags Flags to be passed to the creating FS.
\param kernel \c true, if called in the kernel context (relevant only if
\a path is not \c NULL and not absolute).
\param _superVnode Pointer to a pre-allocated structure to be filled by the
file system creating the node, with the private data pointer and
operations for the super node. Can be \c NULL.
\param _createVnode Pointer to pre-allocated storage where to store the
pointer to the newly created node.
\return \c B_OK, if everything went fine, another error code otherwise.
*/
status_t
vfs_create_special_node(const char *path, fs_vnode *subVnode, mode_t mode,
uint32 flags, bool kernel, fs_vnode *_superVnode,
struct vnode **_createdVnode)
{
struct vnode* dirNode;
char _leaf[B_FILE_NAME_LENGTH];
char* leaf = NULL;
if (path) {
// We've got a path. Get the dir vnode and the leaf name.
KPath tmpPathBuffer(B_PATH_NAME_LENGTH + 1);
if (tmpPathBuffer.InitCheck() != B_OK)
return B_NO_MEMORY;
char* tmpPath = tmpPathBuffer.LockBuffer();
if (strlcpy(tmpPath, path, B_PATH_NAME_LENGTH) >= B_PATH_NAME_LENGTH)
return B_NAME_TOO_LONG;
// get the dir vnode and the leaf name
leaf = _leaf;
status_t error = path_to_dir_vnode(tmpPath, &dirNode, leaf, kernel);
if (error != B_OK)
return error;
} else {
// No path. Create the node in the root FS.
dirNode = sRoot;
inc_vnode_ref_count(dirNode);
}
VNodePutter _(dirNode);
// check support for creating special nodes
if (!HAS_FS_CALL(dirNode, create_special_node))
return B_UNSUPPORTED;
// create the node
fs_vnode superVnode;
ino_t nodeID;
status_t status = FS_CALL(sRoot, create_special_node, leaf, subVnode,
mode, flags, _superVnode != NULL ? _superVnode : &superVnode, &nodeID);
if (status != B_OK)
return status;
// lookup the node
mutex_lock(&sVnodeMutex);
*_createdVnode = lookup_vnode(dirNode->mount->id, nodeID);
mutex_unlock(&sVnodeMutex);
if (*_createdVnode == NULL) {
panic("vfs_create_special_node(): lookup of node failed");
return B_ERROR;
}
return B_OK;
}
extern "C" void
vfs_put_vnode(struct vnode *vnode)
{