Finished node management.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29392 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user