* 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:
Ingo Weinhold 2007-03-01 04:56:08 +00:00
parent 32164a180c
commit 042eb16896
10 changed files with 213 additions and 12 deletions

View File

@ -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;

View File

@ -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)

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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:

View File

@ -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

View File

@ -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

View 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
}
}