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
|
// 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user