From ed517d6c6220cb2e3357f24b98fc02fcdc6e1323 Mon Sep 17 00:00:00 2001 From: Pawel Dziepak Date: Tue, 5 Jun 2012 14:03:53 +0200 Subject: [PATCH] nfs4: Do not store pointer to parent in inodes --- .../kernel/file_systems/nfs4/Filesystem.cpp | 4 +- .../kernel/file_systems/nfs4/Inode.cpp | 64 ++++++++++++++++--- src/add-ons/kernel/file_systems/nfs4/Inode.h | 7 +- 3 files changed, 63 insertions(+), 12 deletions(-) diff --git a/src/add-ons/kernel/file_systems/nfs4/Filesystem.cpp b/src/add-ons/kernel/file_systems/nfs4/Filesystem.cpp index c5f6e87e0e..27c27164af 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Filesystem.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Filesystem.cpp @@ -131,7 +131,7 @@ Filesystem::GetInode(ino_t id, Inode** _inode) if (result != B_OK) return result; - Inode* inode = new(std::nothrow)Inode(this, fh, NULL); + Inode* inode = new(std::nothrow)Inode(this, fh); if (inode == NULL) return B_NO_MEMORY; @@ -143,6 +143,6 @@ Filesystem::GetInode(ino_t id, Inode** _inode) Inode* Filesystem::CreateRootInode() { - return new(std::nothrow)Inode(this, fRootFH, NULL); + return new(std::nothrow)Inode(this, fRootFH, true); } diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp index 48329a1e1b..ffcdda99ea 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp @@ -18,10 +18,10 @@ // Creating Inode object from Filehandle probably is not a good idea when // filehandles are volatile. -Inode::Inode(Filesystem* fs, const Filehandle &fh, Inode* parent) +Inode::Inode(Filesystem* fs, const Filehandle &fh, bool root) : fFilesystem(fs), - fParent(parent) + fRoot(root) { memcpy(&fHandle, &fh, sizeof(fh)); @@ -65,6 +65,7 @@ Inode::Inode(Filesystem* fs, const Filehandle &fh, Inode* parent) status_t Inode::LookUp(const char* name, ino_t* id) { + dprintf("nfs4: lookup: %s\n", name); if (fType != NF4DIR) return B_NOT_A_DIRECTORY; @@ -116,10 +117,10 @@ Inode::LookUp(const char* name, ino_t* id) delete[] values; return B_UNSUPPORTED; } - *id = values[0].fData.fValue64; - delete[] values; + *id = _FileIdToInoT(values[0].fData.fValue64); + fFilesystem->InoIdMap()->AddEntry(fh, values[0].fData.fValue64); - fFilesystem->InoIdMap()->AddEntry(fh, *id); + delete[] values; return B_OK; } @@ -256,6 +257,53 @@ Inode::_FillDirEntry(struct dirent* de, ino_t id, const char* name, uint32 pos, } +status_t +Inode::_ReadDirUp(struct dirent* de, uint32 pos, uint32 size) +{ + RequestBuilder req(ProcCompound); + req.PutFH(fHandle); + req.LookUpUp(); + req.GetFH(); + Attribute attr[] = { FATTR4_FILEID }; + req.GetAttr(attr, sizeof(attr) / sizeof(Attribute)); + + RPC::Reply *rpl; + fFilesystem->Server()->SendCall(req.Request(), &rpl); + ReplyInterpreter reply(rpl); + + status_t result; + result = reply.PutFH(); + if (result != B_OK) + return result; + + result = reply.LookUpUp(); + if (result != B_OK) + return result; + + Filehandle fh; + result = reply.GetFH(&fh); + if (result != B_OK) + return result; + + AttrValue* values; + uint32 count; + result = reply.GetAttr(&values, &count); + if (result != B_OK) + return result; + + uint64 fileId; + if (count < 1 || values[0].fAttribute != FATTR4_FILEID) { + // Server does not provide fileid. We need to make something up. + fileId = fFilesystem->GetId(); + } else + fileId = values[0].fData.fValue64; + + fFilesystem->InoIdMap()->AddEntry(fh, fileId); + + return _FillDirEntry(de, _FileIdToInoT(fileId), "..", pos, size); +} + + status_t Inode::ReadDir(void* _buffer, uint32 size, uint32* _count, uint64* cookie) { @@ -279,10 +327,10 @@ Inode::ReadDir(void* _buffer, uint32 size, uint32* _count, uint64* cookie) if (cookie[0] == 0 && cookie[1] == 1 && count < *_count) { struct dirent* de = reinterpret_cast(buffer + pos); - if (fParent != NULL) - _FillDirEntry(de, fParent->fFileId, "..", pos, size); + if (!fRoot) + _ReadDirUp(de, pos, size); else - _FillDirEntry(de, fFileId, "..", pos, size); + _FillDirEntry(de, _FileIdToInoT(fFileId), "..", pos, size); pos += de->d_reclen; count++; diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.h b/src/add-ons/kernel/file_systems/nfs4/Inode.h index c631b95889..0245e91a79 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.h +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.h @@ -21,7 +21,7 @@ class Inode { public: Inode(Filesystem* fs, const Filehandle &fh, - Inode* parent); + bool root = false); inline ino_t ID() const; inline mode_t Type() const; @@ -38,6 +38,8 @@ private: uint64* cookie, bool* eof); status_t _FillDirEntry(struct dirent* de, ino_t id, const char* name, uint32 pos, uint32 size); + status_t _ReadDirUp(struct dirent* de, uint32 pos, + uint32 size); static inline ino_t _FileIdToInoT(uint64 fileid); @@ -46,7 +48,8 @@ private: Filehandle fHandle; Filesystem* fFilesystem; - Inode* fParent; // this will cause trouble + + bool fRoot; };