diff --git a/src/add-ons/kernel/file_systems/nfs4/Filesystem.cpp b/src/add-ons/kernel/file_systems/nfs4/Filesystem.cpp index 402e67bbe0..282a33d3e8 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Filesystem.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Filesystem.cpp @@ -14,8 +14,12 @@ #include "ReplyInterpreter.h" #include "RequestBuilder.h" +#include "Inode.h" + Filesystem::Filesystem() + : + fId(0) { } @@ -32,7 +36,7 @@ Filesystem::Mount(Filesystem** pfs, RPC::Server* serv, const char* fsPath) req.PutRootFH(); // Better way of doing this will be needed - uint32 lookupCount; + uint32 lookupCount = 0; char* path = strdup(fsPath); char* pathStart = path; char* pathEnd; @@ -104,7 +108,7 @@ Filesystem::Mount(Filesystem** pfs, RPC::Server* serv, const char* fsPath) return B_UNSUPPORTED; } - Filesystem* fs = new Filesystem; + Filesystem* fs = new(std::nothrow) Filesystem; fs->fFHExpiryType = values[0].fData.fValue32; memcpy(&fs->fRootFH, &fh, sizeof(Filehandle)); fs->fServer = serv; @@ -116,3 +120,10 @@ Filesystem::Mount(Filesystem** pfs, RPC::Server* serv, const char* fsPath) return B_OK; } + +Inode* +Filesystem::CreateRootInode() +{ + return new(std::nothrow)Inode(this, fRootFH); +} + diff --git a/src/add-ons/kernel/file_systems/nfs4/Filesystem.h b/src/add-ons/kernel/file_systems/nfs4/Filesystem.h index 7489f2e702..ca370c28de 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Filesystem.h +++ b/src/add-ons/kernel/file_systems/nfs4/Filesystem.h @@ -13,13 +13,19 @@ #include "RPCServer.h" +class Inode; + class Filesystem { public: static status_t Mount(Filesystem** pfs, RPC::Server* serv, const char* path); ~Filesystem(); + Inode* CreateRootInode(); + inline uint32 FHExpiryType() const; + inline RPC::Server* Server(); + inline uint64 GetId(); private: Filesystem(); @@ -29,8 +35,24 @@ private: Filehandle fRootFH; RPC::Server* fServer; + + vint64 fId; }; +inline RPC::Server* +Filesystem::Server() +{ + return fServer; +} + + +inline uint64 +Filesystem::GetId() +{ + return atomic_add64(&fId, 1); +} + + #endif // FILESYSTEM_H diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp new file mode 100644 index 0000000000..f2af559ca4 --- /dev/null +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp @@ -0,0 +1,55 @@ +/* + * Copyright 2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Paweł Dziepak, pdziepak@quarnos.org + */ + + +#include "Inode.h" + +#include + +#include "ReplyInterpreter.h" +#include "RequestBuilder.h" + + +// Creating Inode object from Filehandle probably is not a good idea when +// filehandles are volatile. +Inode::Inode(Filesystem* fs, const Filehandle &fh) + : + fFilesystem(fs) +{ + memcpy(&fHandle, &fh, sizeof(fh)); + + RequestBuilder req(ProcCompound); + req.PutFH(fh); + + Attribute attr[] = { FATTR4_FILEID }; + req.GetAttr(attr, sizeof(attr) / sizeof(Attribute)); + + RPC::Reply *rpl; + fs->Server()->SendCall(req.Request(), &rpl); + ReplyInterpreter reply(rpl); + + status_t result; + result = reply.PutFH(); + if (result != B_OK) + return; + + AttrValue* values; + uint32 count; + result = reply.GetAttr(&values, &count); + if (result != B_OK) + return; + + if (count < 1 || values[0].fAttribute != FATTR4_FILEID) { + // Server does not provide fileid. We need to make something up. + fFileId = fs->GetId(); + } else + fFileId = values[0].fData.fValue64; + + delete values; +} + diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.h b/src/add-ons/kernel/file_systems/nfs4/Inode.h new file mode 100644 index 0000000000..39d9ea4514 --- /dev/null +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.h @@ -0,0 +1,44 @@ +/* + * Copyright 2012 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Paweł Dziepak, pdziepak@quarnos.org + */ +#ifndef INODE_H +#define INODE_H + + +#include + +#include "Filesystem.h" +#include "NFS4Defs.h" + + +class Inode { +public: + Inode(Filesystem* fs, const Filehandle &fh); + + inline ino_t ID() const; + +private: + uint64 fFileId; + + Filehandle fHandle; + Filesystem* fFilesystem; +}; + + +inline ino_t +Inode::ID() const +{ + if (sizeof(ino_t) >= sizeof(uint64)) + return fFileId; + else + return (ino_t)fFileId ^ (fFileId >> + (sizeof(uint64) - sizeof(ino_t)) * 8); +} + + +#endif // INODE_H + diff --git a/src/add-ons/kernel/file_systems/nfs4/Jamfile b/src/add-ons/kernel/file_systems/nfs4/Jamfile index bab7e6c8b8..81f3f46b8a 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Jamfile +++ b/src/add-ons/kernel/file_systems/nfs4/Jamfile @@ -5,6 +5,7 @@ UsePrivateHeaders kernel ; KernelAddon nfs4 : Connection.cpp Filesystem.cpp + Inode.cpp kernel_interface.cpp ReplyInterpreter.cpp RequestBuilder.cpp diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Defs.h b/src/add-ons/kernel/file_systems/nfs4/NFS4Defs.h index b1a4ec7e0f..5938eff370 100644 --- a/src/add-ons/kernel/file_systems/nfs4/NFS4Defs.h +++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Defs.h @@ -29,6 +29,7 @@ enum Opcode { OpGetAttr = 9, OpGetFH = 10, OpLookUp = 15, + OpPutFH = 22, OpPutRootFH = 24 }; diff --git a/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.h b/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.h index 83973b17dd..4361095bc7 100644 --- a/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.h +++ b/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.h @@ -33,6 +33,7 @@ public: status_t GetAttr(AttrValue** attrs, uint32* count); status_t GetFH(Filehandle* fh); inline status_t LookUp(); + inline status_t PutFH(); inline status_t PutRootFH(); private: @@ -51,6 +52,13 @@ ReplyInterpreter::LookUp() } +inline status_t +ReplyInterpreter::PutFH() +{ + return _OperationError(OpPutFH); +} + + inline status_t ReplyInterpreter::PutRootFH() { diff --git a/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.cpp b/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.cpp index 341d54385a..2ed5b59df5 100644 --- a/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.cpp @@ -114,6 +114,22 @@ RequestBuilder::LookUp(const char* name) } +status_t +RequestBuilder::PutFH(const Filehandle& fh) +{ + if (fProcedure != ProcCompound) + return B_BAD_VALUE; + if (fRequest == NULL) + return B_NO_MEMORY; + + fRequest->Stream().AddUInt(OpPutFH); + fRequest->Stream().AddOpaque(fh.fFH, fh.fSize); + fOpCount++; + + return B_OK; +} + + status_t RequestBuilder::PutRootFH() { diff --git a/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.h b/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.h index 377519f15c..7f8b3b3ba1 100644 --- a/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.h +++ b/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.h @@ -25,6 +25,7 @@ public: status_t GetAttr(Attribute* attrs, uint32 count); status_t GetFH(); status_t LookUp(const char* name); + status_t PutFH(const Filehandle& fh); status_t PutRootFH(); RPC::Call* Request();