ramfs: Add support for "special" nodes.

Like S_IFIFO. It doesn't support ones with "sub-vnodes", but FIFOs
and UNIX sockets don't seem to use those (does anything, actually?)

Fixes #19261.

Change-Id: I9eeac4efcbe74e9084653c77d883dbb44e6f1d2c
Reviewed-on: https://review.haiku-os.org/c/haiku/+/8830
Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
Augustin Cavalier 2025-01-14 13:39:37 -05:00 committed by waddlesplash
parent 297aa21e46
commit 7e29de9266
6 changed files with 143 additions and 15 deletions

View File

@ -30,6 +30,7 @@ KernelAddon ramfs
NodeListener.cpp
NodeTable.cpp
Query.cpp
SpecialNode.cpp
SizeIndex.cpp
SymLink.cpp
Volume.cpp

View File

@ -15,20 +15,21 @@
Node::Node(Volume *volume, uint8 type)
: fVolume(volume),
fID(fVolume->NextNodeID()),
fRefCount(0),
fMode(0),
fUID(0),
fGID(0),
fATime(0),
fMTime(0),
fCTime(0),
fCrTime(0),
fModified(0),
fIsKnownToVFS(false),
fAttributes(),
fReferrers()
:
fVolume(volume),
fID(fVolume->NextNodeID()),
fRefCount(0),
fMode(0),
fUID(0),
fGID(0),
fATime(0),
fMTime(0),
fCTime(0),
fCrTime(0),
fModified(0),
fIsKnownToVFS(false),
fAttributes(),
fReferrers()
{
// set file type
switch (type) {

View File

@ -22,6 +22,7 @@ enum {
NODE_TYPE_DIRECTORY,
NODE_TYPE_FILE,
NODE_TYPE_SYMLINK,
NODE_TYPE_SPECIAL,
};
// access modes
@ -115,6 +116,8 @@ private:
Volume *fVolume;
ino_t fID;
int32 fRefCount;
protected:
mode_t fMode;
uid_t fUID;
uid_t fGID;

View File

@ -0,0 +1,35 @@
/*
* Copyright 2025, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT license.
*/
#include "SpecialNode.h"
#include "Volume.h"
SpecialNode::SpecialNode(Volume *volume, mode_t mode)
:
Node(volume, NODE_TYPE_SPECIAL)
{
fMode = mode;
}
SpecialNode::~SpecialNode()
{
}
status_t
SpecialNode::SetSize(off_t newSize)
{
return B_UNSUPPORTED;
}
off_t
SpecialNode::GetSize() const
{
return 0;
}

View File

@ -0,0 +1,22 @@
/*
* Copyright 2025, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT license.
*/
#ifndef SPECIAL_NODE_H
#define SPECIAL_NODE_H
#include "Node.h"
class SpecialNode : public Node {
public:
SpecialNode(Volume *volume, mode_t mode);
virtual ~SpecialNode();
virtual status_t SetSize(off_t newSize);
virtual off_t GetSize() const;
};
#endif // SPECIAL_NODE_H

View File

@ -58,6 +58,7 @@
#include "Node.h"
#include "Query.h"
#include "ramfs_ioctl.h"
#include "SpecialNode.h"
#include "SymLink.h"
#include "Volume.h"
@ -876,6 +877,71 @@ ramfs_create(fs_volume* _volume, fs_vnode* _dir, const char *name, int openMode,
}
static status_t
ramfs_create_special_node(fs_volume *_volume, fs_vnode *_dir, const char *name,
fs_vnode *subVnode, mode_t mode, uint32 flags, fs_vnode *_superVnode,
ino_t *vnid)
{
FUNCTION(("name: `%s', mode: %x\n", name, mode));
Volume* volume = (Volume*)_volume->private_volume;
Directory* dir = dynamic_cast<Directory*>((Node*)_dir->private_node);
if (name == NULL || subVnode != NULL)
RETURN_ERROR(B_UNSUPPORTED);
if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
RETURN_ERROR(B_FILE_EXISTS);
VolumeWriteLocker locker(volume);
if (!locker.IsLocked())
RETURN_ERROR(B_ERROR);
NodeMTimeUpdater mTimeUpdater(dir);
status_t error = B_OK;
// directory deleted?
bool removed;
if (get_vnode_removed(volume->FSVolume(), dir->GetID(), &removed)
!= B_OK || removed) {
SET_ERROR(error, B_NOT_ALLOWED);
}
Node *existingNode = NULL;
if (dir->FindNode(name, &existingNode) == B_OK)
RETURN_ERROR(B_FILE_EXISTS);
error = dir->CheckPermissions(ACCESS_W);
if (error != B_OK)
RETURN_ERROR(error);
SpecialNode* node = new(std::nothrow) SpecialNode(volume, mode);
if (node == NULL)
RETURN_ERROR(B_NO_MEMORY);
*vnid = node->GetID();
node->SetUID(geteuid());
node->SetGID(getegid());
Entry* entry;
error = node->InitCheck();
if (error == B_OK) {
// add node to directory
error = dir->CreateEntry(node, name, &entry);
}
if (error != B_OK) {
delete node;
RETURN_ERROR(error);
}
NodeMTimeUpdater mTimeUpdater2(node);
// notify listeners
notify_entry_created(volume->GetID(), dir->GetID(), name, *vnid);
return B_OK;
}
static status_t
ramfs_open(fs_volume* _volume, fs_vnode* _node, int openMode, void** _cookie)
{
@ -2248,7 +2314,7 @@ fs_vnode_ops gRamFSVnodeOps = {
&ramfs_remove_attr,
/* special nodes */
NULL // create_special_node
&ramfs_create_special_node,
};
static file_system_module_info sRamFSModuleInfo = {