diff --git a/headers/private/userlandfs/private/Requests.h b/headers/private/userlandfs/private/Requests.h index 9fede232b6..ebb78966db 100644 --- a/headers/private/userlandfs/private/Requests.h +++ b/headers/private/userlandfs/private/Requests.h @@ -192,6 +192,8 @@ enum { GET_VNODE_REPLY, PUT_VNODE_REQUEST, PUT_VNODE_REPLY, + ACQUIRE_VNODE_REQUEST, + ACQUIRE_VNODE_REPLY, NEW_VNODE_REQUEST, NEW_VNODE_REPLY, PUBLISH_VNODE_REQUEST, @@ -1465,6 +1467,21 @@ public: PutVNodeReply() : ReplyRequest(PUT_VNODE_REPLY) {} }; +// AcquireVNodeRequest +class AcquireVNodeRequest : public Request { +public: + AcquireVNodeRequest() : Request(ACQUIRE_VNODE_REQUEST) {} + + dev_t nsid; + ino_t vnid; +}; + +// AcquireVNodeReply +class AcquireVNodeReply : public ReplyRequest { +public: + AcquireVNodeReply() : ReplyRequest(ACQUIRE_VNODE_REPLY) {} +}; + // NewVNodeRequest class NewVNodeRequest : public Request { public: @@ -2073,6 +2090,8 @@ using UserlandFSUtil::GetVNodeRequest; using UserlandFSUtil::GetVNodeReply; using UserlandFSUtil::PutVNodeRequest; using UserlandFSUtil::PutVNodeReply; +using UserlandFSUtil::AcquireVNodeRequest; +using UserlandFSUtil::AcquireVNodeReply; using UserlandFSUtil::NewVNodeRequest; using UserlandFSUtil::NewVNodeReply; using UserlandFSUtil::PublishVNodeRequest; 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 d90e199115..045b30b80c 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 @@ -72,6 +72,8 @@ KernelRequestHandler::HandleRequest(Request* request) return _HandleRequest((GetVNodeRequest*)request); case PUT_VNODE_REQUEST: return _HandleRequest((PutVNodeRequest*)request); + case ACQUIRE_VNODE_REQUEST: + return _HandleRequest((AcquireVNodeRequest*)request); case NEW_VNODE_REQUEST: return _HandleRequest((NewVNodeRequest*)request); case PUBLISH_VNODE_REQUEST: @@ -346,6 +348,31 @@ KernelRequestHandler::_HandleRequest(PutVNodeRequest* request) return fPort->SendRequest(&allocator); } + +// _HandleRequest +status_t +KernelRequestHandler::_HandleRequest(AcquireVNodeRequest* request) +{ + // check and executed the request + Volume* volume = NULL; + status_t result = _GetVolume(request->nsid, &volume); + VolumePutter _(volume); + if (result == B_OK) + result = volume->AcquireVNode(request->vnid); + + // prepare the reply + RequestAllocator allocator(fPort->GetPort()); + AcquireVNodeReply* 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(NewVNodeRequest* 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 34f4b10f1c..e3aa140bda 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 @@ -12,6 +12,7 @@ namespace UserlandFSUtil { +class AcquireVNodeRequest; class GetVNodeRemovedRequest; class GetVNodeRequest; class NewVNodeRequest; @@ -25,6 +26,7 @@ class UnremoveVNodeRequest; } +using UserlandFSUtil::AcquireVNodeRequest; using UserlandFSUtil::GetVNodeRemovedRequest; using UserlandFSUtil::GetVNodeRequest; using UserlandFSUtil::NewVNodeRequest; @@ -57,6 +59,7 @@ private: // vnodes status_t _HandleRequest(GetVNodeRequest* request); status_t _HandleRequest(PutVNodeRequest* request); + status_t _HandleRequest(AcquireVNodeRequest* request); status_t _HandleRequest(NewVNodeRequest* request); status_t _HandleRequest(PublishVNodeRequest* request); status_t _HandleRequest(RemoveVNodeRequest* 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 e9dff6a893..32a83e18f3 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 @@ -151,6 +151,24 @@ PRINT(("put_vnode(%ld, %lld)\n", GetID(), vnid)); return error; } + +// AcquireVNode +status_t +Volume::AcquireVNode(ino_t vnid) +{ +PRINT(("acquire_vnode(%ld, %lld)\n", GetID(), vnid)); + if (IsMounting() && !fMountVNodes->ContainsKey(vnid)) { + ERROR(("Volume::AcquireVNode(): acquire_vnode() invoked for unknown " + "vnode while mounting!\n")); + } + + status_t error = acquire_vnode(fFSVolume, vnid); + if (error == B_OK) + _IncrementVNodeCount(vnid); + return error; +} + + // NewVNode status_t Volume::NewVNode(ino_t vnid, void* node) 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 80244057a1..28badd10ec 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 @@ -49,6 +49,7 @@ public: // client methods status_t GetVNode(ino_t vnid, void** node); status_t PutVNode(ino_t vnid); + status_t AcquireVNode(ino_t vnid); status_t NewVNode(ino_t vnid, void* node); status_t PublishVNode(ino_t vnid, void* node, int type, uint32 flags); 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 cf79dc1629..34e6dbbe49 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 @@ -328,10 +328,37 @@ UserlandFS::KernelEmu::put_vnode(dev_t nsid, ino_t vnid) // acquire_vnode status_t -UserlandFS::KernelEmu::acquire_vnode(dev_t nsid, ino_t vnodeID) +UserlandFS::KernelEmu::acquire_vnode(dev_t nsid, ino_t vnid) { - // 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()); + AcquireVNodeRequest* request; + error = AllocateRequest(allocator, &request); + if (error != B_OK) + return error; + + request->nsid = nsid; + request->vnid = vnid; + + // send the request + UserlandRequestHandler handler(fileSystem, ACQUIRE_VNODE_REPLY); + AcquireVNodeReply* 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; } // new_vnode @@ -420,7 +447,6 @@ UserlandFS::KernelEmu::publish_vnode(dev_t nsid, ino_t vnid, void* data) 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)