* More debug output in the kernel module.
* Made publish_vnode() available in userland. For old style FS add-ons publish_vnode() is used when they request a new_vnode(). The semantics of new_vnode() changed considerably in Haiku, but publish_vnode() seems to do pretty much what the old new_vnode() did. * The UserlandFS hosted RamFS begins to work under Haiku. It runs pretty soon out of memory though (under vmware with 256 MB) and node monitoring is broken ATM. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20264 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
32164a180c
commit
042eb16896
@ -185,6 +185,8 @@ enum {
|
||||
PUT_VNODE_REPLY,
|
||||
NEW_VNODE_REQUEST,
|
||||
NEW_VNODE_REPLY,
|
||||
PUBLISH_VNODE_REQUEST,
|
||||
PUBLISH_VNODE_REPLY,
|
||||
REMOVE_VNODE_REQUEST,
|
||||
REMOVE_VNODE_REPLY,
|
||||
UNREMOVE_VNODE_REQUEST,
|
||||
@ -1425,6 +1427,22 @@ public:
|
||||
NewVNodeReply() : ReplyRequest(NEW_VNODE_REPLY) {}
|
||||
};
|
||||
|
||||
// PublishVNodeRequest
|
||||
class PublishVNodeRequest : public Request {
|
||||
public:
|
||||
PublishVNodeRequest() : Request(PUBLISH_VNODE_REQUEST) {}
|
||||
|
||||
mount_id nsid;
|
||||
vnode_id vnid;
|
||||
fs_vnode node;
|
||||
};
|
||||
|
||||
// PublishVNodeReply
|
||||
class PublishVNodeReply : public ReplyRequest {
|
||||
public:
|
||||
PublishVNodeReply() : ReplyRequest(PUBLISH_VNODE_REPLY) {}
|
||||
};
|
||||
|
||||
// RemoveVNodeRequest
|
||||
class RemoveVNodeRequest : public Request {
|
||||
public:
|
||||
@ -1788,6 +1806,10 @@ do_for_request(Request* request, Task& task)
|
||||
return task((NewVNodeRequest*)request);
|
||||
case NEW_VNODE_REPLY:
|
||||
return task((NewVNodeReply*)request);
|
||||
case PUBLISH_VNODE_REQUEST:
|
||||
return task((PublishVNodeRequest*)request);
|
||||
case PUBLISH_VNODE_REPLY:
|
||||
return task((PublishVNodeReply*)request);
|
||||
case REMOVE_VNODE_REQUEST:
|
||||
return task((RemoveVNodeRequest*)request);
|
||||
case REMOVE_VNODE_REPLY:
|
||||
@ -1979,6 +2001,8 @@ using UserlandFSUtil::PutVNodeRequest;
|
||||
using UserlandFSUtil::PutVNodeReply;
|
||||
using UserlandFSUtil::NewVNodeRequest;
|
||||
using UserlandFSUtil::NewVNodeReply;
|
||||
using UserlandFSUtil::PublishVNodeRequest;
|
||||
using UserlandFSUtil::PublishVNodeReply;
|
||||
using UserlandFSUtil::RemoveVNodeRequest;
|
||||
using UserlandFSUtil::RemoveVNodeReply;
|
||||
using UserlandFSUtil::UnremoveVNodeRequest;
|
||||
|
@ -71,6 +71,8 @@ KernelRequestHandler::HandleRequest(Request* request)
|
||||
return _HandleRequest((PutVNodeRequest*)request);
|
||||
case NEW_VNODE_REQUEST:
|
||||
return _HandleRequest((NewVNodeRequest*)request);
|
||||
case PUBLISH_VNODE_REQUEST:
|
||||
return _HandleRequest((PublishVNodeRequest*)request);
|
||||
case REMOVE_VNODE_REQUEST:
|
||||
return _HandleRequest((RemoveVNodeRequest*)request);
|
||||
case UNREMOVE_VNODE_REQUEST:
|
||||
@ -274,6 +276,30 @@ KernelRequestHandler::_HandleRequest(NewVNodeRequest* request)
|
||||
return fPort->SendRequest(&allocator);
|
||||
}
|
||||
|
||||
// _HandleRequest
|
||||
status_t
|
||||
KernelRequestHandler::_HandleRequest(PublishVNodeRequest* request)
|
||||
{
|
||||
// check and executed the request
|
||||
Volume* volume = NULL;
|
||||
status_t result = _GetVolume(request->nsid, &volume);
|
||||
VolumePutter _(volume);
|
||||
if (result == B_OK)
|
||||
result = volume->PublishVNode(request->vnid, request->node);
|
||||
|
||||
// prepare the reply
|
||||
RequestAllocator allocator(fPort->GetPort());
|
||||
PublishVNodeReply* reply;
|
||||
status_t error = AllocateRequest(allocator, &reply);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
reply->error = result;
|
||||
|
||||
// send the reply
|
||||
return fPort->SendRequest(&allocator);
|
||||
}
|
||||
|
||||
// _HandleRequest
|
||||
status_t
|
||||
KernelRequestHandler::_HandleRequest(RemoveVNodeRequest* request)
|
||||
|
@ -14,6 +14,7 @@ class IsVNodeRemovedRequest;
|
||||
class NewVNodeRequest;
|
||||
class NotifyListenerRequest;
|
||||
class NotifySelectEventRequest;
|
||||
class PublishVNodeRequest;
|
||||
class PutVNodeRequest;
|
||||
class RemoveVNodeRequest;
|
||||
class SendNotificationRequest;
|
||||
@ -26,11 +27,11 @@ using UserlandFSUtil::IsVNodeRemovedRequest;
|
||||
using UserlandFSUtil::NewVNodeRequest;
|
||||
using UserlandFSUtil::NotifyListenerRequest;
|
||||
using UserlandFSUtil::NotifySelectEventRequest;
|
||||
using UserlandFSUtil::PublishVNodeRequest;
|
||||
using UserlandFSUtil::PutVNodeRequest;
|
||||
using UserlandFSUtil::RemoveVNodeRequest;
|
||||
using UserlandFSUtil::SendNotificationRequest;
|
||||
using UserlandFSUtil::UnremoveVNodeRequest;
|
||||
using UserlandFSUtil::GetVNodeRequest;
|
||||
|
||||
class Volume;
|
||||
|
||||
@ -55,6 +56,7 @@ private:
|
||||
status_t _HandleRequest(GetVNodeRequest* request);
|
||||
status_t _HandleRequest(PutVNodeRequest* request);
|
||||
status_t _HandleRequest(NewVNodeRequest* request);
|
||||
status_t _HandleRequest(PublishVNodeRequest* request);
|
||||
status_t _HandleRequest(RemoveVNodeRequest* request);
|
||||
status_t _HandleRequest(UnremoveVNodeRequest* request);
|
||||
status_t _HandleRequest(IsVNodeRemovedRequest* request);
|
||||
|
@ -163,6 +163,29 @@ PRINT(("new_vnode(%ld, %Ld)\n", fID, vnid));
|
||||
if (error != B_OK) {
|
||||
ERROR(("Volume::NewVNode(): Failed to add vnode to mount "
|
||||
"vnode map!\n"));
|
||||
publish_vnode(fID, vnid, node);
|
||||
put_vnode(fID, vnid);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
// TODO: Check what need to do according to the new semantics.
|
||||
// _IncrementVNodeCount(vnid);
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
// PublishVNode
|
||||
status_t
|
||||
Volume::PublishVNode(vnode_id vnid, fs_vnode node)
|
||||
{
|
||||
PRINT(("publish_vnode(%ld, %Ld)\n", fID, vnid));
|
||||
status_t error = publish_vnode(fID, vnid, node);
|
||||
if (error == B_OK) {
|
||||
if (IsMounting()) {
|
||||
error = fMountVNodes->Put(vnid, node);
|
||||
if (error != B_OK) {
|
||||
ERROR(("Volume::PublishVNode(): Failed to add vnode to mount "
|
||||
"vnode map!\n"));
|
||||
put_vnode(fID, vnid);
|
||||
return error;
|
||||
}
|
||||
|
@ -35,9 +35,10 @@ public:
|
||||
bool IsMounting() const;
|
||||
|
||||
// client methods
|
||||
status_t GetVNode(vnode_id vnid, void** node);
|
||||
status_t GetVNode(vnode_id vnid, fs_vnode* node);
|
||||
status_t PutVNode(vnode_id vnid);
|
||||
status_t NewVNode(vnode_id vnid, void* node);
|
||||
status_t NewVNode(vnode_id vnid, fs_vnode node);
|
||||
status_t PublishVNode(vnode_id vnid, fs_vnode node);
|
||||
status_t RemoveVNode(vnode_id vnid);
|
||||
status_t UnremoveVNode(vnode_id vnid);
|
||||
status_t IsVNodeRemoved(vnode_id vnid);
|
||||
|
@ -67,6 +67,9 @@ static status_t
|
||||
userlandfs_mount(mount_id id, const char *device, uint32 flags,
|
||||
const char *args, fs_volume *fsCookie, vnode_id *rootVnodeID)
|
||||
{
|
||||
PRINT(("userlandfs_mount(%ld, %s, 0x%lx, %s, %p, %p)\n", id, device, flags,
|
||||
args, fsCookie, rootVnodeID));
|
||||
|
||||
status_t error = B_OK;
|
||||
|
||||
// get the parameters
|
||||
@ -75,44 +78,50 @@ userlandfs_mount(mount_id id, const char *device, uint32 flags,
|
||||
const char* fsParameters;
|
||||
error = parse_parameters(args, fsName, &fsParameters);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
RETURN_ERROR(error);
|
||||
|
||||
// get the UserlandFS object
|
||||
UserlandFS* userlandFS = UserlandFS::GetUserlandFS();
|
||||
if (!userlandFS)
|
||||
return B_ERROR;
|
||||
RETURN_ERROR(B_ERROR);
|
||||
|
||||
// get the file system
|
||||
FileSystem* fileSystem = NULL;
|
||||
error = userlandFS->RegisterFileSystem(fsName.GetString(), &fileSystem);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
RETURN_ERROR(error);
|
||||
|
||||
// mount the volume
|
||||
Volume* volume = NULL;
|
||||
error = fileSystem->Mount(id, device, flags, fsParameters, &volume);
|
||||
if (error != B_OK) {
|
||||
userlandFS->UnregisterFileSystem(fileSystem);
|
||||
return error;
|
||||
RETURN_ERROR(error);
|
||||
}
|
||||
|
||||
*fsCookie = volume;
|
||||
*rootVnodeID = volume->GetRootID();
|
||||
|
||||
PRINT(("userlandfs_mount() done: %p, %lld\n", *fsCookie, *rootVnodeID));
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
// userlandfs_unmount
|
||||
static status_t
|
||||
userlandfs_unmount(fs_volume ns)
|
||||
userlandfs_unmount(fs_volume fs)
|
||||
{
|
||||
Volume* volume = (Volume*)ns;
|
||||
Volume* volume = (Volume*)fs;
|
||||
PRINT(("userlandfs_unmount(%p)\n", fs));
|
||||
|
||||
FileSystem* fileSystem = volume->GetFileSystem();
|
||||
status_t error = volume->Unmount();
|
||||
// The error code the FS's unmount hook returns is completely irrelevant to
|
||||
// the VFS. It considers the volume unmounted in any case.
|
||||
volume->RemoveReference();
|
||||
UserlandFS::GetUserlandFS()->UnregisterFileSystem(fileSystem);
|
||||
|
||||
PRINT(("userlandfs_unmount() done: %lx\n", error));
|
||||
return error;
|
||||
}
|
||||
|
||||
@ -960,6 +969,7 @@ userlandfs_std_ops(int32 op, ...)
|
||||
case B_MODULE_INIT:
|
||||
{
|
||||
init_debugging();
|
||||
PRINT(("userlandfs_std_ops(): B_MODULE_INIT\n"));
|
||||
|
||||
// make sure there is a UserlandFS we can work with
|
||||
UserlandFS* userlandFS = NULL;
|
||||
@ -973,6 +983,7 @@ userlandfs_std_ops(int32 op, ...)
|
||||
}
|
||||
|
||||
case B_MODULE_UNINIT:
|
||||
PRINT(("userlandfs_std_ops(): B_MODULE_UNINIT\n"));
|
||||
UserlandFS::UninitUserlandFS();
|
||||
exit_debugging();
|
||||
return B_OK;
|
||||
|
@ -645,6 +645,7 @@ UserlandFSUtil::is_kernel_request(uint32 type)
|
||||
case GET_VNODE_REQUEST:
|
||||
case PUT_VNODE_REQUEST:
|
||||
case NEW_VNODE_REQUEST:
|
||||
case PUBLISH_VNODE_REQUEST:
|
||||
case REMOVE_VNODE_REQUEST:
|
||||
case UNREMOVE_VNODE_REQUEST:
|
||||
case IS_VNODE_REMOVED_REQUEST:
|
||||
@ -652,6 +653,7 @@ UserlandFSUtil::is_kernel_request(uint32 type)
|
||||
case GET_VNODE_REPLY:
|
||||
case PUT_VNODE_REPLY:
|
||||
case NEW_VNODE_REPLY:
|
||||
case PUBLISH_VNODE_REPLY:
|
||||
case REMOVE_VNODE_REPLY:
|
||||
case UNREMOVE_VNODE_REPLY:
|
||||
case IS_VNODE_REMOVED_REPLY:
|
||||
@ -843,6 +845,7 @@ UserlandFSUtil::is_userland_request(uint32 type)
|
||||
case GET_VNODE_REQUEST:
|
||||
case PUT_VNODE_REQUEST:
|
||||
case NEW_VNODE_REQUEST:
|
||||
case PUBLISH_VNODE_REQUEST:
|
||||
case REMOVE_VNODE_REQUEST:
|
||||
case UNREMOVE_VNODE_REQUEST:
|
||||
case IS_VNODE_REMOVED_REQUEST:
|
||||
@ -850,6 +853,7 @@ UserlandFSUtil::is_userland_request(uint32 type)
|
||||
case GET_VNODE_REPLY:
|
||||
case PUT_VNODE_REPLY:
|
||||
case NEW_VNODE_REPLY:
|
||||
case PUBLISH_VNODE_REPLY:
|
||||
case REMOVE_VNODE_REPLY:
|
||||
case UNREMOVE_VNODE_REPLY:
|
||||
case IS_VNODE_REMOVED_REPLY:
|
||||
|
@ -83,7 +83,9 @@ put_vnode(nspace_id nsid, vnode_id vnid)
|
||||
int
|
||||
new_vnode(nspace_id nsid, vnode_id vnid, void *data)
|
||||
{
|
||||
return UserlandFS::KernelEmu::new_vnode(nsid, vnid, data);
|
||||
// The semantics of new_vnode() has changed. The new publish_vnode()
|
||||
// should work like the former new_vnode().
|
||||
return UserlandFS::KernelEmu::publish_vnode(nsid, vnid, data);
|
||||
}
|
||||
|
||||
// remove_vnode
|
||||
|
@ -360,8 +360,36 @@ status_t
|
||||
UserlandFS::KernelEmu::publish_vnode(mount_id nsid, vnode_id vnid,
|
||||
fs_vnode data)
|
||||
{
|
||||
// TODO: Implement!
|
||||
return B_BAD_VALUE;
|
||||
// get the request port and the file system
|
||||
RequestPort* port;
|
||||
FileSystem* fileSystem;
|
||||
status_t error = get_port_and_fs(&port, &fileSystem);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
// prepare the request
|
||||
RequestAllocator allocator(port->GetPort());
|
||||
PublishVNodeRequest* request;
|
||||
error = AllocateRequest(allocator, &request);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
request->nsid = nsid;
|
||||
request->vnid = vnid;
|
||||
request->node = data;
|
||||
|
||||
// send the request
|
||||
UserlandRequestHandler handler(fileSystem, PUBLISH_VNODE_REPLY);
|
||||
PublishVNodeReply* reply;
|
||||
error = port->SendRequest(&allocator, &handler, (Request**)&reply);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
RequestReleaser requestReleaser(port, reply);
|
||||
|
||||
// process the reply
|
||||
if (reply->error != B_OK)
|
||||
return reply->error;
|
||||
return error;
|
||||
}
|
||||
|
||||
// remove_vnode
|
||||
|
80
src/add-ons/kernel/file_systems/userlandfs/userlandfs
Normal file
80
src/add-ons/kernel/file_systems/userlandfs/userlandfs
Normal file
@ -0,0 +1,80 @@
|
||||
# userlandfs settings
|
||||
#
|
||||
# Lives in /boot/home/config/settings/kernel/drivers/.
|
||||
|
||||
# OpenBFS
|
||||
file_system obfs {
|
||||
# BFS_IOCTL_VERSION
|
||||
ioctl 14200 {
|
||||
buffer_size 0
|
||||
write_buffer_size 4
|
||||
is_buffer true
|
||||
}
|
||||
|
||||
# BFS_IOCTL_START_CHECKING
|
||||
ioctl 14201 {
|
||||
buffer_size 312
|
||||
write_buffer_size 312
|
||||
is_buffer true
|
||||
}
|
||||
|
||||
# BFS_IOCTL_STOP_CHECKING
|
||||
ioctl 14202 {
|
||||
buffer_size 312
|
||||
write_buffer_size 312
|
||||
is_buffer true
|
||||
}
|
||||
|
||||
# BFS_IOCTL_CHECK_NEXT_NODE
|
||||
ioctl 14203 {
|
||||
buffer_size 312
|
||||
write_buffer_size 312
|
||||
is_buffer true
|
||||
}
|
||||
|
||||
# allocate and zero all free blocks
|
||||
ioctl 56742 {
|
||||
buffer_size 0
|
||||
write_buffer_size 0
|
||||
is_buffer false
|
||||
}
|
||||
|
||||
# dump super block
|
||||
ioctl 56743 {
|
||||
buffer_size 0
|
||||
write_buffer_size 0
|
||||
is_buffer false
|
||||
}
|
||||
|
||||
# dump inode
|
||||
ioctl 56744 {
|
||||
buffer_size 0
|
||||
write_buffer_size 0
|
||||
is_buffer false
|
||||
}
|
||||
|
||||
# dump inode block
|
||||
ioctl 56745 {
|
||||
buffer_size 0
|
||||
write_buffer_size 0
|
||||
is_buffer false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# NetFS
|
||||
file_system netfs {
|
||||
# NET_FS_IOCTL_ADD_SERVER
|
||||
ioctl 11000 {
|
||||
buffer_size 256
|
||||
write_buffer_size 0
|
||||
is_buffer true
|
||||
}
|
||||
|
||||
# NET_FS_IOCTL_REMOVE_SERVER
|
||||
ioctl 11001 {
|
||||
buffer_size 256
|
||||
write_buffer_size 0
|
||||
is_buffer true
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user