* FileSystem does now have a list of all volumes. This allows to get a volume
by ID. * Added a three parameters version of UserlandFS::KernelEmu::publish_vnode(), which is used by the BeOS new_vnode() emulation. It calls the new Volume::GetVNodeType() to get the type of the node. Theoretically BeOS FS interface style add-ons should work again, but ATM we crash the kernel when trying to mount. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29367 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -2,13 +2,60 @@
|
|||||||
|
|
||||||
#include "FileSystem.h"
|
#include "FileSystem.h"
|
||||||
|
|
||||||
|
#include "AutoLocker.h"
|
||||||
|
#include "Volume.h"
|
||||||
|
|
||||||
|
|
||||||
|
FileSystem* FileSystem::sInstance = NULL;
|
||||||
|
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
FileSystem::FileSystem()
|
FileSystem::FileSystem()
|
||||||
{
|
{
|
||||||
|
sInstance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// destructor
|
// destructor
|
||||||
FileSystem::~FileSystem()
|
FileSystem::~FileSystem()
|
||||||
{
|
{
|
||||||
|
sInstance = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ FileSystem*
|
||||||
|
FileSystem::GetInstance()
|
||||||
|
{
|
||||||
|
return sInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
FileSystem::RegisterVolume(Volume* volume)
|
||||||
|
{
|
||||||
|
AutoLocker<Locker> _(fLock);
|
||||||
|
fVolumes.Add(volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
FileSystem::UnregisterVolume(Volume* volume)
|
||||||
|
{
|
||||||
|
AutoLocker<Locker> _(fLock);
|
||||||
|
fVolumes.Remove(volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Volume*
|
||||||
|
FileSystem::VolumeWithID(dev_t id)
|
||||||
|
{
|
||||||
|
AutoLocker<Locker> _(fLock);
|
||||||
|
|
||||||
|
VolumeList::Iterator it = fVolumes.GetIterator();
|
||||||
|
while (Volume* volume = it.Next()) {
|
||||||
|
if (volume->GetID() == id)
|
||||||
|
return volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,7 +7,11 @@
|
|||||||
#include <image.h>
|
#include <image.h>
|
||||||
#include <OS.h>
|
#include <OS.h>
|
||||||
|
|
||||||
|
#include <kernel/util/DoublyLinkedList.h>
|
||||||
|
|
||||||
#include "FSCapabilities.h"
|
#include "FSCapabilities.h"
|
||||||
|
#include "Locker.h"
|
||||||
|
|
||||||
|
|
||||||
namespace UserlandFS {
|
namespace UserlandFS {
|
||||||
|
|
||||||
@@ -18,9 +22,15 @@ public:
|
|||||||
FileSystem();
|
FileSystem();
|
||||||
virtual ~FileSystem();
|
virtual ~FileSystem();
|
||||||
|
|
||||||
|
static FileSystem* GetInstance();
|
||||||
|
|
||||||
virtual status_t CreateVolume(Volume** volume, dev_t id) = 0;
|
virtual status_t CreateVolume(Volume** volume, dev_t id) = 0;
|
||||||
virtual status_t DeleteVolume(Volume* volume) = 0;
|
virtual status_t DeleteVolume(Volume* volume) = 0;
|
||||||
|
|
||||||
|
void RegisterVolume(Volume* volume);
|
||||||
|
void UnregisterVolume(Volume* volume);
|
||||||
|
Volume* VolumeWithID(dev_t id);
|
||||||
|
|
||||||
void GetCapabilities(
|
void GetCapabilities(
|
||||||
FSCapabilities& capabilities) const
|
FSCapabilities& capabilities) const
|
||||||
{ capabilities = fCapabilities; }
|
{ capabilities = fCapabilities; }
|
||||||
@@ -28,8 +38,15 @@ public:
|
|||||||
{ return fClientFSType; }
|
{ return fClientFSType; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
typedef DoublyLinkedList<Volume> VolumeList;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Locker fLock;
|
||||||
|
VolumeList fVolumes;
|
||||||
FSCapabilities fCapabilities;
|
FSCapabilities fCapabilities;
|
||||||
client_fs_type fClientFSType;
|
client_fs_type fClientFSType;
|
||||||
|
|
||||||
|
static FileSystem* sInstance;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace UserlandFS
|
} // namespace UserlandFS
|
||||||
|
|||||||
@@ -6,18 +6,22 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include "FileSystem.h"
|
||||||
#include "kernel_emu.h"
|
#include "kernel_emu.h"
|
||||||
|
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
Volume::Volume(FileSystem* fileSystem, dev_t id)
|
Volume::Volume(FileSystem* fileSystem, dev_t id)
|
||||||
: fFileSystem(fileSystem),
|
: fFileSystem(fileSystem),
|
||||||
fID(id)
|
fID(id)
|
||||||
{
|
{
|
||||||
|
fFileSystem->RegisterVolume(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// destructor
|
// destructor
|
||||||
Volume::~Volume()
|
Volume::~Volume()
|
||||||
{
|
{
|
||||||
|
fFileSystem->UnregisterVolume(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetFileSystem
|
// GetFileSystem
|
||||||
@@ -85,6 +89,15 @@ Volume::Lookup(void* dir, const char* entryName, ino_t* vnid)
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// GetVNodeType
|
||||||
|
status_t
|
||||||
|
Volume::GetVNodeType(void* node, int* type)
|
||||||
|
{
|
||||||
|
return B_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// GetVNodeName
|
// GetVNodeName
|
||||||
status_t
|
status_t
|
||||||
Volume::GetVNodeName(void* node, char* buffer, size_t bufferSize)
|
Volume::GetVNodeName(void* node, char* buffer, size_t bufferSize)
|
||||||
|
|||||||
@@ -6,15 +6,18 @@
|
|||||||
#include <fs_interface.h>
|
#include <fs_interface.h>
|
||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
#include <kernel/util/DoublyLinkedList.h>
|
||||||
|
|
||||||
#include "FSCapabilities.h"
|
#include "FSCapabilities.h"
|
||||||
|
|
||||||
|
|
||||||
namespace UserlandFS {
|
namespace UserlandFS {
|
||||||
|
|
||||||
class FileSystem;
|
class FileSystem;
|
||||||
|
|
||||||
using UserlandFSUtil::FSVolumeCapabilities;
|
using UserlandFSUtil::FSVolumeCapabilities;
|
||||||
|
|
||||||
class Volume {
|
class Volume : public DoublyLinkedListLinkImpl<Volume> {
|
||||||
public:
|
public:
|
||||||
Volume(FileSystem* fileSystem, dev_t id);
|
Volume(FileSystem* fileSystem, dev_t id);
|
||||||
virtual ~Volume();
|
virtual ~Volume();
|
||||||
@@ -38,6 +41,10 @@ public:
|
|||||||
// vnodes
|
// vnodes
|
||||||
virtual status_t Lookup(void* dir, const char* entryName,
|
virtual status_t Lookup(void* dir, const char* entryName,
|
||||||
ino_t* vnid);
|
ino_t* vnid);
|
||||||
|
virtual status_t GetVNodeType(void* node, int* type);
|
||||||
|
// Only needs to be implemented when
|
||||||
|
// the three parameters publish_vnode() is
|
||||||
|
// used.
|
||||||
virtual status_t GetVNodeName(void* node, char* buffer,
|
virtual status_t GetVNodeName(void* node, char* buffer,
|
||||||
size_t bufferSize);
|
size_t bufferSize);
|
||||||
virtual status_t ReadVNode(ino_t vnid, bool reenter,
|
virtual status_t ReadVNode(ino_t vnid, bool reenter,
|
||||||
|
|||||||
@@ -43,9 +43,11 @@ public:
|
|||||||
// constructor
|
// constructor
|
||||||
BeOSKernelVolume::BeOSKernelVolume(FileSystem* fileSystem, dev_t id,
|
BeOSKernelVolume::BeOSKernelVolume(FileSystem* fileSystem, dev_t id,
|
||||||
beos_vnode_ops* fsOps)
|
beos_vnode_ops* fsOps)
|
||||||
: Volume(fileSystem, id),
|
:
|
||||||
|
Volume(fileSystem, id),
|
||||||
fFSOps(fsOps),
|
fFSOps(fsOps),
|
||||||
fVolumeCookie(NULL)
|
fVolumeCookie(NULL),
|
||||||
|
fMounted(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,8 +68,13 @@ BeOSKernelVolume::Mount(const char* device, uint32 flags,
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
size_t len = (parameters ? strlen(parameters) : 0);
|
size_t len = (parameters ? strlen(parameters) : 0);
|
||||||
return fFSOps->mount(GetID(), device, flags, (void*)parameters, len,
|
status_t error = fFSOps->mount(GetID(), device, flags, (void*)parameters,
|
||||||
&fVolumeCookie, rootID);
|
len, &fVolumeCookie, rootID);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
fMounted = true;
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unmount
|
// Unmount
|
||||||
@@ -123,6 +130,35 @@ BeOSKernelVolume::Lookup(void* dir, const char* entryName, ino_t* vnid)
|
|||||||
return fFSOps->walk(fVolumeCookie, dir, entryName, NULL, vnid);
|
return fFSOps->walk(fVolumeCookie, dir, entryName, NULL, vnid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// GetVNodeType
|
||||||
|
status_t
|
||||||
|
BeOSKernelVolume::GetVNodeType(void* node, int* type)
|
||||||
|
{
|
||||||
|
if (fMounted) {
|
||||||
|
// The volume is mounted. We can stat() the node to get its type.
|
||||||
|
struct stat st;
|
||||||
|
status_t error = ReadStat(node, &st);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
*type = st.st_mode & S_IFMT;
|
||||||
|
} else {
|
||||||
|
// Not mounted yet. That particularly means we don't have a volume
|
||||||
|
// cookie yet and cannot use calls into the FS to get the node type.
|
||||||
|
// Just assume the node is a directory. That definitely is the case for
|
||||||
|
// the root node and shouldn't do harm for the index directory or
|
||||||
|
// indices, which could get published while mounting as well.
|
||||||
|
*type = S_IFDIR;
|
||||||
|
// TODO: Store the concerned nodes and check their type as soon as
|
||||||
|
// possible (at the end of Mount()). The incorrect ones could be
|
||||||
|
// corrected in the kernel: remove_vnode(), x*put_vnode() (catching
|
||||||
|
// the "remove_vnode()" callback), publish_vnode(),
|
||||||
|
// (x-1)*get_vnode().
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ReadVNode
|
// ReadVNode
|
||||||
status_t
|
status_t
|
||||||
BeOSKernelVolume::ReadVNode(ino_t vnid, bool reenter, void** node, int* type,
|
BeOSKernelVolume::ReadVNode(ino_t vnid, bool reenter, void** node, int* type,
|
||||||
|
|||||||
@@ -27,6 +27,10 @@ public:
|
|||||||
// vnodes
|
// vnodes
|
||||||
virtual status_t Lookup(void* dir, const char* entryName,
|
virtual status_t Lookup(void* dir, const char* entryName,
|
||||||
ino_t* vnid);
|
ino_t* vnid);
|
||||||
|
virtual status_t GetVNodeType(void* node, int* type);
|
||||||
|
// Only needs to be implemented when
|
||||||
|
// the three parameters publish_vnode() is
|
||||||
|
// used.
|
||||||
virtual status_t ReadVNode(ino_t vnid, bool reenter,
|
virtual status_t ReadVNode(ino_t vnid, bool reenter,
|
||||||
void** node, int* type, uint32* flags);
|
void** node, int* type, uint32* flags);
|
||||||
virtual status_t WriteVNode(void* node, bool reenter);
|
virtual status_t WriteVNode(void* node, bool reenter);
|
||||||
@@ -153,6 +157,7 @@ private:
|
|||||||
private:
|
private:
|
||||||
beos_vnode_ops* fFSOps;
|
beos_vnode_ops* fFSOps;
|
||||||
void* fVolumeCookie;
|
void* fVolumeCookie;
|
||||||
|
bool fMounted;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace UserlandFS
|
} // namespace UserlandFS
|
||||||
|
|||||||
@@ -147,9 +147,7 @@ new_vnode(nspace_id nsid, ino_t vnid, void *data)
|
|||||||
{
|
{
|
||||||
// The semantics of new_vnode() has changed. The new publish_vnode()
|
// The semantics of new_vnode() has changed. The new publish_vnode()
|
||||||
// should work like the former new_vnode().
|
// should work like the former new_vnode().
|
||||||
// TODO: Implement correctly! Get the type!
|
return UserlandFS::KernelEmu::publish_vnode(nsid, vnid, data);
|
||||||
// return UserlandFS::KernelEmu::publish_vnode(nsid, vnid, data);
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove_vnode
|
// remove_vnode
|
||||||
|
|||||||
@@ -6,11 +6,13 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "FileSystem.h"
|
||||||
#include "RequestPort.h"
|
#include "RequestPort.h"
|
||||||
#include "Requests.h"
|
#include "Requests.h"
|
||||||
#include "RequestThread.h"
|
#include "RequestThread.h"
|
||||||
#include "UserlandFSServer.h"
|
#include "UserlandFSServer.h"
|
||||||
#include "UserlandRequestHandler.h"
|
#include "UserlandRequestHandler.h"
|
||||||
|
#include "Volume.h"
|
||||||
|
|
||||||
|
|
||||||
// Taken from the Haiku Storage Kit (storage_support.cpp)
|
// Taken from the Haiku Storage Kit (storage_support.cpp)
|
||||||
@@ -407,6 +409,28 @@ UserlandFS::KernelEmu::publish_vnode(dev_t nsid, ino_t vnid, void* data,
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// publish_vnode
|
||||||
|
status_t
|
||||||
|
UserlandFS::KernelEmu::publish_vnode(dev_t nsid, ino_t vnid, void* data)
|
||||||
|
{
|
||||||
|
// get the volume
|
||||||
|
Volume* volume = FileSystem::GetInstance()->VolumeWithID(nsid);
|
||||||
|
if (volume == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
// stat() the node to get its type
|
||||||
|
// TODO: This must not be called while mounting!
|
||||||
|
int type;
|
||||||
|
status_t error = volume->GetVNodeType(data, &type);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
// publish the node
|
||||||
|
return UserlandFS::KernelEmu::publish_vnode(nsid, vnid, data, type, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// remove_vnode
|
// remove_vnode
|
||||||
status_t
|
status_t
|
||||||
UserlandFS::KernelEmu::remove_vnode(dev_t nsid, ino_t vnid)
|
UserlandFS::KernelEmu::remove_vnode(dev_t nsid, ino_t vnid)
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ status_t acquire_vnode(dev_t nsid, ino_t vnodeID);
|
|||||||
status_t new_vnode(dev_t nsid, ino_t vnid, void* data);
|
status_t new_vnode(dev_t nsid, ino_t vnid, void* data);
|
||||||
status_t publish_vnode(dev_t nsid, ino_t vnid, void* data, int type,
|
status_t publish_vnode(dev_t nsid, ino_t vnid, void* data, int type,
|
||||||
uint32 flags);
|
uint32 flags);
|
||||||
|
status_t publish_vnode(dev_t nsid, ino_t vnid, void* data);
|
||||||
status_t remove_vnode(dev_t nsid, ino_t vnid);
|
status_t remove_vnode(dev_t nsid, ino_t vnid);
|
||||||
status_t unremove_vnode(dev_t nsid, ino_t vnid);
|
status_t unremove_vnode(dev_t nsid, ino_t vnid);
|
||||||
status_t get_vnode_removed(dev_t nsid, ino_t vnid, bool* removed);
|
status_t get_vnode_removed(dev_t nsid, ino_t vnid, bool* removed);
|
||||||
|
|||||||
Reference in New Issue
Block a user