* For every request to userland we also send the team/thread/user/group ID of

the current thread, now. Implemented by introducing a new base class
  KernelRequest which has respective attributes.
* Server: RequestThreadContext does now also save the request that is being
  processed. Furthermore some space has been reserved for file system specific
  data, which can be initialized by the new
  FileSystem::InitRequestThreadContext().
* FUSE library: Implemented fuse_get_context() using the new
  RequestThreadContext feature.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29872 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2009-04-02 19:41:53 +00:00
parent a773113804
commit e66cd9d71b
11 changed files with 193 additions and 87 deletions
+17 -5
View File
@@ -256,10 +256,21 @@ public:
// #pragma mark - kernel requests // #pragma mark - kernel requests
// VolumeRequest // KernelRequest
class VolumeRequest : public Request { class KernelRequest : public Request {
public: public:
VolumeRequest(uint32 type) : Request(type) {} KernelRequest(uint32 type) : Request(type) {}
team_id team;
thread_id thread;
uid_t user;
gid_t group;
};
// VolumeRequest
class VolumeRequest : public KernelRequest {
public:
VolumeRequest(uint32 type) : KernelRequest(type) {}
void* volume; void* volume;
}; };
@@ -365,9 +376,9 @@ public:
// MountVolumeRequest // MountVolumeRequest
class MountVolumeRequest : public Request { class MountVolumeRequest : public KernelRequest {
public: public:
MountVolumeRequest() : Request(MOUNT_VOLUME_REQUEST) {} MountVolumeRequest() : KernelRequest(MOUNT_VOLUME_REQUEST) {}
status_t GetAddressInfos(AddressInfo* infos, int32* count); status_t GetAddressInfos(AddressInfo* infos, int32* count);
dev_t nsid; dev_t nsid;
@@ -2235,6 +2246,7 @@ status_t relocate_request(Request* request, int32 requestBufferSize,
} // namespace UserlandFSUtil } // namespace UserlandFSUtil
using UserlandFSUtil::ReplyRequest; using UserlandFSUtil::ReplyRequest;
using UserlandFSUtil::KernelRequest;
using UserlandFSUtil::VolumeRequest; using UserlandFSUtil::VolumeRequest;
using UserlandFSUtil::NodeRequest; using UserlandFSUtil::NodeRequest;
using UserlandFSUtil::FileRequest; using UserlandFSUtil::FileRequest;
@@ -18,6 +18,7 @@
#include <util/OpenHashTable.h> #include <util/OpenHashTable.h>
#include <fs/fd.h> // kernel private #include <fs/fd.h> // kernel private
#include <thread.h>
#include "IORequest.h" // kernel internal #include "IORequest.h" // kernel internal
@@ -4327,6 +4328,15 @@ status_t
Volume::_SendRequest(RequestPort* port, RequestAllocator* allocator, Volume::_SendRequest(RequestPort* port, RequestAllocator* allocator,
RequestHandler* handler, Request** reply) RequestHandler* handler, Request** reply)
{ {
// fill in the caller info
KernelRequest* request = static_cast<KernelRequest*>(
allocator->GetRequest());
struct thread* thread = thread_get_current_thread();
request->team = thread->team->id;
request->thread = thread->id;
request->user = geteuid();
request->group = getegid();
if (!fFileSystem->IsUserlandServerThread()) if (!fFileSystem->IsUserlandServerThread())
return port->SendRequest(allocator, handler, reply); return port->SendRequest(allocator, handler, reply);
// Here it gets dangerous: a thread of the userland server team being here // Here it gets dangerous: a thread of the userland server team being here
@@ -1,4 +1,7 @@
// FileSystem.cpp /*
* Copyright 2001-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "FileSystem.h" #include "FileSystem.h"
@@ -32,6 +35,12 @@ FileSystem::GetInstance()
} }
void
FileSystem::InitRequestThreadContext(RequestThreadContext* context)
{
}
void void
FileSystem::RegisterVolume(Volume* volume) FileSystem::RegisterVolume(Volume* volume)
{ {
@@ -1,5 +1,7 @@
// FileSystem.h /*
* Copyright 2001-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef USERLAND_FS_FILE_SYSTEM_H #ifndef USERLAND_FS_FILE_SYSTEM_H
#define USERLAND_FS_FILE_SYSTEM_H #define USERLAND_FS_FILE_SYSTEM_H
@@ -15,8 +17,10 @@
namespace UserlandFS { namespace UserlandFS {
class RequestThreadContext;
class Volume; class Volume;
class FileSystem { class FileSystem {
public: public:
FileSystem(const char* fsName); FileSystem(const char* fsName);
@@ -29,6 +33,9 @@ public:
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;
virtual void InitRequestThreadContext(
RequestThreadContext* context);
void RegisterVolume(Volume* volume); void RegisterVolume(Volume* volume);
void UnregisterVolume(Volume* volume); void UnregisterVolume(Volume* volume);
Volume* VolumeWithID(dev_t id); Volume* VolumeWithID(dev_t id);
@@ -1,28 +1,39 @@
// RequestThread.cpp /*
* Copyright 2001-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "RequestThread.h"
#include <new> #include <new>
#include <TLS.h> #include <TLS.h>
#include "RequestThread.h" #include "FileSystem.h"
#include "ServerDefs.h" #include "ServerDefs.h"
#include "UserlandRequestHandler.h" #include "UserlandRequestHandler.h"
#include "Volume.h"
using std::nothrow;
static const int32 sTLSVariable = tls_allocate(); static const int32 sTLSVariable = tls_allocate();
// constructor // constructor
RequestThreadContext::RequestThreadContext(Volume* volume) RequestThreadContext::RequestThreadContext(Volume* volume,
: fPreviousContext(NULL), KernelRequest* request)
fThread(NULL), :
fVolume(volume) fPreviousContext(NULL),
fThread(NULL),
fVolume(volume),
fRequest(request)
{ {
fThread = RequestThread::GetCurrentThread(); fThread = RequestThread::GetCurrentThread();
if (fThread) { if (fThread) {
fPreviousContext = fThread->GetContext(); fPreviousContext = fThread->GetContext();
fThread->SetContext(this); fThread->SetContext(this);
} }
volume->GetFileSystem()->InitRequestThreadContext(this);
} }
// destructor // destructor
@@ -74,7 +85,7 @@ RequestThread::Init(FileSystem* fileSystem)
if (!fileSystem) if (!fileSystem)
return B_BAD_VALUE; return B_BAD_VALUE;
// create the port // create the port
fPort = new(nothrow) RequestPort(kRequestPortSize); fPort = new(std::nothrow) RequestPort(kRequestPortSize);
if (!fPort) if (!fPort)
return B_NO_MEMORY; return B_NO_MEMORY;
status_t error = fPort->InitCheck(); status_t error = fPort->InitCheck();
@@ -1,5 +1,7 @@
// RequestThread.h /*
* Copyright 2001-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef USERLAND_FS_REQUEST_THREAD_H #ifndef USERLAND_FS_REQUEST_THREAD_H
#define USERLAND_FS_REQUEST_THREAD_H #define USERLAND_FS_REQUEST_THREAD_H
@@ -11,19 +13,26 @@ class FileSystem;
class RequestThread; class RequestThread;
class Volume; class Volume;
#define REQUEST_THREAD_CONTEXT_FS_DATA_SIZE 256
// RequestThreadContext // RequestThreadContext
class RequestThreadContext { class RequestThreadContext {
public: public:
RequestThreadContext(Volume* volume); RequestThreadContext(Volume* volume,
KernelRequest* request);
~RequestThreadContext(); ~RequestThreadContext();
RequestThread* GetThread() const; RequestThread* GetThread() const;
Volume* GetVolume() const; Volume* GetVolume() const;
KernelRequest* GetRequest() const { return fRequest; }
void* GetFSData() { return fFSData; }
private: private:
RequestThreadContext* fPreviousContext; RequestThreadContext* fPreviousContext;
RequestThread* fThread; RequestThread* fThread;
Volume* fVolume; Volume* fVolume;
KernelRequest* fRequest;
uint8 fFSData[REQUEST_THREAD_CONTEXT_FS_DATA_SIZE];
}; };
// RequestThread // RequestThread
@@ -51,6 +51,7 @@ UserlandRequestHandler::HandleRequest(Request* request)
fDone = true; fDone = true;
return B_OK; return B_OK;
} }
switch (request->GetType()) { switch (request->GetType()) {
// FS // FS
case MOUNT_VOLUME_REQUEST: case MOUNT_VOLUME_REQUEST:
@@ -253,7 +254,7 @@ UserlandRequestHandler::_HandleRequest(MountVolumeRequest* request)
// mount it // mount it
ino_t rootID; ino_t rootID;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->Mount(device, request->flags, result = volume->Mount(device, request->flags,
(const char*)request->parameters.GetData(), &rootID); (const char*)request->parameters.GetData(), &rootID);
if (result != B_OK) if (result != B_OK)
@@ -288,7 +289,7 @@ UserlandRequestHandler::_HandleRequest(UnmountVolumeRequest* request)
if (!volume) if (!volume)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->Unmount(); result = volume->Unmount();
} }
@@ -314,7 +315,7 @@ UserlandRequestHandler::_HandleRequest(SyncVolumeRequest* request)
if (!volume) if (!volume)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->Sync(); result = volume->Sync();
} }
// prepare the reply // prepare the reply
@@ -340,7 +341,7 @@ UserlandRequestHandler::_HandleRequest(ReadFSInfoRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
fs_info info; fs_info info;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->ReadFSInfo(&info); result = volume->ReadFSInfo(&info);
} }
// prepare the reply // prepare the reply
@@ -366,7 +367,7 @@ UserlandRequestHandler::_HandleRequest(WriteFSInfoRequest* request)
if (!volume) if (!volume)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->WriteFSInfo(&request->info, request->mask); result = volume->WriteFSInfo(&request->info, request->mask);
} }
@@ -398,7 +399,7 @@ UserlandRequestHandler::_HandleRequest(LookupRequest* request)
ino_t vnid = 0; ino_t vnid = 0;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->Lookup(request->node, result = volume->Lookup(request->node,
(const char*)request->entryName.GetData(), &vnid); (const char*)request->entryName.GetData(), &vnid);
} }
@@ -444,7 +445,7 @@ UserlandRequestHandler::_HandleRequest(GetVNodeNameRequest* request)
// execute the request // execute the request
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->GetVNodeName(node, buffer, bufferSize); result = volume->GetVNodeName(node, buffer, bufferSize);
} }
@@ -471,7 +472,7 @@ UserlandRequestHandler::_HandleRequest(ReadVNodeRequest* request)
uint32 flags; uint32 flags;
FSVNodeCapabilities capabilities; FSVNodeCapabilities capabilities;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->ReadVNode(request->vnid, request->reenter, &node, result = volume->ReadVNode(request->vnid, request->reenter, &node,
&type, &flags, &capabilities); &type, &flags, &capabilities);
} }
@@ -504,7 +505,7 @@ UserlandRequestHandler::_HandleRequest(WriteVNodeRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->WriteVNode(request->node, request->reenter); result = volume->WriteVNode(request->node, request->reenter);
} }
@@ -532,7 +533,7 @@ UserlandRequestHandler::_HandleRequest(FSRemoveVNodeRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->RemoveVNode(request->node, request->reenter); result = volume->RemoveVNode(request->node, request->reenter);
} }
@@ -563,7 +564,7 @@ UserlandRequestHandler::_HandleRequest(DoIORequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
IORequestInfo requestInfo(request->request, request->isWrite, IORequestInfo requestInfo(request->request, request->isWrite,
request->offset, request->length); request->offset, request->length);
result = volume->DoIO(request->node, request->fileCookie, requestInfo); result = volume->DoIO(request->node, request->fileCookie, requestInfo);
@@ -593,7 +594,7 @@ UserlandRequestHandler::_HandleRequest(CancelIORequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->CancelIO(request->node, request->fileCookie, result = volume->CancelIO(request->node, request->fileCookie,
request->request); request->request);
} }
@@ -625,7 +626,7 @@ UserlandRequestHandler::_HandleRequest(IterativeIOGetVecsRequest* request)
file_io_vec vecs[IterativeIOGetVecsReply::MAX_VECS]; file_io_vec vecs[IterativeIOGetVecsReply::MAX_VECS];
size_t vecCount = IterativeIOGetVecsReply::MAX_VECS; size_t vecCount = IterativeIOGetVecsReply::MAX_VECS;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->IterativeIOGetVecs(request->cookie, request->request, result = volume->IterativeIOGetVecs(request->cookie, request->request,
request->offset, request->size, vecs, &vecCount); request->offset, request->size, vecs, &vecCount);
if (result == B_OK) { if (result == B_OK) {
@@ -664,7 +665,7 @@ UserlandRequestHandler::_HandleRequest(IterativeIOFinishedRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->IterativeIOFinished(request->cookie, request->request, result = volume->IterativeIOFinished(request->cookie, request->request,
request->status, request->partialTransfer, request->status, request->partialTransfer,
request->bytesTransferred); request->bytesTransferred);
@@ -729,7 +730,7 @@ UserlandRequestHandler::_HandleRequest(IOCtlRequest* request)
// execute the request // execute the request
status_t ioctlError = B_OK; status_t ioctlError = B_OK;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
ioctlError = volume->IOCtl(request->node, request->fileCookie, ioctlError = volume->IOCtl(request->node, request->fileCookie,
request->command, buffer, len); request->command, buffer, len);
} }
@@ -754,7 +755,7 @@ UserlandRequestHandler::_HandleRequest(SetFlagsRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->SetFlags(request->node, request->fileCookie, result = volume->SetFlags(request->node, request->fileCookie,
request->flags); request->flags);
} }
@@ -783,7 +784,7 @@ UserlandRequestHandler::_HandleRequest(SelectRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->Select(request->node, request->fileCookie, result = volume->Select(request->node, request->fileCookie,
request->event, request->sync); request->event, request->sync);
} }
@@ -812,7 +813,7 @@ UserlandRequestHandler::_HandleRequest(DeselectRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->Deselect(request->node, request->fileCookie, result = volume->Deselect(request->node, request->fileCookie,
request->event, request->sync); request->event, request->sync);
} }
@@ -841,7 +842,7 @@ UserlandRequestHandler::_HandleRequest(FSyncRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->FSync(request->node); result = volume->FSync(request->node);
} }
@@ -886,7 +887,7 @@ UserlandRequestHandler::_HandleRequest(ReadSymlinkRequest* request)
// execute the request // execute the request
size_t bytesRead; size_t bytesRead;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->ReadSymlink(node, buffer, bufferSize, &bytesRead); result = volume->ReadSymlink(node, buffer, bufferSize, &bytesRead);
} }
@@ -910,7 +911,7 @@ UserlandRequestHandler::_HandleRequest(CreateSymlinkRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->CreateSymlink(request->node, result = volume->CreateSymlink(request->node,
(const char*)request->name.GetData(), (const char*)request->name.GetData(),
(const char*)request->target.GetData(), request->mode); (const char*)request->target.GetData(), request->mode);
@@ -940,7 +941,7 @@ UserlandRequestHandler::_HandleRequest(LinkRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->Link(request->node, result = volume->Link(request->node,
(const char*)request->name.GetData(), request->target); (const char*)request->name.GetData(), request->target);
} }
@@ -969,7 +970,7 @@ UserlandRequestHandler::_HandleRequest(UnlinkRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->Unlink(request->node, result = volume->Unlink(request->node,
(const char*)request->name.GetData()); (const char*)request->name.GetData());
} }
@@ -998,7 +999,7 @@ UserlandRequestHandler::_HandleRequest(RenameRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->Rename(request->oldDir, result = volume->Rename(request->oldDir,
(const char*)request->oldName.GetData(), request->newDir, (const char*)request->oldName.GetData(), request->newDir,
(const char*)request->newName.GetData()); (const char*)request->newName.GetData());
@@ -1028,7 +1029,7 @@ UserlandRequestHandler::_HandleRequest(AccessRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->Access(request->node, request->mode); result = volume->Access(request->node, request->mode);
} }
@@ -1057,7 +1058,7 @@ UserlandRequestHandler::_HandleRequest(ReadStatRequest* request)
struct stat st; struct stat st;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->ReadStat(request->node, &st); result = volume->ReadStat(request->node, &st);
} }
@@ -1086,7 +1087,7 @@ UserlandRequestHandler::_HandleRequest(WriteStatRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->WriteStat(request->node, &request->st, request->mask); result = volume->WriteStat(request->node, &request->st, request->mask);
} }
@@ -1120,7 +1121,7 @@ UserlandRequestHandler::_HandleRequest(CreateRequest* request)
ino_t vnid; ino_t vnid;
void* fileCookie; void* fileCookie;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->Create(request->node, result = volume->Create(request->node,
(const char*)request->name.GetData(), request->openMode, (const char*)request->name.GetData(), request->openMode,
request->mode, &fileCookie, &vnid); request->mode, &fileCookie, &vnid);
@@ -1153,7 +1154,7 @@ UserlandRequestHandler::_HandleRequest(OpenRequest* request)
void* fileCookie; void* fileCookie;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->Open(request->node, request->openMode, &fileCookie); result = volume->Open(request->node, request->openMode, &fileCookie);
} }
@@ -1182,7 +1183,7 @@ UserlandRequestHandler::_HandleRequest(CloseRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->Close(request->node, request->fileCookie); result = volume->Close(request->node, request->fileCookie);
} }
@@ -1210,7 +1211,7 @@ UserlandRequestHandler::_HandleRequest(FreeCookieRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->FreeCookie(request->node, request->fileCookie); result = volume->FreeCookie(request->node, request->fileCookie);
} }
@@ -1258,7 +1259,7 @@ UserlandRequestHandler::_HandleRequest(ReadRequest* request)
// execute the request // execute the request
size_t bytesRead; size_t bytesRead;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->Read(node, fileCookie, pos, buffer, size, &bytesRead); result = volume->Read(node, fileCookie, pos, buffer, size, &bytesRead);
} }
@@ -1283,7 +1284,7 @@ UserlandRequestHandler::_HandleRequest(WriteRequest* request)
size_t bytesWritten; size_t bytesWritten;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->Write(request->node, request->fileCookie, result = volume->Write(request->node, request->fileCookie,
request->pos, request->buffer.GetData(), request->buffer.GetSize(), request->pos, request->buffer.GetData(), request->buffer.GetSize(),
&bytesWritten); &bytesWritten);
@@ -1318,7 +1319,7 @@ UserlandRequestHandler::_HandleRequest(CreateDirRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->CreateDir(request->node, result = volume->CreateDir(request->node,
(const char*)request->name.GetData(), request->mode); (const char*)request->name.GetData(), request->mode);
} }
@@ -1347,7 +1348,7 @@ UserlandRequestHandler::_HandleRequest(RemoveDirRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->RemoveDir(request->node, result = volume->RemoveDir(request->node,
(const char*)request->name.GetData()); (const char*)request->name.GetData());
} }
@@ -1377,7 +1378,7 @@ UserlandRequestHandler::_HandleRequest(OpenDirRequest* request)
void* dirCookie = NULL; void* dirCookie = NULL;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->OpenDir(request->node, &dirCookie); result = volume->OpenDir(request->node, &dirCookie);
} }
@@ -1406,7 +1407,7 @@ UserlandRequestHandler::_HandleRequest(CloseDirRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->CloseDir(request->node, request->dirCookie); result = volume->CloseDir(request->node, request->dirCookie);
} }
@@ -1434,7 +1435,7 @@ UserlandRequestHandler::_HandleRequest(FreeDirCookieRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->FreeDirCookie(request->node, request->dirCookie); result = volume->FreeDirCookie(request->node, request->dirCookie);
} }
@@ -1482,7 +1483,7 @@ UserlandRequestHandler::_HandleRequest(ReadDirRequest* request)
// execute the request // execute the request
uint32 countRead; uint32 countRead;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->ReadDir(node, dirCookie, buffer, bufferSize, count, result = volume->ReadDir(node, dirCookie, buffer, bufferSize, count,
&countRead); &countRead);
} }
@@ -1517,7 +1518,7 @@ UserlandRequestHandler::_HandleRequest(RewindDirRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->RewindDir(request->node, request->dirCookie); result = volume->RewindDir(request->node, request->dirCookie);
} }
@@ -1550,7 +1551,7 @@ UserlandRequestHandler::_HandleRequest(OpenAttrDirRequest* request)
void* attrDirCookie; void* attrDirCookie;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->OpenAttrDir(request->node, &attrDirCookie); result = volume->OpenAttrDir(request->node, &attrDirCookie);
} }
@@ -1579,7 +1580,7 @@ UserlandRequestHandler::_HandleRequest(CloseAttrDirRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->CloseAttrDir(request->node, request->attrDirCookie); result = volume->CloseAttrDir(request->node, request->attrDirCookie);
} }
@@ -1607,7 +1608,7 @@ UserlandRequestHandler::_HandleRequest(FreeAttrDirCookieRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->FreeAttrDirCookie(request->node, result = volume->FreeAttrDirCookie(request->node,
request->attrDirCookie); request->attrDirCookie);
} }
@@ -1656,7 +1657,7 @@ UserlandRequestHandler::_HandleRequest(ReadAttrDirRequest* request)
// execute the request // execute the request
uint32 countRead; uint32 countRead;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->ReadAttrDir(node, attrDirCookie, buffer, bufferSize, result = volume->ReadAttrDir(node, attrDirCookie, buffer, bufferSize,
count, &countRead); count, &countRead);
} }
@@ -1681,7 +1682,7 @@ UserlandRequestHandler::_HandleRequest(RewindAttrDirRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->RewindAttrDir(request->node, request->attrDirCookie); result = volume->RewindAttrDir(request->node, request->attrDirCookie);
} }
@@ -1714,7 +1715,7 @@ UserlandRequestHandler::_HandleRequest(CreateAttrRequest* request)
void* attrCookie; void* attrCookie;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->CreateAttr(request->node, result = volume->CreateAttr(request->node,
(const char*)request->name.GetData(), request->type, (const char*)request->name.GetData(), request->type,
request->openMode, &attrCookie); request->openMode, &attrCookie);
@@ -1746,7 +1747,7 @@ UserlandRequestHandler::_HandleRequest(OpenAttrRequest* request)
void* attrCookie; void* attrCookie;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->OpenAttr(request->node, result = volume->OpenAttr(request->node,
(const char*)request->name.GetData(), request->openMode, (const char*)request->name.GetData(), request->openMode,
&attrCookie); &attrCookie);
@@ -1777,7 +1778,7 @@ UserlandRequestHandler::_HandleRequest(CloseAttrRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->CloseAttr(request->node, request->attrCookie); result = volume->CloseAttr(request->node, request->attrCookie);
} }
@@ -1805,7 +1806,7 @@ UserlandRequestHandler::_HandleRequest(FreeAttrCookieRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->FreeAttrCookie(request->node, request->attrCookie); result = volume->FreeAttrCookie(request->node, request->attrCookie);
} }
@@ -1853,7 +1854,7 @@ UserlandRequestHandler::_HandleRequest(ReadAttrRequest* request)
// execute the request // execute the request
size_t bytesRead; size_t bytesRead;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->ReadAttr(node, attrCookie, pos, buffer, size, result = volume->ReadAttr(node, attrCookie, pos, buffer, size,
&bytesRead); &bytesRead);
} }
@@ -1879,7 +1880,7 @@ UserlandRequestHandler::_HandleRequest(WriteAttrRequest* request)
size_t bytesWritten; size_t bytesWritten;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->WriteAttr(request->node, request->attrCookie, result = volume->WriteAttr(request->node, request->attrCookie,
request->pos, request->buffer.GetData(), request->buffer.GetSize(), request->pos, request->buffer.GetData(), request->buffer.GetSize(),
&bytesWritten); &bytesWritten);
@@ -1911,7 +1912,7 @@ UserlandRequestHandler::_HandleRequest(ReadAttrStatRequest* request)
struct stat st; struct stat st;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->ReadAttrStat(request->node, request->attrCookie, result = volume->ReadAttrStat(request->node, request->attrCookie,
&st); &st);
} }
@@ -1941,7 +1942,7 @@ UserlandRequestHandler::_HandleRequest(WriteAttrStatRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->WriteAttrStat(request->node, request->attrCookie, result = volume->WriteAttrStat(request->node, request->attrCookie,
&request->st, request->mask); &request->st, request->mask);
} }
@@ -1970,7 +1971,7 @@ UserlandRequestHandler::_HandleRequest(RenameAttrRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->RenameAttr( result = volume->RenameAttr(
request->oldNode, (const char*)request->oldName.GetData(), request->oldNode, (const char*)request->oldName.GetData(),
request->newNode, (const char*)request->newName.GetData()); request->newNode, (const char*)request->newName.GetData());
@@ -2000,7 +2001,7 @@ UserlandRequestHandler::_HandleRequest(RemoveAttrRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->RemoveAttr(request->node, result = volume->RemoveAttr(request->node,
(const char*)request->name.GetData()); (const char*)request->name.GetData());
} }
@@ -2034,7 +2035,7 @@ UserlandRequestHandler::_HandleRequest(OpenIndexDirRequest* request)
void* indexDirCookie; void* indexDirCookie;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->OpenIndexDir(&indexDirCookie); result = volume->OpenIndexDir(&indexDirCookie);
} }
@@ -2063,7 +2064,7 @@ UserlandRequestHandler::_HandleRequest(CloseIndexDirRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->CloseIndexDir(request->indexDirCookie); result = volume->CloseIndexDir(request->indexDirCookie);
} }
@@ -2091,7 +2092,7 @@ UserlandRequestHandler::_HandleRequest(FreeIndexDirCookieRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->FreeIndexDirCookie(request->indexDirCookie); result = volume->FreeIndexDirCookie(request->indexDirCookie);
} }
@@ -2138,7 +2139,7 @@ UserlandRequestHandler::_HandleRequest(ReadIndexDirRequest* request)
// execute the request // execute the request
uint32 countRead; uint32 countRead;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->ReadIndexDir(indexDirCookie, buffer, bufferSize, result = volume->ReadIndexDir(indexDirCookie, buffer, bufferSize,
count, &countRead); count, &countRead);
} }
@@ -2163,7 +2164,7 @@ UserlandRequestHandler::_HandleRequest(RewindIndexDirRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->RewindIndexDir(request->indexDirCookie); result = volume->RewindIndexDir(request->indexDirCookie);
} }
@@ -2191,7 +2192,7 @@ UserlandRequestHandler::_HandleRequest(CreateIndexRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->CreateIndex((const char*)request->name.GetData(), result = volume->CreateIndex((const char*)request->name.GetData(),
request->type, request->flags); request->type, request->flags);
} }
@@ -2220,7 +2221,7 @@ UserlandRequestHandler::_HandleRequest(RemoveIndexRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->RemoveIndex((const char*)request->name.GetData()); result = volume->RemoveIndex((const char*)request->name.GetData());
} }
@@ -2249,7 +2250,7 @@ UserlandRequestHandler::_HandleRequest(ReadIndexStatRequest* request)
struct stat st; struct stat st;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->ReadIndexStat((const char*)request->name.GetData(), result = volume->ReadIndexStat((const char*)request->name.GetData(),
&st); &st);
} }
@@ -2284,7 +2285,7 @@ UserlandRequestHandler::_HandleRequest(OpenQueryRequest* request)
void* queryCookie; void* queryCookie;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->OpenQuery((const char*)request->queryString.GetData(), result = volume->OpenQuery((const char*)request->queryString.GetData(),
request->flags, request->port, request->token, &queryCookie); request->flags, request->port, request->token, &queryCookie);
} }
@@ -2314,7 +2315,7 @@ UserlandRequestHandler::_HandleRequest(CloseQueryRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->CloseQuery(request->queryCookie); result = volume->CloseQuery(request->queryCookie);
} }
@@ -2342,7 +2343,7 @@ UserlandRequestHandler::_HandleRequest(FreeQueryCookieRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->FreeQueryCookie(request->queryCookie); result = volume->FreeQueryCookie(request->queryCookie);
} }
@@ -2389,7 +2390,7 @@ UserlandRequestHandler::_HandleRequest(ReadQueryRequest* request)
// execute the request // execute the request
uint32 countRead; uint32 countRead;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->ReadQuery(queryCookie, buffer, bufferSize, result = volume->ReadQuery(queryCookie, buffer, bufferSize,
count, &countRead); count, &countRead);
} }
@@ -2414,7 +2415,7 @@ UserlandRequestHandler::_HandleRequest(RewindQueryRequest* request)
result = B_BAD_VALUE; result = B_BAD_VALUE;
if (result == B_OK) { if (result == B_OK) {
RequestThreadContext context(volume); RequestThreadContext context(volume, request);
result = volume->RewindQuery(request->queryCookie); result = volume->RewindQuery(request->queryCookie);
} }
@@ -13,6 +13,8 @@
#include "fuse_fs.h" #include "fuse_fs.h"
#include "FUSEVolume.h" #include "FUSEVolume.h"
#include "../RequestThread.h"
class FUSEFileSystem::ArgumentVector { class FUSEFileSystem::ArgumentVector {
private: private:
@@ -180,6 +182,30 @@ FUSEFileSystem::DeleteVolume(Volume* volume)
} }
void
FUSEFileSystem::InitRequestThreadContext(RequestThreadContext* context)
{
// Statically assert that fuse_context fits in the RequestThreadContext
// FS data. We can't include <Debug.h> as it clashes with our "Debug.h".
do {
static const int staticAssertHolds
= sizeof(fuse_context) <= REQUEST_THREAD_CONTEXT_FS_DATA_SIZE;
struct __staticAssertStruct__ {
char __static_assert_failed__[2 * staticAssertHolds - 1];
};
} while (false);
// init a fuse_context
KernelRequest* request = context->GetRequest();
fuse_context* fuseContext = (fuse_context*)context->GetFSData();
fuseContext->fuse = (struct fuse*)this;
fuseContext->uid = request->user;
fuseContext->gid = request->group;
fuseContext->pid = request->team;
fuseContext->private_data = fFS != NULL ? fFS->userData : NULL;
}
status_t status_t
FUSEFileSystem::InitClientFS(const char* parameters) FUSEFileSystem::InitClientFS(const char* parameters)
{ {
@@ -38,6 +38,9 @@ public:
virtual status_t CreateVolume(Volume** _volume, dev_t id); virtual status_t CreateVolume(Volume** _volume, dev_t id);
virtual status_t DeleteVolume(Volume* volume); virtual status_t DeleteVolume(Volume* volume);
virtual void InitRequestThreadContext(
RequestThreadContext* context);
status_t InitClientFS(const char* parameters); status_t InitClientFS(const char* parameters);
void ExitClientFS(status_t status); void ExitClientFS(status_t status);
@@ -17,6 +17,7 @@
#include "FUSEFileSystem.h" #include "FUSEFileSystem.h"
#include "../kernel_emu.h" #include "../kernel_emu.h"
#include "../RequestThread.h"
// TODO: For remote/shared file systems (sshfs, nfs, etc.) we need to notice // TODO: For remote/shared file systems (sshfs, nfs, etc.) we need to notice
@@ -673,6 +674,11 @@ printf("FUSEVolume::Mount()\n");
const fuse_config& config = _FileSystem()->GetFUSEConfig(); const fuse_config& config = _FileSystem()->GetFUSEConfig();
fUseNodeIDs = config.use_ino; fUseNodeIDs = config.use_ino;
// update the fuse_context::private_data field before calling into the FS
fuse_context* context = (fuse_context*)RequestThread::GetCurrentThread()
->GetContext()->GetFSData();
context->private_data = fFS->userData;
// get the root node // get the root node
struct stat st; struct stat st;
int fuseError = fuse_fs_getattr(fFS, "/", &st); int fuseError = fuse_fs_getattr(fFS, "/", &st);
@@ -10,6 +10,8 @@
#include "fuse_config.h" #include "fuse_config.h"
#include "FUSEFileSystem.h" #include "FUSEFileSystem.h"
#include "../RequestThread.h"
int int
fuse_main_real(int argc, char* argv[], const struct fuse_operations* op, fuse_main_real(int argc, char* argv[], const struct fuse_operations* op,
@@ -48,3 +50,13 @@ fuse_version(void)
{ {
return FUSE_VERSION; return FUSE_VERSION;
} }
struct fuse_context*
fuse_get_context(void)
{
RequestThread* requestThread = RequestThread::GetCurrentThread();
return requestThread != NULL
? (fuse_context*)requestThread->GetContext()->GetFSData()
: NULL;
}