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 // CreateVolume
status_t status_t
HaikuKernelFileSystem::CreateVolume(Volume** volume, dev_t id) HaikuKernelFileSystem::CreateVolume(Volume** _volume, dev_t id)
{ {
// check initialization and parameters // check initialization and parameters
if (!fFSModule || !volume) if (!fFSModule || !_volume)
return B_BAD_VALUE; return B_BAD_VALUE;
// create the volume // create and init the volume
*volume = new(std::nothrow) HaikuKernelVolume(this, id, fFSModule); HaikuKernelVolume* volume
if (!*volume) = new(std::nothrow) HaikuKernelVolume(this, id, fFSModule);
if (!volume)
return B_NO_MEMORY; return B_NO_MEMORY;
status_t error = volume->Init();
if (error != B_OK) {
delete volume;
return error;
}
return B_OK; return B_OK;
} }
@@ -18,15 +18,33 @@ using UserlandFSUtil::FSVNodeCapabilities;
struct HaikuKernelNode : fs_vnode { struct HaikuKernelNode : fs_vnode {
ino_t id;
HaikuKernelVolume* volume; HaikuKernelVolume* volume;
bool published;
public: public:
inline HaikuKernelNode(HaikuKernelVolume* volume,
ino_t vnodeID, void* privateNode,
fs_vnode_ops* ops);
static HaikuKernelNode* GetNode(fs_vnode* node); static HaikuKernelNode* GetNode(fs_vnode* node);
HaikuKernelVolume* GetVolume() const { return volume; } 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* /*static*/ inline HaikuKernelNode*
HaikuKernelNode::GetNode(fs_vnode* node) HaikuKernelNode::GetNode(fs_vnode* node)
{ {
@@ -7,18 +7,29 @@
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include "AutoDeleter.h"
#include "AutoLocker.h"
#include "Debug.h" #include "Debug.h"
#include "HashMap.h"
#include "../kernel_emu.h" #include "../kernel_emu.h"
#include "HaikuKernelNode.h" #include "HaikuKernelNode.h"
// NodeMap
class HaikuKernelVolume::NodeMap
: public SynchronizedHashMap<HashKey64<ino_t>, HaikuKernelNode*> {
};
// constructor // constructor
HaikuKernelVolume::HaikuKernelVolume(FileSystem* fileSystem, dev_t id, HaikuKernelVolume::HaikuKernelVolume(FileSystem* fileSystem, dev_t id,
file_system_module_info* fsModule) file_system_module_info* fsModule)
: Volume(fileSystem, id), :
fFSModule(fsModule) Volume(fileSystem, id),
fFSModule(fsModule),
fNodes(NULL)
{ {
fVolume.id = id; fVolume.id = id;
fVolume.partition = -1; 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 // NewVNode
status_t status_t
HaikuKernelVolume::NewVNode(ino_t vnodeID, void* privateNode, fs_vnode_ops* ops, HaikuKernelVolume::NewVNode(ino_t vnodeID, void* privateNode, fs_vnode_ops* ops,
HaikuKernelNode** node) HaikuKernelNode** _node)
{ {
// TODO: Implement! AutoLocker<NodeMap> _(fNodes);
return B_NOT_SUPPORTED;
// 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 // PublishVNode
status_t status_t
HaikuKernelVolume::PublishVNode(ino_t vnodeID, void* privateNode, 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! AutoLocker<NodeMap> _(fNodes);
return B_NOT_SUPPORTED;
// 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 // UndoNewVNode
status_t void
HaikuKernelVolume::UndoNewVNode(HaikuKernelNode* node) HaikuKernelVolume::UndoNewVNode(HaikuKernelNode* node)
{ {
// TODO: Implement! fNodes->Remove(node->id);
return B_NOT_SUPPORTED; delete node;
} }
// UndoPublishVNode // UndoPublishVNode
status_t void
HaikuKernelVolume::UndoPublishVNode(HaikuKernelNode* node) HaikuKernelVolume::UndoPublishVNode(HaikuKernelNode* node)
{ {
// TODO: Implement! fNodes->Remove(node->id);
return B_NOT_SUPPORTED; delete node;
} }
@@ -189,21 +257,37 @@ HaikuKernelVolume::ReadVNode(ino_t vnid, bool reenter, void** _node, int* type,
if (!fVolume.ops->get_vnode) if (!fVolume.ops->get_vnode)
return B_BAD_VALUE; return B_BAD_VALUE;
// create a new wrapper node // create a new wrapper node and add it to the map
HaikuKernelNode* node = new(std::nothrow) HaikuKernelNode; HaikuKernelNode* node = new(std::nothrow) HaikuKernelNode(this, vnid, NULL,
NULL);
if (node == NULL) if (node == NULL)
return B_NO_MEMORY; 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 // get the node
status_t error = fVolume.ops->get_vnode(&fVolume, vnid, node, type, flags, error = fVolume.ops->get_vnode(&fVolume, vnid, node, type, flags, reenter);
reenter);
if (error != B_OK) { if (error != B_OK) {
delete node; locker.Lock();
fNodes->Remove(vnid);
return error; return error;
} }
locker.Lock();
node->published = true;
nodeDeleter.Detach();
*_node = node; *_node = node;
return B_OK; return B_OK;
} }
@@ -213,6 +297,8 @@ HaikuKernelVolume::WriteVNode(void* _node, bool reenter)
{ {
HaikuKernelNode* node = (HaikuKernelNode*)_node; HaikuKernelNode* node = (HaikuKernelNode*)_node;
fNodes->Remove(node->id);
if (!node->ops->put_vnode) if (!node->ops->put_vnode)
return B_BAD_VALUE; return B_BAD_VALUE;
status_t error = node->ops->put_vnode(&fVolume, node, reenter); status_t error = node->ops->put_vnode(&fVolume, node, reenter);
@@ -228,6 +314,8 @@ HaikuKernelVolume::RemoveVNode(void* _node, bool reenter)
{ {
HaikuKernelNode* node = (HaikuKernelNode*)_node; HaikuKernelNode* node = (HaikuKernelNode*)_node;
fNodes->Remove(node->id);
if (!node->ops->remove_vnode) if (!node->ops->remove_vnode)
return B_BAD_VALUE; return B_BAD_VALUE;
return node->ops->remove_vnode(&fVolume, node, reenter); return node->ops->remove_vnode(&fVolume, node, reenter);
@@ -23,13 +23,15 @@ public:
inline fs_volume* GetFSVolume() { return &fVolume; } inline fs_volume* GetFSVolume() { return &fVolume; }
status_t Init();
status_t NewVNode(ino_t vnodeID, void* privateNode, status_t NewVNode(ino_t vnodeID, void* privateNode,
fs_vnode_ops* ops, HaikuKernelNode** node); fs_vnode_ops* ops, HaikuKernelNode** node);
status_t PublishVNode(ino_t vnodeID, void* privateNode, status_t PublishVNode(ino_t vnodeID, void* privateNode,
fs_vnode_ops* ops, int type, uint32 flags, fs_vnode_ops* ops, int type, uint32 flags,
HaikuKernelNode** node); HaikuKernelNode** node);
status_t UndoNewVNode(HaikuKernelNode* node); void UndoNewVNode(HaikuKernelNode* node);
status_t UndoPublishVNode(HaikuKernelNode* node); void UndoPublishVNode(HaikuKernelNode* node);
// FS // FS
virtual status_t Mount(const char* device, uint32 flags, virtual status_t Mount(const char* device, uint32 flags,
@@ -173,12 +175,15 @@ private:
HaikuKernelVolume* haikuVolume; HaikuKernelVolume* haikuVolume;
}; };
class NodeMap;
private: private:
void _InitCapabilities(); void _InitCapabilities();
private: private:
file_system_module_info* fFSModule; file_system_module_info* fFSModule;
FSVolume fVolume; FSVolume fVolume;
NodeMap* fNodes;
}; };