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:
@@ -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()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user