added 2 changesets to branch 'refs/remotes/pdziepak-github/nfs4' old head: 870528b79923b065c9d04bc598b43a518f3cfafa new head: e8c12d9410d16c9a504198755b85c385e7ab667a ---------------------------------------------------------------------------- 060a463: nfs4: Make the client more configurable e8c12d9: nfs4: Fix file handle recovery [ Pawel Dziepak <pdziepak@xxxxxxxxxxx> ] ---------------------------------------------------------------------------- 25 files changed, 361 insertions(+), 168 deletions(-) .../kernel/file_systems/nfs4/CacheRevalidator.cpp | 1 + .../kernel/file_systems/nfs4/CacheRevalidator.h | 5 +- .../kernel/file_systems/nfs4/Connection.cpp | 10 ++ src/add-ons/kernel/file_systems/nfs4/Connection.h | 2 + .../kernel/file_systems/nfs4/Delegation.cpp | 2 +- .../kernel/file_systems/nfs4/DirectoryCache.cpp | 48 ++++++--- .../kernel/file_systems/nfs4/DirectoryCache.h | 2 + src/add-ons/kernel/file_systems/nfs4/FileInfo.cpp | 4 +- .../kernel/file_systems/nfs4/FileSystem.cpp | 60 ++++++----- src/add-ons/kernel/file_systems/nfs4/FileSystem.h | 24 ++++- src/add-ons/kernel/file_systems/nfs4/Inode.cpp | 54 ++++++---- src/add-ons/kernel/file_systems/nfs4/Inode.h | 11 +- src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp | 57 +++++----- src/add-ons/kernel/file_systems/nfs4/InodeIdMap.h | 7 +- .../kernel/file_systems/nfs4/MetadataCache.cpp | 8 +- src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp | 42 ++++---- .../kernel/file_systems/nfs4/NFS4Object.cpp | 3 +- src/add-ons/kernel/file_systems/nfs4/NFS4Object.h | 10 ++ .../kernel/file_systems/nfs4/NFS4Server.cpp | 6 +- src/add-ons/kernel/file_systems/nfs4/OpenState.cpp | 8 +- src/add-ons/kernel/file_systems/nfs4/Request.cpp | 24 ++++- src/add-ons/kernel/file_systems/nfs4/Request.h | 12 ++- src/add-ons/kernel/file_systems/nfs4/RootInode.cpp | 30 ++++-- src/add-ons/kernel/file_systems/nfs4/RootInode.h | 13 +++ .../kernel/file_systems/nfs4/kernel_interface.cpp | 86 ++++++++++++---- ############################################################################ Commit: 060a4636e4a286dd70b9cbf335d12ddc10924937 Author: Pawel Dziepak <pdziepak@xxxxxxxxxxx> Date: Thu Aug 16 17:59:50 2012 UTC nfs4: Make the client more configurable ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/file_systems/nfs4/CacheRevalidator.cpp b/src/add-ons/kernel/file_systems/nfs4/CacheRevalidator.cpp index 749d6f8..d1abbbf 100644 --- a/src/add-ons/kernel/file_systems/nfs4/CacheRevalidator.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/CacheRevalidator.cpp @@ -105,6 +105,7 @@ CacheRevalidator::_DirectoryCacheRevalidator() } fDirectoryCaches.RemoveHead(); + current->fRevalidated = false; if (current->Revalidate() == B_OK) AddDirectory(current); diff --git a/src/add-ons/kernel/file_systems/nfs4/CacheRevalidator.h b/src/add-ons/kernel/file_systems/nfs4/CacheRevalidator.h index b3bfed9..7e1e4a7 100644 --- a/src/add-ons/kernel/file_systems/nfs4/CacheRevalidator.h +++ b/src/add-ons/kernel/file_systems/nfs4/CacheRevalidator.h @@ -58,6 +58,7 @@ CacheRevalidator::Unlock() inline void CacheRevalidator::AddDirectory(DirectoryCache* cache) { + cache->fRevalidated = true; fDirectoryCaches.InsertAfter(fDirectoryCaches.Tail(), cache); } @@ -65,7 +66,9 @@ CacheRevalidator::AddDirectory(DirectoryCache* cache) inline void CacheRevalidator::RemoveDirectory(DirectoryCache* cache) { - fDirectoryCaches.Remove(cache); + if (cache->fRevalidated == true) + fDirectoryCaches.Remove(cache); + cache->fRevalidated = false; } diff --git a/src/add-ons/kernel/file_systems/nfs4/Connection.cpp b/src/add-ons/kernel/file_systems/nfs4/Connection.cpp index 22f08f2..d94801b 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Connection.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Connection.cpp @@ -77,6 +77,16 @@ PeerAddress::ProtocolString() const } +void +PeerAddress::SetProtocol(const char* protocol) +{ + if (strcmp(protocol, "tcp") == 0) + fProtocol = IPPROTO_TCP; + else if (strcmp(protocol, "udp") == 0) + fProtocol = IPPROTO_UDP; +} + + char* PeerAddress::UniversalAddress() const { diff --git a/src/add-ons/kernel/file_systems/nfs4/Connection.h b/src/add-ons/kernel/file_systems/nfs4/Connection.h index b10cc9c..aceb2c0 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Connection.h +++ b/src/add-ons/kernel/file_systems/nfs4/Connection.h @@ -27,6 +27,8 @@ struct PeerAddress { PeerAddress(); const char* ProtocolString() const; + void SetProtocol(const char* protocol); + char* UniversalAddress() const; socklen_t AddressSize() const; diff --git a/src/add-ons/kernel/file_systems/nfs4/Delegation.cpp b/src/add-ons/kernel/file_systems/nfs4/Delegation.cpp index a0ce499..bf2b33a 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Delegation.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Delegation.cpp @@ -41,7 +41,7 @@ Delegation::ReturnDelegation() { do { RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + Request request(serv, fFileSystem); RequestBuilder& req = request.Builder(); req.PutFH(fInfo.fHandle); diff --git a/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp b/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp index b9483a0..52be9fd 100644 --- a/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp @@ -49,6 +49,7 @@ DirectoryCacheSnapshot::~DirectoryCacheSnapshot() DirectoryCache::DirectoryCache(Inode* inode, bool attr) : + fRevalidated(false), fDirectoryCache(NULL), fInode(inode), fAttrDir(attr), @@ -60,6 +61,10 @@ DirectoryCache::DirectoryCache(Inode* inode, bool attr) DirectoryCache::~DirectoryCache() { + fInode->GetFileSystem()->Revalidator().Lock(); + fInode->GetFileSystem()->Revalidator().RemoveDirectory(this); + fInode->GetFileSystem()->Revalidator().Unlock(); + mutex_destroy(&fLock); } @@ -179,7 +184,12 @@ status_t DirectoryCache::Revalidate() { uint64 change; - if (fInode->GetChangeInfo(&change, true) == B_OK && change == fChange) { + if (fInode->GetChangeInfo(&change, true) != B_OK) { + Trash(); + return B_ERROR; + } + + if (change == fChange) { fExpireTime = system_time() + kExpirationTime; return B_OK; } diff --git a/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.h b/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.h index ac152f0..4099950 100644 --- a/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.h +++ b/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.h @@ -65,6 +65,8 @@ public: inline time_t ExpireTime(); static const bigtime_t kExpirationTime = 15000000; + + bool fRevalidated; protected: void NotifyChanges(DirectoryCacheSnapshot* oldSnapshot, DirectoryCacheSnapshot* newSnapshot); diff --git a/src/add-ons/kernel/file_systems/nfs4/FileInfo.cpp b/src/add-ons/kernel/file_systems/nfs4/FileInfo.cpp index 402c642..e81242e 100644 --- a/src/add-ons/kernel/file_systems/nfs4/FileInfo.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/FileInfo.cpp @@ -49,7 +49,7 @@ FileInfo::ParsePath(RequestBuilder& req, uint32& count, const char* _path) status_t FileInfo::UpdateFileHandles(FileSystem* fs) { - Request request(fs->Server()); + Request request(fs->Server(), fs); RequestBuilder& req = request.Builder(); req.PutRootFH(); diff --git a/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp b/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp index 46bd002..4c8963a 100644 --- a/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp @@ -11,6 +11,7 @@ #include <string.h> +#include <AutoDeleter.h> #include <lock.h> #include "Request.h" @@ -21,7 +22,7 @@ extern RPC::ServerManager* gRPCServerManager; extern RPC::ProgramData* CreateNFS4Server(RPC::Server* serv); -FileSystem::FileSystem() +FileSystem::FileSystem(const MountConfiguration& configuration) : fNext(NULL), fPrev(NULL), @@ -30,7 +31,8 @@ FileSystem::FileSystem() fNamedAttrs(true), fPath(NULL), fRoot(NULL), - fId(1) + fId(1), + fConfiguration(configuration) { fOpenOwner = rand(); fOpenOwner <<= 32; @@ -73,9 +75,14 @@ sGetPath(const char* root, const char* path) status_t FileSystem::Mount(FileSystem** pfs, RPC::Server* serv, const char* fsPath, - dev_t id) + dev_t id, const MountConfiguration& configuration) { - Request request(serv); + FileSystem* fs = new(std::nothrow) FileSystem(configuration); + if (fs == NULL) + return B_NO_MEMORY; + ObjectDeleter<FileSystem> fsDeleter(fs); + + Request request(serv, fs); RequestBuilder& req = request.Builder(); req.PutRootFH(); @@ -120,10 +127,6 @@ FileSystem::Mount(FileSystem** pfs, RPC::Server* serv, const char* fsPath, if (result != B_OK || count < 2) return result; - FileSystem* fs = new(std::nothrow) FileSystem; - if (fs == NULL) - return B_NO_MEMORY; - // FATTR4_SUPPORTED_ATTRS is mandatory memcpy(fs->fSupAttrs, &values[0].fData.fValue64, sizeof(fs->fSupAttrs)); @@ -163,23 +166,20 @@ FileSystem::Mount(FileSystem** pfs, RPC::Server* serv, const char* fsPath, delete[] values; - if (fi.fName == NULL || fi.fPath == NULL) { - delete fs; + if (fi.fName == NULL || fi.fPath == NULL) return B_NO_MEMORY; - } Inode* inode; result = Inode::CreateInode(fs, fi, &inode); - if (result != B_OK) { - delete fs; + if (result != B_OK) return result; - } fs->fRoot = reinterpret_cast<RootInode*>(inode); fs->NFSServer()->AddFileSystem(fs); *pfs = fs; + fsDeleter.Detach(); return B_OK; } diff --git a/src/add-ons/kernel/file_systems/nfs4/FileSystem.h b/src/add-ons/kernel/file_systems/nfs4/FileSystem.h index 3a2dfac..e7884fe 100644 --- a/src/add-ons/kernel/file_systems/nfs4/FileSystem.h +++ b/src/add-ons/kernel/file_systems/nfs4/FileSystem.h @@ -19,10 +19,19 @@ class Inode; class RootInode; +struct MountConfiguration { + bool fHard; + int fRetryLimit; + + bool fEmulateNamedAttrs; + bool fCacheMetadata; +}; + class FileSystem { public: static status_t Mount(FileSystem** pfs, RPC::Server* serv, - const char* path, dev_t id); + const char* path, dev_t id, + const MountConfiguration& configuration); ~FileSystem(); status_t GetInode(ino_t id, Inode** inode); @@ -65,10 +74,12 @@ public: inline bool NamedAttrs(); inline void SetNamedAttrs(bool attrs); + inline const MountConfiguration& GetConfiguration(); + FileSystem* fNext; FileSystem* fPrev; private: - FileSystem(); + FileSystem(const MountConfiguration& config); CacheRevalidator fCacheRevalidator; @@ -99,6 +110,8 @@ private: dev_t fDevId; InodeIdMap fInoIdMap; + + MountConfiguration fConfiguration; }; @@ -223,5 +236,12 @@ FileSystem::SetNamedAttrs(bool attrs) } +inline const MountConfiguration& +FileSystem::GetConfiguration() +{ + return fConfiguration; +} + + #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 index 02ea63e..c8cfd2c 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp @@ -55,7 +55,7 @@ Inode::CreateInode(FileSystem* fs, const FileInfo &fi, Inode** _inode) uint64 size; do { RPC::Server* serv = fs->Server(); - Request request(serv); + Request request(serv, fs); RequestBuilder& req = request.Builder(); req.PutFH(inode->fInfo.fHandle); diff --git a/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp b/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp index 33e7822..65f735a 100644 --- a/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp @@ -67,32 +67,43 @@ Inode::LoadAttrDirHandle() FileHandle handle; status_t result; - if (!fFileSystem->NamedAttrs()) { - char* attrDir - = reinterpret_cast<char*>(malloc(strlen(fInfo.fName) + 32)); - if (attrDir == NULL) - return B_NO_MEMORY; - strcpy(attrDir, "."); - strcat(attrDir, fInfo.fName); - strcat(attrDir, "-haiku-attrs"); - - result = NFS4Inode::LookUp(attrDir, NULL, NULL, &handle, true); - if (result == B_ENTRY_NOT_FOUND) { - ChangeInfo change; - struct stat st; - Stat(&st); - st.st_mode |= S_IXUSR | S_IXGRP | S_IXOTH; - result = NFS4Inode::CreateObject(attrDir, NULL, st.st_mode, NF4DIR, - &change, NULL, &handle, true); - } - free(attrDir); - } else { + if (fFileSystem->NamedAttrs()) { result = NFS4Inode::OpenAttrDir(&handle); - if (result == B_UNSUPPORTED) - fFileSystem->SetNamedAttrs(false); + if (result == B_OK) { + fInfo.fAttrDir = handle; + return B_OK; + } + + if (result != B_UNSUPPORTED) + return result; + + fFileSystem->SetNamedAttrs(false); } + if (!fFileSystem->GetConfiguration().fEmulateNamedAttrs) + return B_UNSUPPORTED; + + char* attrDir + = reinterpret_cast<char*>(malloc(strlen(fInfo.fName) + 32)); + if (attrDir == NULL) + return B_NO_MEMORY; + strcpy(attrDir, "."); + strcat(attrDir, fInfo.fName); + strcat(attrDir, "-haiku-attrs"); + + result = NFS4Inode::LookUp(attrDir, NULL, NULL, &handle, true); + if (result == B_ENTRY_NOT_FOUND) { + ChangeInfo change; + struct stat st; + Stat(&st); + st.st_mode |= S_IXUSR | S_IXGRP | S_IXOTH; + result = NFS4Inode::CreateObject(attrDir, NULL, st.st_mode, NF4DIR, + &change, NULL, &handle, true); + } + + free(attrDir); + if (result != B_OK) return result; @@ -128,7 +139,7 @@ Inode::ReadDirUp(struct dirent* de, uint32 pos, uint32 size) { do { RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + Request request(serv, fFileSystem); RequestBuilder& req = request.Builder(); req.PutFH(fInfo.fHandle); diff --git a/src/add-ons/kernel/file_systems/nfs4/MetadataCache.cpp b/src/add-ons/kernel/file_systems/nfs4/MetadataCache.cpp index 3c0f9b6..bc345a9 100644 --- a/src/add-ons/kernel/file_systems/nfs4/MetadataCache.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/MetadataCache.cpp @@ -35,7 +35,8 @@ status_t MetadataCache::GetStat(struct stat* st) { MutexLocker _(fLock); - if (fForceValid || fExpire > time(NULL)) { + bool cache = fInode->GetFileSystem()->GetConfiguration().fCacheMetadata; + if (fForceValid || (cache && fExpire > time(NULL))) { // Do not touch other members of struct stat st->st_size = fStatCache.st_size; st->st_mode = fStatCache.st_mode; @@ -110,7 +111,10 @@ MetadataCache::SetAccess(uid_t uid, uint32 allowed) entry.fAllowed = allowed; entry.fExpire = time(NULL) + kExpirationTime; entry.fForceValid = fForceValid; - fAccessCache.Insert(uid, entry); + + bool cache = fInode->GetFileSystem()->GetConfiguration().fCacheMetadata; + if (fForceValid || cache) + fAccessCache.Insert(uid, entry); } diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp b/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp index 81e6280..43ae3fe 100644 --- a/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp @@ -18,7 +18,7 @@ NFS4Inode::GetChangeInfo(uint64* change, bool attrDir) { do { RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + Request request(serv, fFileSystem); RequestBuilder& req = request.Builder(); if (attrDir) @@ -60,7 +60,7 @@ NFS4Inode::CommitWrites() { do { RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + Request request(serv, fFileSystem); RequestBuilder& req = request.Builder(); req.PutFH(fInfo.fHandle); @@ -86,7 +86,7 @@ NFS4Inode::Access(uint32* allowed) { do { RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + Request request(serv, fFileSystem); RequestBuilder& req = request.Builder(); req.PutFH(fInfo.fHandle); @@ -114,7 +114,7 @@ NFS4Inode::LookUp(const char* name, uint64* change, uint64* fileID, { do { RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + Request request(serv, fFileSystem); RequestBuilder& req = request.Builder(); if (parent) @@ -199,7 +199,7 @@ NFS4Inode::Link(Inode* dir, const char* name, ChangeInfo* changeInfo) { do { RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + Request request(serv, fFileSystem); RequestBuilder& req = request.Builder(); req.PutFH(fInfo.fHandle); @@ -231,7 +231,7 @@ NFS4Inode::ReadLink(void* buffer, size_t* length) { do { RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + Request request(serv, fFileSystem); RequestBuilder& req = request.Builder(); req.PutFH(fInfo.fHandle); @@ -262,7 +262,7 @@ NFS4Inode::GetStat(AttrValue** values, uint32* count, OpenAttrCookie* cookie) { do { RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + Request request(serv, fFileSystem); RequestBuilder& req = request.Builder(); if (cookie != NULL) @@ -297,7 +297,7 @@ NFS4Inode::WriteStat(OpenState* state, AttrValue* attrs, uint32 attrCount) { do { RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + Request request(serv, fFileSystem); RequestBuilder& req = request.Builder(); if (state != NULL) { @@ -335,7 +335,7 @@ NFS4Inode::Rename(Inode* from, Inode* to, const char* fromName, { do { RPC::Server* serv = from->fFileSystem->Server(); - Request request(serv); + Request request(serv, from->fFileSystem); RequestBuilder& req = request.Builder(); if (attribute) @@ -421,7 +421,7 @@ NFS4Inode::CreateFile(const char* name, int mode, int perms, OpenState* state, state->fClientID = fFileSystem->NFSServer()->ClientId(); RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + Request request(serv, fFileSystem); RequestBuilder& req = request.Builder(); req.PutFH(fInfo.fHandle); @@ -512,7 +512,7 @@ NFS4Inode::OpenFile(OpenState* state, int mode, OpenDelegationData* delegation) state->fClientID = fFileSystem->NFSServer()->ClientId(); RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + Request request(serv, fFileSystem); RequestBuilder& req = request.Builder(); // Since we are opening the file using a pair (parentFH, name) we @@ -613,7 +613,7 @@ NFS4Inode::OpenAttr(OpenState* state, const char* name, int mode, state->fClientID = fFileSystem->NFSServer()->ClientId(); RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + Request request(serv, fFileSystem); RequestBuilder& req = request.Builder(); req.PutFH(fInfo.fAttrDir); @@ -665,7 +665,7 @@ NFS4Inode::ReadFile(OpenStateCookie* cookie, OpenState* state, uint64 position, { do { RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + Request request(serv, fFileSystem); RequestBuilder& req = request.Builder(); req.PutFH(state->fInfo.fHandle); @@ -697,7 +697,7 @@ NFS4Inode::WriteFile(OpenStateCookie* cookie, OpenState* state, uint64 position, do { RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + Request request(serv, fFileSystem); RequestBuilder& req = request.Builder(); req.PutFH(state->fInfo.fHandle); @@ -732,7 +732,7 @@ NFS4Inode::CreateObject(const char* name, const char* path, int mode, { do { RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + Request request(serv, fFileSystem); RequestBuilder& req = request.Builder(); if (parent) @@ -810,7 +810,7 @@ NFS4Inode::RemoveObject(const char* name, FileType type, ChangeInfo* changeInfo, { do { RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + Request request(serv, fFileSystem); RequestBuilder& req = request.Builder(); req.PutFH(fInfo.fHandle); @@ -888,7 +888,7 @@ NFS4Inode::ReadDirOnce(DirEntry** dirents, uint32* count, OpenDirCookie* cookie, { do { RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + Request request(serv, fFileSystem); RequestBuilder& req = request.Builder(); if (attribute) @@ -958,7 +958,7 @@ NFS4Inode::OpenAttrDir(FileHandle* handle) { do { RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + Request request(serv, fFileSystem); RequestBuilder& req = request.Builder(); req.PutFH(fInfo.fHandle); @@ -990,7 +990,7 @@ NFS4Inode::TestLock(OpenFileCookie* cookie, LockType* type, uint64* position, { do { RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + Request request(serv, fFileSystem); RequestBuilder& req = request.Builder(); req.PutFH(fInfo.fHandle); @@ -1027,7 +1027,7 @@ NFS4Inode::AcquireLock(OpenFileCookie* cookie, LockInfo* lockInfo, bool wait) MutexLocker ownerLocker(lockInfo->fOwner->fLock); RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + Request request(serv, fFileSystem); RequestBuilder& req = request.Builder(); req.PutFH(fInfo.fHandle); @@ -1073,7 +1073,7 @@ NFS4Inode::ReleaseLock(OpenFileCookie* cookie, LockInfo* lockInfo) MutexLocker ownerLocker(lockInfo->fOwner->fLock); RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + Request request(serv, fFileSystem); RequestBuilder& req = request.Builder(); req.PutFH(fInfo.fHandle); diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Object.cpp b/src/add-ons/kernel/file_systems/nfs4/NFS4Object.cpp index 0e089ac..e24abce 100644 --- a/src/add-ons/kernel/file_systems/nfs4/NFS4Object.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Object.cpp @@ -111,6 +111,7 @@ NFS4Object::HandleErrors(uint32 nfs4Error, RPC::Server* serv, return false; // FileHandle has expired or is invalid + case NFS4ERR_NOFILEHANDLE: case NFS4ERR_BADHANDLE: case NFS4ERR_FHEXPIRED: if (fInfo.UpdateFileHandles(fFileSystem) == B_OK) @@ -143,7 +144,7 @@ NFS4Object::ConfirmOpen(const FileHandle& fh, OpenState* state, { do { RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + Request request(serv, fFileSystem); RequestBuilder& req = request.Builder(); diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Object.h b/src/add-ons/kernel/file_systems/nfs4/NFS4Object.h index 8cb927f..d0ac9cb 100644 --- a/src/add-ons/kernel/file_systems/nfs4/NFS4Object.h +++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Object.h @@ -27,10 +27,20 @@ public: static uint32 IncrementSequence(uint32 error); + inline NFS4Object(); + FileInfo fInfo; FileSystem* fFileSystem; }; +inline +NFS4Object::NFS4Object() + : + fFileSystem(NULL) +{ +} + + #endif // NFS4OBJECT_H diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Server.cpp b/src/add-ons/kernel/file_systems/nfs4/NFS4Server.cpp index 1b09e63..8a39021 100644 --- a/src/add-ons/kernel/file_systems/nfs4/NFS4Server.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Server.cpp @@ -112,7 +112,7 @@ NFS4Server::ClientId(uint64 prevId, bool forceNew) if ((fUseCount == 0 && fClientIdLastUse + (time_t)LeaseTime() < time(NULL)) || (forceNew && fClientId == prevId)) { - Request request(fServer); + Request request(fServer, NULL); request.Builder().SetClientID(fServer); status_t result = request.Send(); @@ -159,7 +159,7 @@ NFS4Server::FileSystemMigrated() status_t NFS4Server::_GetLeaseTime() { - Request request(fServer); + Request request(fServer, NULL); request.Builder().PutRootFH(); Attribute attr[] = { FATTR4_LEASE_TIME }; request.Builder().GetAttr(attr, sizeof(attr) / sizeof(Attribute)); @@ -246,7 +246,7 @@ NFS4Server::_Renewal() } } - Request request(fServer); + Request request(fServer, NULL); request.Builder().Renew(fClientId); request.Send(); diff --git a/src/add-ons/kernel/file_systems/nfs4/OpenState.cpp b/src/add-ons/kernel/file_systems/nfs4/OpenState.cpp index 7de9b42..1655c79 100644 --- a/src/add-ons/kernel/file_systems/nfs4/OpenState.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/OpenState.cpp @@ -114,7 +114,7 @@ OpenState::_ReleaseLockOwner(LockOwner* owner) { do { RPC::Server* server = fFileSystem->Server(); - Request request(server); + Request request(server, fFileSystem); RequestBuilder& req = request.Builder(); req.ReleaseLockOwner(this, owner); @@ -166,7 +166,7 @@ OpenState::_ReclaimOpen(uint64 newClientID) : OPEN_DELEGATE_NONE; do { RPC::Server* server = fFileSystem->Server(); - Request request(server); + Request request(server, fFileSystem); RequestBuilder& req = request.Builder(); req.PutFH(fInfo.fHandle); @@ -231,7 +231,7 @@ OpenState::_ReclaimLocks(uint64 newClientID) do { RPC::Server* server = fFileSystem->Server(); - Request request(server); + Request request(server, fFileSystem); RequestBuilder& req = request.Builder(); req.PutFH(fInfo.fHandle); @@ -272,7 +272,7 @@ OpenState::Close() uint32 sequence = fFileSystem->OpenOwnerSequenceLock(); do { RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + Request request(serv, fFileSystem); RequestBuilder& req = request.Builder(); req.PutFH(fInfo.fHandle); diff --git a/src/add-ons/kernel/file_systems/nfs4/Request.cpp b/src/add-ons/kernel/file_systems/nfs4/Request.cpp index 5262341..d68d5b2 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Request.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Request.cpp @@ -7,9 +7,11 @@ */ -#include "Inode.h" #include "Request.h" +#include "FileSystem.h" +#include "Inode.h" + status_t Request::Send(Cookie* cookie) @@ -36,10 +38,17 @@ Request::_SendUDP(Cookie* cookie) if (cookie != NULL) cookie->RegisterRequest(rpc); + int retryLimit = 0; + bool hard = true; + if (fFileSystem != NULL) { + retryLimit = fFileSystem->GetConfiguration().fRetryLimit; + hard = fFileSystem->GetConfiguration().fHard; + } + result = fServer->WaitCall(rpc); if (result != B_OK) { int attempts = 1; - while (result != B_OK && attempts++ < kRetryLimit) { + while (result != B_OK && (hard || attempts++ < retryLimit)) { result = fServer->ResendCallAsync(fBuilder.Request(), rpc); if (result != B_OK) { if (cookie != NULL) @@ -83,6 +92,15 @@ Request::_SendTCP(Cookie* cookie) status_t result; int attempts = 0; + + int retryLimit = 0; + bool hard = true; + + if (fFileSystem != NULL) { + retryLimit = fFileSystem->GetConfiguration().fRetryLimit; + hard = fFileSystem->GetConfiguration().fHard; + } + do { result = fServer->SendCallAsync(fBuilder.Request(), &rpl, &rpc); if (result == B_NO_MEMORY) @@ -105,7 +123,7 @@ Request::_SendTCP(Cookie* cookie) fServer->Repair(); } - } while (result != B_OK && attempts++ < kRetryLimit); + } while (result != B_OK && (hard || attempts++ < retryLimit)); if (cookie != NULL) cookie->UnregisterRequest(rpc); diff --git a/src/add-ons/kernel/file_systems/nfs4/Request.h b/src/add-ons/kernel/file_systems/nfs4/Request.h index cb8e5e0..2c0d014 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Request.h +++ b/src/add-ons/kernel/file_systems/nfs4/Request.h @@ -15,10 +15,12 @@ class Cookie; +class FileSystem; class Request { public: - inline Request(RPC::Server* serv); + inline Request(RPC::Server* server, + FileSystem* fileSystem); inline RequestBuilder& Builder(); inline ReplyInterpreter& Reply(); @@ -31,18 +33,18 @@ private: status_t _SendTCP(Cookie* cookie); RPC::Server* fServer; + FileSystem* fFileSystem; RequestBuilder fBuilder; ReplyInterpreter fReply; - - static const int kRetryLimit = 5; }; inline -Request::Request(RPC::Server* serv) +Request::Request(RPC::Server* server, FileSystem* fileSystem) : - fServer(serv) + fServer(server), + fFileSystem(fileSystem) { } diff --git a/src/add-ons/kernel/file_systems/nfs4/RootInode.cpp b/src/add-ons/kernel/file_systems/nfs4/RootInode.cpp index 1369d2f..0275f67 100644 --- a/src/add-ons/kernel/file_systems/nfs4/RootInode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/RootInode.cpp @@ -55,8 +55,8 @@ RootInode::_UpdateInfo(bool force) return B_OK; do { - RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + RPC::Server* server = fFileSystem->Server(); + Request request(server, fFileSystem); RequestBuilder& req = request.Builder(); req.PutFH(fInfo.fHandle); @@ -71,7 +71,7 @@ RootInode::_UpdateInfo(bool force) ReplyInterpreter& reply = request.Reply(); - if (HandleErrors(reply.NFS4Error(), serv)) + if (HandleErrors(reply.NFS4Error(), server)) continue; reply.PutFH(); @@ -137,8 +137,8 @@ bool RootInode::ProbeMigration() { do { - RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + RPC::Server* server = fFileSystem->Server(); + Request request(server, fFileSystem); RequestBuilder& req = request.Builder(); req.PutFH(fInfo.fHandle); @@ -153,7 +153,7 @@ RootInode::ProbeMigration() if (reply.NFS4Error() == NFS4ERR_MOVED) return true; - if (HandleErrors(reply.NFS4Error(), serv)) + if (HandleErrors(reply.NFS4Error(), server)) continue; return false; @@ -166,8 +166,8 @@ status_t RootInode::GetLocations(AttrValue** attrv) { do { - RPC::Server* serv = fFileSystem->Server(); - Request request(serv); + RPC::Server* server = fFileSystem->Server(); + Request request(server, fFileSystem); RequestBuilder& req = request.Builder(); req.PutFH(fInfo.fHandle); @@ -180,7 +180,7 @@ RootInode::GetLocations(AttrValue** attrv) ReplyInterpreter& reply = request.Reply(); - if (HandleErrors(reply.NFS4Error(), serv)) + if (HandleErrors(reply.NFS4Error(), server)) continue; reply.PutFH(); diff --git a/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp b/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp index f40cc40..a675138 100644 --- a/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp @@ -9,6 +9,7 @@ #include <stdio.h> +#include <AutoDeleter.h> #include <fs_cache.h> #include <fs_interface.h> @@ -28,9 +29,6 @@ extern fs_volume_ops gNFSv4VolumeOps; extern fs_vnode_ops gNFSv4VnodeOps; -extern "C" void -dprintf(const char* format, ...); - RPC::ServerManager* gRPCServerManager; @@ -42,30 +40,80 @@ CreateNFS4Server(RPC::Server* serv) } - -// TODO: IPv6 address will cause problems +// Format: ip{4,6}_address:path options +// Available options: +// hard - retry requests until success +// soft - retry requests no more than retrans times (default) +// retrans=X - retry requests X times (default: 5) +// ac - use metadata cache (default) +// noac - do not use metadata cache +// xattr-emu - emulate named attributes +// noxattr-emu - do not emulate named attributes (default) +// port=X - connect to port X (default: 2049) +// proto=X - user transport protocol X (default: tcp) static status_t -ParseArguments(const char* _args, PeerAddress* address, char* _path) +ParseArguments(const char* _args, PeerAddress* address, char** _path, + MountConfiguration* conf) { if (_args == NULL) return B_BAD_VALUE; char* args = strdup(_args); - char* path = strpbrk(args, ":"); - if (path == NULL) { - free(args); + if (args == NULL) + return B_NO_MEMORY; + MemoryDeleter argsDeleter(args); + + char* options = strchr(args, ' '); + if (options != NULL) + *options++ = '\0'; + + char* path = strrchr(args, ':'); + if (path == NULL) return B_MISMATCHED_VALUES; - } *path++ = '\0'; status_t result = PeerAddress::ResolveName(args, address); if (result != B_OK) return result; - _path[255] = '\0'; - strncpy(_path, path, 255); + *_path = strdup(path); + if (*_path == NULL) + return B_NO_MEMORY; + + conf->fHard = false; + conf->fRetryLimit = 5; + conf->fEmulateNamedAttrs = false; + conf->fCacheMetadata = true; + + char* optionsEnd; + if (options != NULL) + optionsEnd = strchr(options, ' '); + while (options != NULL && *options != '\0') { + if (optionsEnd != NULL) + *optionsEnd++ = '\0'; + + if (strcmp(options, "hard") == 0) + conf->fHard = true; + else if (strncmp(options, "retrans=", 8) == 0) { + options += strlen("retrans="); + conf->fRetryLimit = atoi(options); + } else if (strcmp(options, "noac") == 0) + conf->fCacheMetadata = false; + else if (strcmp(options, "xattr-emu") == 0) + conf->fEmulateNamedAttrs = true; + else if (strncmp(options, "port=", 5) == 0) { + options += strlen("port="); + address->SetPort(atoi(options)); + } else if (strncmp(options, "proto=", 6) == 0) { + options += strlen("proto="); + address->SetProtocol(options); + } + + options = optionsEnd; + if (options != NULL) + optionsEnd = strchr(options, ' '); + } - free(args); return B_OK; } @@ -83,10 +131,12 @@ nfs4_mount(fs_volume* volume, const char* device, uint32 flags, locker.Unlock(); PeerAddress address; - char path[256]; - result = ParseArguments(args, &address, path); + MountConfiguration config; + char *path; + result = ParseArguments(args, &address, &path, &config); if (result != B_OK) return result; + MemoryDeleter pathDeleter(path); RPC::Server *server; result = gRPCServerManager->Acquire(&server, address, CreateNFS4Server); @@ -94,7 +144,7 @@ nfs4_mount(fs_volume* volume, const char* device, uint32 flags, return result; FileSystem* fs; - result = FileSystem::Mount(&fs, server, path, volume->id); + result = FileSystem::Mount(&fs, server, path, volume->id, config); if (result != B_OK) { gRPCServerManager->Release(server); return result; @@ -824,8 +874,6 @@ nfs4_release_lock(fs_volume* volume, fs_vnode* vnode, void* _cookie, status_t nfs4_init() { - dprintf("NFS4 Init\n"); - gRPCServerManager = new(std::nothrow) RPC::ServerManager; if (gRPCServerManager == NULL) return B_NO_MEMORY; @@ -856,8 +904,6 @@ nfs4_init() status_t nfs4_uninit() { - dprintf("NFS4 Uninit\n"); - delete gRPCCallbackServer; delete gIdMapper; delete gWorkQueue; ############################################################################ Commit: e8c12d9410d16c9a504198755b85c385e7ab667a Author: Pawel Dziepak <pdziepak@xxxxxxxxxxx> Date: Thu Aug 16 19:11:56 2012 UTC nfs4: Fix file handle recovery ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp b/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp index 52be9fd..370a337 100644 --- a/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp @@ -184,7 +184,7 @@ status_t DirectoryCache::Revalidate() { uint64 change; - if (fInode->GetChangeInfo(&change, true) != B_OK) { + if (fInode->GetChangeInfo(&change, fAttrDir) != B_OK) { Trash(); return B_ERROR; } @@ -263,24 +263,34 @@ DirectoryCache::NotifyChanges(DirectoryCacheSnapshot* oldSnapshot, notify_entry_created(fInode->GetFileSystem()->DevId(), fInode->ID(), newCurrent->fName, newCurrent->fNode); - FileInfo fi; - fi.fFileId = newCurrent->fNode; - fi.fParent = fInode->fInfo.fHandle; - fi.fName = strdup(newCurrent->fName); - if (fi.fName != NULL) { - size_t pathLength = strlen(newCurrent->fName) + 2 + - strlen(fInode->fInfo.fPath); - char* path = reinterpret_cast<char*>(malloc(pathLength)); - if (path != NULL) { + do { + FileInfo fi; + fi.fFileId = newCurrent->fNode; + fi.fParent = fInode->fInfo.fHandle; + fi.fName = strdup(newCurrent->fName); + if (fi.fName == NULL) + break; + + if (fInode->fInfo.fPath != NULL) { + size_t pathLength = strlen(newCurrent->fName) + 2 + + strlen(fInode->fInfo.fPath); + char* path = reinterpret_cast<char*>(pathLength); + if (path == NULL) + break; + strcpy(path, fInode->fInfo.fPath); strcat(path, "/"); strcat(path, newCurrent->fName); fi.fPath = path; - - fInode->GetFileSystem()->InoIdMap()->AddEntry(fi, - Inode::FileIdToInoT(newCurrent->fNode)); + } else { + fi.fPath = strdup(newCurrent->fName); + if (fi.fPath == NULL) + break; } - } + + fInode->GetFileSystem()->InoIdMap()->AddEntry(fi, + Inode::FileIdToInoT(newCurrent->fNode), true); + } while (false); } } else oldSnapshot->fEntries.Remove(prev, oldCurrent); diff --git a/src/add-ons/kernel/file_systems/nfs4/FileInfo.cpp b/src/add-ons/kernel/file_systems/nfs4/FileInfo.cpp index e81242e..9ff0e49 100644 --- a/src/add-ons/kernel/file_systems/nfs4/FileInfo.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/FileInfo.cpp @@ -56,7 +56,7 @@ FileInfo::UpdateFileHandles(FileSystem* fs) uint32 lookupCount = 0; status_t result; - +dprintf("%s %s\n", fs->Path(), fPath); result = ParsePath(req, lookupCount, fs->Path()); if (result != B_OK) return result; diff --git a/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp b/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp index 4c8963a..ec5d992 100644 --- a/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp @@ -58,10 +58,11 @@ FileSystem::~FileSystem() static const char* -sGetPath(const char* root, const char* path) +GetPath(const char* root, const char* path) { int slash = 0; - for (int i = 0; path[i] != '\0'; i++) { + int i; + for (i = 0; path[i] != '\0'; i++) { if (path[i] != root[i] || root[i] == '\0') break; @@ -69,6 +70,9 @@ sGetPath(const char* root, const char* path) slash = i; } + if (path[i] == '\0') + return NULL; + return path + slash; } @@ -149,12 +153,6 @@ FileSystem::Mount(FileSystem** pfs, RPC::Server* serv, const char* fsPath, const char* name; if (fsPath != NULL && fsPath[0] == '/') fsPath++; - name = strrchr(fsPath, '/'); - if (name != NULL) { - name++; - fi.fName = strdup(name); - } else - fi.fName = strdup(fsPath); fs->fServer = serv; fs->fDevId = id; @@ -162,18 +160,30 @@ FileSystem::Mount(FileSystem** pfs, RPC::Server* serv, const char* fsPath, fi.fHandle = fh; fi.fParent = fh; - fi.fPath = strdup(sGetPath(fs->fPath, fsPath)); + fi.fPath = strdup(GetPath(fs->fPath, fsPath)); - delete[] values; + if (fi.fPath != NULL) { + name = strrchr(fi.fPath, '/'); + if (name != NULL) { + name++; + fi.fName = strdup(name); + } + } - if (fi.fName == NULL || fi.fPath == NULL) - return B_NO_MEMORY; + delete[] values; Inode* inode; result = Inode::CreateInode(fs, fi, &inode); if (result != B_OK) return result; + name = strrchr(fsPath, '/'); + if (name != NULL) { + name++; + reinterpret_cast<RootInode*>(inode)->SetName(name); + } else + reinterpret_cast<RootInode*>(inode)->SetName(fsPath); + fs->fRoot = reinterpret_cast<RootInode*>(inode); fs->NFSServer()->AddFileSystem(fs); diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp index c8cfd2c..a98ca4c 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp @@ -230,16 +230,21 @@ Inode::Link(Inode* dir, const char* name) if (fi.fName == NULL) return B_NO_MEMORY; - char* path = reinterpret_cast<char*>(malloc(strlen(name) + 2 + - strlen(fInfo.fPath))); - if (path == NULL) - return B_NO_MEMORY; - - strcpy(path, dir->fInfo.fPath); - strcat(path, "/"); - strcat(path, name); - free(const_cast<char*>(fi.fPath)); - fi.fPath = path; + if (fInfo.fPath != NULL) { + char* path = reinterpret_cast<char*>(malloc(strlen(name) + 2 + + strlen(fInfo.fPath))); + if (path == NULL) + return B_NO_MEMORY; + + strcpy(path, fInfo.fPath); + strcat(path, "/"); + strcat(path, name); + fi.fPath = path; + } else { + fi.fPath = strdup(name); + if (fi.fPath == NULL) + return B_NO_MEMORY; + } fFileSystem->InoIdMap()->AddEntry(fi, fInfo.fFileId); @@ -803,20 +808,33 @@ Inode::ChildAdded(const char* name, uint64 fileID, if (fi.fName == NULL) return B_NO_MEMORY; - char* path = reinterpret_cast<char*>(malloc(strlen(name) + 2 + - strlen(fInfo.fPath))); - if (path == NULL) - return B_NO_MEMORY; + if (fInfo.fPath != NULL) { + char* path = reinterpret_cast<char*>(malloc(strlen(name) + 2 + + strlen(fInfo.fPath))); + if (path == NULL) + return B_NO_MEMORY; - strcpy(path, fInfo.fPath); - strcat(path, "/"); - strcat(path, name); - fi.fPath = path; + strcpy(path, fInfo.fPath); + strcat(path, "/"); + strcat(path, name); + fi.fPath = path; + } else { + fi.fPath = strdup(name); + if (fi.fPath == NULL) + return B_NO_MEMORY; + } return fFileSystem->InoIdMap()->AddEntry(fi, FileIdToInoT(fileID)); } +const char* +Inode::Name() const +{ + return fInfo.fName; +} + + void Inode::SetDelegation(Delegation* delegation) { diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.h b/src/add-ons/kernel/file_systems/nfs4/Inode.h index d4d16ac..7497fa5 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.h +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.h @@ -20,11 +20,11 @@ class Inode : public NFS4Inode { public: static status_t CreateInode(FileSystem* fs, const FileInfo& fi, Inode** inode); - ~Inode(); + virtual ~Inode(); inline ino_t ID() const; inline mode_t Type() const; - inline const char* Name() const; + virtual const char* Name() const; inline FileSystem* GetFileSystem() const; inline void SetOpenState(OpenState* state); @@ -181,13 +181,6 @@ Inode::Type() const } -inline const char* -Inode::Name() const -{ - return fInfo.fName; -} - - inline FileSystem* Inode::GetFileSystem() const { diff --git a/src/add-ons/kernel/file_systems/nfs4/InodeIdMap.h b/src/add-ons/kernel/file_systems/nfs4/InodeIdMap.h index 2a29e07..ae85c32 100644 --- a/src/add-ons/kernel/file_systems/nfs4/InodeIdMap.h +++ b/src/add-ons/kernel/file_systems/nfs4/InodeIdMap.h @@ -23,7 +23,7 @@ public: inline ~InodeIdMap(); inline status_t AddEntry(const FileInfo& fi, - ino_t id); + ino_t id, bool weak = false); inline status_t RemoveEntry(ino_t id); inline status_t GetFileInfo(FileInfo* fi, ino_t id); @@ -49,10 +49,11 @@ InodeIdMap::~InodeIdMap() inline status_t -InodeIdMap::AddEntry(const FileInfo& fi, ino_t id) +InodeIdMap::AddEntry(const FileInfo& fi, ino_t id, bool weak) { MutexLocker _(fLock); - fMap.Remove(id); + //if (weak) + fMap.Remove(id); return fMap.Insert(id, fi); } diff --git a/src/add-ons/kernel/file_systems/nfs4/RootInode.cpp b/src/add-ons/kernel/file_systems/nfs4/RootInode.cpp index 0275f67..4ca51e2 100644 --- a/src/add-ons/kernel/file_systems/nfs4/RootInode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/RootInode.cpp @@ -18,6 +18,7 @@ RootInode::RootInode() : fInfoCacheExpire(0), + fName(NULL), fIOSize(0) { mutex_init(&fInfoCacheLock, NULL); @@ -26,6 +27,7 @@ RootInode::RootInode() RootInode::~RootInode() { + free(const_cast<char*>(fName)); mutex_destroy(&fInfoCacheLock); } @@ -125,7 +127,7 @@ RootInode::_UpdateInfo(bool force) } while (true); fInfoCache.flags = 0; - strncpy(fInfoCache.volume_name, fInfo.fName, B_FILE_NAME_LENGTH); + strncpy(fInfoCache.volume_name, fName, B_FILE_NAME_LENGTH); fInfoCacheExpire = time(NULL) + MetadataCache::kExpirationTime; @@ -161,7 +163,6 @@ RootInode::ProbeMigration() } - status_t RootInode::GetLocations(AttrValue** attrv) { @@ -198,3 +199,10 @@ RootInode::GetLocations(AttrValue** attrv) return B_OK; } + +const char* +RootInode::Name() const +{ + return fName; +} + diff --git a/src/add-ons/kernel/file_systems/nfs4/RootInode.h b/src/add-ons/kernel/file_systems/nfs4/RootInode.h index 864d49d..4810b78 100644 --- a/src/add-ons/kernel/file_systems/nfs4/RootInode.h +++ b/src/add-ons/kernel/file_systems/nfs4/RootInode.h @@ -19,6 +19,9 @@ public: RootInode(); ~RootInode(); + virtual const char* Name() const; + inline void SetName(const char* name); + status_t ReadInfo(struct fs_info* info); inline void MakeInfoInvalid(); @@ -32,6 +35,8 @@ private: mutex fInfoCacheLock; time_t fInfoCacheExpire; + const char* fName; + uint32 fIOSize; status_t _UpdateInfo(bool force = false); @@ -55,5 +60,13 @@ RootInode::IOSize() } +inline void +RootInode::SetName(const char* name) +{ + free(const_cast<char*>(fName)); + fName = strdup(name); +} + + #endif // ROOTINODE_H