Finished node management.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29392 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2009-03-04 00:44:13 +00:00
parent 0234794770
commit c74777f3d3
4 changed files with 146 additions and 27 deletions
@@ -59,16 +59,24 @@ HaikuKernelFileSystem::Init()
// CreateVolume
status_t
HaikuKernelFileSystem::CreateVolume(Volume** volume, dev_t id)
HaikuKernelFileSystem::CreateVolume(Volume** _volume, dev_t id)
{
// check initialization and parameters
if (!fFSModule || !volume)
if (!fFSModule || !_volume)
return B_BAD_VALUE;
// create the volume
*volume = new(std::nothrow) HaikuKernelVolume(this, id, fFSModule);
if (!*volume)
// create and init the volume
HaikuKernelVolume* volume
= new(std::nothrow) HaikuKernelVolume(this, id, fFSModule);
if (!volume)
return B_NO_MEMORY;
status_t error = volume->Init();
if (error != B_OK) {
delete volume;
return error;
}
return B_OK;
}
@@ -18,15 +18,33 @@ using UserlandFSUtil::FSVNodeCapabilities;
struct HaikuKernelNode : fs_vnode {
ino_t id;
HaikuKernelVolume* volume;
bool published;
public:
inline HaikuKernelNode(HaikuKernelVolume* volume,
ino_t vnodeID, void* privateNode,
fs_vnode_ops* ops);
static HaikuKernelNode* GetNode(fs_vnode* node);
HaikuKernelVolume* GetVolume() const { return volume; }
};
HaikuKernelNode::HaikuKernelNode(HaikuKernelVolume* volume, ino_t vnodeID,
void* privateNode, fs_vnode_ops* ops)
:
id(vnodeID),
volume(volume),
published(false)
{
this->private_node = privateNode;
this->ops = ops;
}
/*static*/ inline HaikuKernelNode*
HaikuKernelNode::GetNode(fs_vnode* node)
{
@@ -7,18 +7,29 @@
#include <fcntl.h>
#include <unistd.h>
#include "AutoDeleter.h"
#include "AutoLocker.h"
#include "Debug.h"
#include "HashMap.h"
#include "../kernel_emu.h"
#include "HaikuKernelNode.h"
// NodeMap
class HaikuKernelVolume::NodeMap
: public SynchronizedHashMap<HashKey64<ino_t>, HaikuKernelNode*> {
};
// constructor
HaikuKernelVolume::HaikuKernelVolume(FileSystem* fileSystem, dev_t id,
file_system_module_info* fsModule)
: Volume(fileSystem, id),
fFSModule(fsModule)
:
Volume(fileSystem, id),
fFSModule(fsModule),
fNodes(NULL)
{
fVolume.id = id;
fVolume.partition = -1;
@@ -38,41 +49,98 @@ HaikuKernelVolume::~HaikuKernelVolume()
}
// Init
status_t
HaikuKernelVolume::Init()
{
fNodes = new(std::nothrow) NodeMap;
if (fNodes == NULL)
return B_NO_MEMORY;
return fNodes->InitCheck();
}
// NewVNode
status_t
HaikuKernelVolume::NewVNode(ino_t vnodeID, void* privateNode, fs_vnode_ops* ops,
HaikuKernelNode** node)
HaikuKernelNode** _node)
{
// TODO: Implement!
return B_NOT_SUPPORTED;
AutoLocker<NodeMap> _(fNodes);
// check whether we do already know the node
HaikuKernelNode* node = fNodes->Get(vnodeID);
if (node != NULL)
return B_BAD_VALUE;
// create a new node
node = new(std::nothrow) HaikuKernelNode(this, vnodeID, privateNode, ops);
if (node == NULL)
return B_NO_MEMORY;
// add to map
status_t error = fNodes->Put(vnodeID, node);
if (error != B_OK) {
delete node;
return error;
}
*_node = node;
return B_OK;
}
// PublishVNode
status_t
HaikuKernelVolume::PublishVNode(ino_t vnodeID, void* privateNode,
fs_vnode_ops* ops, int type, uint32 flags, HaikuKernelNode** node)
fs_vnode_ops* ops, int type, uint32 flags, HaikuKernelNode** _node)
{
// TODO: Implement!
return B_NOT_SUPPORTED;
AutoLocker<NodeMap> _(fNodes);
// check whether we do already know the node
HaikuKernelNode* node = fNodes->Get(vnodeID);
if (node != NULL) {
if (node->published)
return B_BAD_VALUE;
} else {
// create a new node
node = new(std::nothrow) HaikuKernelNode(this, vnodeID, privateNode,
ops);
if (node == NULL)
return B_NO_MEMORY;
// add to map
status_t error = fNodes->Put(vnodeID, node);
if (error != B_OK) {
delete node;
return error;
}
}
node->published = true;
*_node = node;
return B_OK;
}
// UndoNewVNode
status_t
void
HaikuKernelVolume::UndoNewVNode(HaikuKernelNode* node)
{
// TODO: Implement!
return B_NOT_SUPPORTED;
fNodes->Remove(node->id);
delete node;
}
// UndoPublishVNode
status_t
void
HaikuKernelVolume::UndoPublishVNode(HaikuKernelNode* node)
{
// TODO: Implement!
return B_NOT_SUPPORTED;
fNodes->Remove(node->id);
delete node;
}
@@ -189,21 +257,37 @@ HaikuKernelVolume::ReadVNode(ino_t vnid, bool reenter, void** _node, int* type,
if (!fVolume.ops->get_vnode)
return B_BAD_VALUE;
// create a new wrapper node
HaikuKernelNode* node = new(std::nothrow) HaikuKernelNode;
// create a new wrapper node and add it to the map
HaikuKernelNode* node = new(std::nothrow) HaikuKernelNode(this, vnid, NULL,
NULL);
if (node == NULL)
return B_NO_MEMORY;
node->volume = this;
ObjectDeleter<HaikuKernelNode> nodeDeleter(node);
AutoLocker<NodeMap> locker(fNodes);
if (fNodes->Get(vnid) != NULL)
return B_BAD_VALUE;
status_t error = fNodes->Put(vnid, node);
if (error != B_OK)
return error;
locker.Unlock();
// get the node
status_t error = fVolume.ops->get_vnode(&fVolume, vnid, node, type, flags,
reenter);
error = fVolume.ops->get_vnode(&fVolume, vnid, node, type, flags, reenter);
if (error != B_OK) {
delete node;
locker.Lock();
fNodes->Remove(vnid);
return error;
}
locker.Lock();
node->published = true;
nodeDeleter.Detach();
*_node = node;
return B_OK;
}
@@ -213,6 +297,8 @@ HaikuKernelVolume::WriteVNode(void* _node, bool reenter)
{
HaikuKernelNode* node = (HaikuKernelNode*)_node;
fNodes->Remove(node->id);
if (!node->ops->put_vnode)
return B_BAD_VALUE;
status_t error = node->ops->put_vnode(&fVolume, node, reenter);
@@ -228,6 +314,8 @@ HaikuKernelVolume::RemoveVNode(void* _node, bool reenter)
{
HaikuKernelNode* node = (HaikuKernelNode*)_node;
fNodes->Remove(node->id);
if (!node->ops->remove_vnode)
return B_BAD_VALUE;
return node->ops->remove_vnode(&fVolume, node, reenter);
@@ -23,13 +23,15 @@ public:
inline fs_volume* GetFSVolume() { return &fVolume; }
status_t Init();
status_t NewVNode(ino_t vnodeID, void* privateNode,
fs_vnode_ops* ops, HaikuKernelNode** node);
status_t PublishVNode(ino_t vnodeID, void* privateNode,
fs_vnode_ops* ops, int type, uint32 flags,
HaikuKernelNode** node);
status_t UndoNewVNode(HaikuKernelNode* node);
status_t UndoPublishVNode(HaikuKernelNode* node);
void UndoNewVNode(HaikuKernelNode* node);
void UndoPublishVNode(HaikuKernelNode* node);
// FS
virtual status_t Mount(const char* device, uint32 flags,
@@ -173,12 +175,15 @@ private:
HaikuKernelVolume* haikuVolume;
};
class NodeMap;
private:
void _InitCapabilities();
private:
file_system_module_info* fFSModule;
FSVolume fVolume;
NodeMap* fNodes;
};