nfs4: Add per server NFS4 objects

RPC::Server is now able to store RPC programs data.
NFS4Server objects are currently used mainly for managing client id.
This commit is contained in:
Pawel Dziepak
2012-06-29 02:14:44 +02:00
parent 96e3dbc2d0
commit 6ee3ed0f6f
9 changed files with 184 additions and 39 deletions
@@ -11,7 +11,7 @@
#include "InodeIdMap.h" #include "InodeIdMap.h"
#include "NFS4Defs.h" #include "NFS4Defs.h"
#include "RPCServer.h" #include "NFS4Server.h"
class Inode; class Inode;
@@ -27,7 +27,10 @@ public:
Inode* CreateRootInode(); Inode* CreateRootInode();
inline uint32 FHExpiryType() const; inline uint32 FHExpiryType() const;
inline RPC::Server* Server(); inline RPC::Server* Server();
inline NFS4Server* NFSServer();
inline uint64 AllocFileId(); inline uint64 AllocFileId();
inline dev_t DevId() const; inline dev_t DevId() const;
@@ -55,6 +58,13 @@ Filesystem::Server()
} }
inline NFS4Server*
Filesystem::NFSServer()
{
return reinterpret_cast<NFS4Server*>(fServer->PrivateData());
}
inline uint64 inline uint64
Filesystem::AllocFileId() Filesystem::AllocFileId()
{ {
+10 -33
View File
@@ -83,9 +83,6 @@ Inode::~Inode()
} }
// filesystems that do not provide fileid are currently unsupported
// client will have to be able to create its own mapping between file names
// and made up IDs
status_t status_t
Inode::LookUp(const char* name, ino_t* id) Inode::LookUp(const char* name, ino_t* id)
{ {
@@ -309,39 +306,16 @@ Inode::Stat(struct stat* st)
status_t status_t
Inode::Open(int mode, OpenFileCookie* cookie) Inode::Open(int mode, OpenFileCookie* cookie)
{ {
cookie->fSeq = 0; cookie->fClientId = fFilesystem->NFSServer()->ClientId();
Request request(fFilesystem->Server()); Request request(fFilesystem->Server());
request.Builder().SetClientID(fFilesystem->Server());
status_t result = request.Send();
if (result != B_OK)
return result;
uint64 id, ver;
result = request.Reply().SetClientID(&id, &ver);
if (result != B_OK)
return result;
request.Reset();
request.Builder().SetClientIDConfirm(id, ver);
result = request.Send();
if (result != B_OK)
return result;
result = request.Reply().SetClientIDConfirm();
if (result != B_OK)
return result;
request.Reset();
RequestBuilder& req = request.Builder(); RequestBuilder& req = request.Builder();
req.PutFH(fParentFH); req.PutFH(fParentFH);
req.Open(cookie->fSeq, OPEN4_SHARE_ACCESS_READ, id, OPEN4_NOCREATE, fName); req.Open(fFilesystem->NFSServer()->SequenceId(), OPEN4_SHARE_ACCESS_READ,
cookie->fSeq++; cookie->fClientId, OPEN4_NOCREATE, fName);
result = request.Send(); status_t result = request.Send();
if (result != B_OK) if (result != B_OK)
return result; return result;
@@ -359,8 +333,8 @@ Inode::Open(int mode, OpenFileCookie* cookie)
if (confirm) { if (confirm) {
request.Reset(); request.Reset();
req.PutFH(fHandle); req.PutFH(fHandle);
req.OpenConfirm(cookie->fSeq, cookie->fStateId, cookie->fStateSeq); req.OpenConfirm(fFilesystem->NFSServer()->SequenceId(),
cookie->fSeq++; cookie->fStateId, cookie->fStateSeq);
result = request.Send(); result = request.Send();
if (result != B_OK) if (result != B_OK)
@@ -386,7 +360,8 @@ Inode::Close(OpenFileCookie* cookie)
RequestBuilder& req = request.Builder(); RequestBuilder& req = request.Builder();
req.PutFH(fHandle); req.PutFH(fHandle);
req.Close(cookie->fSeq, cookie->fStateId, cookie->fStateSeq); req.Close(fFilesystem->NFSServer()->SequenceId(), cookie->fStateId,
cookie->fStateSeq);
status_t result = request.Send(); status_t result = request.Send();
if (result != B_OK) if (result != B_OK)
@@ -402,6 +377,8 @@ Inode::Close(OpenFileCookie* cookie)
if (result != B_OK) if (result != B_OK)
return result; return result;
fFilesystem->NFSServer()->ReleaseCID(cookie->fClientId);
return B_OK; return B_OK;
} }
+1 -1
View File
@@ -19,9 +19,9 @@
struct OpenFileCookie { struct OpenFileCookie {
uint64 fClientId;
uint32 fStateId[3]; uint32 fStateId[3];
uint32 fStateSeq; uint32 fStateSeq;
uint32 fSeq;
}; };
class Inode { class Inode {
@@ -7,6 +7,7 @@ KernelAddon nfs4 :
Filesystem.cpp Filesystem.cpp
Inode.cpp Inode.cpp
kernel_interface.cpp kernel_interface.cpp
NFS4Server.cpp
ReplyInterpreter.cpp ReplyInterpreter.cpp
Request.cpp Request.cpp
RequestBuilder.cpp RequestBuilder.cpp
@@ -0,0 +1,74 @@
/*
* Copyright 2012 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Paweł Dziepak, [email protected]
*/
#include "NFS4Server.h"
#include "Request.h"
NFS4Server::NFS4Server(RPC::Server* serv)
:
fCIDUseCount(0),
fSequenceId(0),
fServer(serv)
{
mutex_init(&fLock, NULL);
}
NFS4Server::~NFS4Server()
{
mutex_destroy(&fLock);
}
uint64
NFS4Server::ClientId(uint64 prevId, bool forceNew)
{
mutex_lock(&fLock);
if ((forceNew && fClientId == prevId) || fCIDUseCount == 0) {
Request request(fServer);
request.Builder().SetClientID(fServer);
status_t result = request.Send();
if (result != B_OK)
goto out_unlock;
uint64 ver;
result = request.Reply().SetClientID(&fClientId, &ver);
if (result != B_OK)
goto out_unlock;
request.Reset();
request.Builder().SetClientIDConfirm(fClientId, ver);
result = request.Send();
if (result != B_OK)
goto out_unlock;
result = request.Reply().SetClientIDConfirm();
if (result != B_OK)
goto out_unlock;
}
fCIDUseCount++;
out_unlock:
mutex_unlock(&fLock);
return fClientId;
}
void
NFS4Server::ReleaseCID(uint64 cid)
{
mutex_lock(&fLock);
fCIDUseCount--;
mutex_unlock(&fLock);
}
@@ -0,0 +1,44 @@
/*
* Copyright 2012 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Paweł Dziepak, [email protected]
*/
#ifndef NFS4SERVER_H
#define NFS4SERVER_H
#include <lock.h>
#include "RPCServer.h"
class NFS4Server : public RPC::ProgramData {
public:
NFS4Server(RPC::Server* serv);
virtual ~NFS4Server();
uint64 ClientId(uint64 prevId = 0, bool forceNew = false);
void ReleaseCID(uint64 cid);
inline uint32 SequenceId();
private:
uint64 fClientId;
uint32 fCIDUseCount;
mutex fLock;
vint32 fSequenceId;
RPC::Server* fServer;
};
uint32
NFS4Server::SequenceId()
{
return static_cast<uint32>(atomic_add(&fSequenceId, 1));
}
#endif // NFS4SERVER_H
@@ -77,6 +77,7 @@ Server::Server(Connection* conn, ServerAddress* addr)
: :
fConnection(conn), fConnection(conn),
fAddress(addr), fAddress(addr),
fPrivateData(NULL),
fXID(rand() << 1) fXID(rand() << 1)
{ {
_StartListening(); _StartListening();
@@ -85,6 +86,8 @@ Server::Server(Connection* conn, ServerAddress* addr)
Server::~Server() Server::~Server()
{ {
delete fPrivateData;
fThreadCancel = true; fThreadCancel = true;
fConnection->Disconnect(); fConnection->Disconnect();
interrupt_thread(fThread); interrupt_thread(fThread);
@@ -200,7 +203,7 @@ Server::Repair()
uint32 uint32
Server::_GetXID() Server::_GetXID()
{ {
return (uint32)atomic_add(&fXID, 1); return static_cast<uint32>(atomic_add(&fXID, 1));
} }
@@ -262,7 +265,8 @@ ServerManager::~ServerManager()
status_t status_t
ServerManager::Acquire(Server** pserv, uint32 ip, uint16 port, Transport proto) ServerManager::Acquire(Server** pserv, uint32 ip, uint16 port, Transport proto,
ProgramData* (*createPriv)(Server*))
{ {
status_t result; status_t result;
@@ -301,6 +305,7 @@ ServerManager::Acquire(Server** pserv, uint32 ip, uint16 port, Transport proto)
delete conn; delete conn;
return B_NO_MEMORY; return B_NO_MEMORY;
} }
node->fServer->SetPrivateData(createPriv(node->fServer));
node->fRefCount = 1; node->fRefCount = 1;
node->fLeft = node->fRight = NULL; node->fLeft = node->fRight = NULL;
@@ -43,6 +43,11 @@ private:
}; };
class ProgramData {
public:
virtual ~ProgramData() { }
};
class Server { class Server {
public: public:
Server(Connection* conn, Server(Connection* conn,
@@ -63,6 +68,9 @@ public:
inline const ServerAddress& ID() const; inline const ServerAddress& ID() const;
inline ServerAddress LocalID() const; inline ServerAddress LocalID() const;
inline ProgramData* PrivateData();
inline void SetPrivateData(ProgramData* priv);
private: private:
inline uint32 _GetXID(); inline uint32 _GetXID();
@@ -79,6 +87,8 @@ private:
Connection* fConnection; Connection* fConnection;
const ServerAddress* fAddress; const ServerAddress* fAddress;
ProgramData* fPrivateData;
vint32 fXID; vint32 fXID;
static const bigtime_t kWaitTime = 1000000; static const bigtime_t kWaitTime = 1000000;
}; };
@@ -118,6 +128,21 @@ Server::LocalID() const
} }
inline ProgramData*
Server::PrivateData()
{
return fPrivateData;
}
inline void
Server::SetPrivateData(ProgramData* priv)
{
delete fPrivateData;
fPrivateData = priv;
}
struct ServerNode { struct ServerNode {
ServerAddress fID; ServerAddress fID;
Server* fServer; Server* fServer;
@@ -133,7 +158,8 @@ public:
~ServerManager(); ~ServerManager();
status_t Acquire(Server** pserv, uint32 ip, uint16 port, status_t Acquire(Server** pserv, uint32 ip, uint16 port,
Transport proto); Transport proto,
ProgramData* (*createPriv)(Server*));
void Release(Server* serv); void Release(Server* serv);
private: private:
@@ -28,6 +28,13 @@ dprintf(const char* format, ...);
RPC::ServerManager* gRPCServerManager; RPC::ServerManager* gRPCServerManager;
static RPC::ProgramData*
sCreateNFS4Server(RPC::Server* serv)
{
return new NFS4Server(serv);
}
static status_t static status_t
nfs4_mount(fs_volume* volume, const char* device, uint32 flags, nfs4_mount(fs_volume* volume, const char* device, uint32 flags,
const char* args, ino_t* _rootVnodeID) const char* args, ino_t* _rootVnodeID)
@@ -36,7 +43,8 @@ nfs4_mount(fs_volume* volume, const char* device, uint32 flags,
RPC::Server *server; RPC::Server *server;
// hardcoded ip 192.168.1.70 // hardcoded ip 192.168.1.70
result = gRPCServerManager->Acquire(&server, 0xc0a80146, 2049, ProtocolUDP); result = gRPCServerManager->Acquire(&server, 0xc0a80146, 2049, ProtocolUDP,
sCreateNFS4Server);
if (result != B_OK) if (result != B_OK)
return result; return result;