From 042eb168965cf38c32b9355c199ebc197672bd2d Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Thu, 1 Mar 2007 04:56:08 +0000 Subject: [PATCH] * 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 --- headers/private/userlandfs/private/Requests.h | 24 ++++++ .../kernel_add_on/KernelRequestHandler.cpp | 26 ++++++ .../kernel_add_on/KernelRequestHandler.h | 4 +- .../userlandfs/kernel_add_on/Volume.cpp | 23 ++++++ .../userlandfs/kernel_add_on/Volume.h | 5 +- .../kernel_add_on/kernel_interface.cpp | 23 ++++-- .../userlandfs/private/Requests.cpp | 4 + .../userlandfs/server/beos_kernel_emu.cpp | 4 +- .../userlandfs/server/kernel_emu.cpp | 32 +++++++- .../kernel/file_systems/userlandfs/userlandfs | 80 +++++++++++++++++++ 10 files changed, 213 insertions(+), 12 deletions(-) create mode 100644 src/add-ons/kernel/file_systems/userlandfs/userlandfs diff --git a/headers/private/userlandfs/private/Requests.h b/headers/private/userlandfs/private/Requests.h index 358a165dc0..316a5f8912 100644 --- a/headers/private/userlandfs/private/Requests.h +++ b/headers/private/userlandfs/private/Requests.h @@ -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; diff --git a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.cpp b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.cpp index 92140327a0..2059c47b88 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.cpp @@ -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) diff --git a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.h b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.h index 3beb6caead..9d32f894ca 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.h +++ b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.h @@ -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); diff --git a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.cpp b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.cpp index 05ead6c77a..5f141683c6 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.cpp @@ -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; } diff --git a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.h b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.h index 5de7dbc886..15ddf6c62c 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.h +++ b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.h @@ -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); diff --git a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/kernel_interface.cpp b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/kernel_interface.cpp index 7f1ca4747f..86dd12bc2d 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/kernel_interface.cpp @@ -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; diff --git a/src/add-ons/kernel/file_systems/userlandfs/private/Requests.cpp b/src/add-ons/kernel/file_systems/userlandfs/private/Requests.cpp index eff963c1e6..1e52bb875b 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/private/Requests.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/private/Requests.cpp @@ -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: diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/beos_kernel_emu.cpp b/src/add-ons/kernel/file_systems/userlandfs/server/beos_kernel_emu.cpp index b3542e3b0c..97a9da7023 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/beos_kernel_emu.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/server/beos_kernel_emu.cpp @@ -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 diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.cpp b/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.cpp index 8e0884fa7a..f4f43d5539 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.cpp @@ -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 diff --git a/src/add-ons/kernel/file_systems/userlandfs/userlandfs b/src/add-ons/kernel/file_systems/userlandfs/userlandfs new file mode 100644 index 0000000000..aef6d9e556 --- /dev/null +++ b/src/add-ons/kernel/file_systems/userlandfs/userlandfs @@ -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 + } +}