mirror of
https://review.haiku-os.org/haiku
synced 2025-01-18 04:28:52 +01:00
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:
parent
297aa21e46
commit
7e29de9266
@ -30,6 +30,7 @@ KernelAddon ramfs
|
||||
NodeListener.cpp
|
||||
NodeTable.cpp
|
||||
Query.cpp
|
||||
SpecialNode.cpp
|
||||
SizeIndex.cpp
|
||||
SymLink.cpp
|
||||
Volume.cpp
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
35
src/add-ons/kernel/file_systems/ramfs/SpecialNode.cpp
Normal file
35
src/add-ons/kernel/file_systems/ramfs/SpecialNode.cpp
Normal 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;
|
||||
}
|
22
src/add-ons/kernel/file_systems/ramfs/SpecialNode.h
Normal file
22
src/add-ons/kernel/file_systems/ramfs/SpecialNode.h
Normal 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
|
@ -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 = {
|
||||
|
Loading…
Reference in New Issue
Block a user