added 2 changesets to branch 'refs/remotes/pdziepak-github/nfs4' old head: 09dbdd3644142673a8df63ae77ff8ccd4524c835 new head: 7cac2f6e50588ad130d2770ada1b1981569a1602 ---------------------------------------------------------------------------- 6b9a91e: nfs4: ReadDir sholud not including '..' and '.' 7cac2f6: nfs4: Local creation of node should not invalidate the cache [ Pawel Dziepak <pdziepak@xxxxxxxxxxx> ] ---------------------------------------------------------------------------- 5 files changed, 145 insertions(+), 43 deletions(-) src/add-ons/kernel/file_systems/nfs4/Cookie.h | 1 + .../kernel/file_systems/nfs4/DirectoryCache.cpp | 17 ++- .../kernel/file_systems/nfs4/DirectoryCache.h | 4 +- src/add-ons/kernel/file_systems/nfs4/Inode.cpp | 78 ++++++++++++-- src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp | 88 ++++++++++------ ############################################################################ Commit: 6b9a91eb660bb88915f900678e3f3609b71135d1 Author: Pawel Dziepak <pdziepak@xxxxxxxxxxx> Date: Fri Jul 20 01:56:12 2012 UTC nfs4: ReadDir sholud not including '..' and '.' ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/file_systems/nfs4/Cookie.h b/src/add-ons/kernel/file_systems/nfs4/Cookie.h index 38a77d3..c5b0528 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Cookie.h +++ b/src/add-ons/kernel/file_systems/nfs4/Cookie.h @@ -106,6 +106,7 @@ private: }; struct OpenDirCookie : public Cookie { + int fSpecial; DirectoryCacheSnapshot* fSnapshot; NameCacheEntry* fCurrent; bool fEOF; diff --git a/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp b/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp index 05af489..2c84afb 100644 --- a/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp @@ -122,6 +122,7 @@ Inode::OpenDir(OpenDirCookie* cookie) return B_PERMISSION_DENIED; cookie->fFileSystem = fFileSystem; + cookie->fSpecial = 0; cookie->fSnapshot = NULL; cookie->fCurrent = NULL; cookie->fEOF = false; @@ -334,30 +335,6 @@ Inode::_GetDirSnapshot(DirectoryCacheSnapshot** _snapshot, return B_OK; } -/* - if (cookie->fCookie == 0 && cookie->fCookieVerf == 2 && count < *_count) { - struct dirent* de = reinterpret_cast<dirent*>(buffer + pos); - - _FillDirEntry(de, fInfo.fFileId, ".", pos, size); - - pos += de->d_reclen; - count++; - cookie->fCookieVerf--; - } - - if (cookie->fCookie == 0 && cookie->fCookieVerf == 1 && count < *_count) { - struct dirent* de = reinterpret_cast<dirent*>(buffer + pos); - - if (strcmp(fInfo.fName, "/")) - _ReadDirUp(de, pos, size); - else - _FillDirEntry(de, _FileIdToInoT(fInfo.fFileId), "..", pos, size); - - pos += de->d_reclen; - count++; - cookie->fCookieVerf--; - } -*/ status_t Inode::ReadDir(void* _buffer, uint32 size, uint32* _count, @@ -397,11 +374,46 @@ Inode::ReadDir(void* _buffer, uint32 size, uint32* _count, char* buffer = reinterpret_cast<char*>(_buffer); uint32 pos = 0; + uint32 i = 0; + bool overflow = false; + + if (cookie->fSpecial == 0 && i < *_count) { + struct dirent* de = reinterpret_cast<dirent*>(buffer + pos); + + status_t result; + result = _FillDirEntry(de, fInfo.fFileId, ".", pos, size); + + if (result == B_BUFFER_OVERFLOW) + overflow = true; + else if (result == B_OK) { + pos += de->d_reclen; + i++; + cookie->fSpecial++; + } else + return result; + } + + if (cookie->fSpecial == 1 && i < *_count) { + struct dirent* de = reinterpret_cast<dirent*>(buffer + pos); + + status_t result; + if (strcmp(fInfo.fName, "/")) + result = _ReadDirUp(de, pos, size); + else + result = _FillDirEntry(de, _FileIdToInoT(fInfo.fFileId), "..", pos, size); + + if (result == B_BUFFER_OVERFLOW) + overflow = true; + else if (result == B_OK) { + pos += de->d_reclen; + i++; + cookie->fSpecial++; + } else + return result; + } MutexLocker _(cookie->fSnapshot->fLock); - uint32 i; - bool overflow = false; - for (i = 0; i < *_count; i++) { + for (; !overflow && i < *_count; i++) { struct dirent* de = reinterpret_cast<dirent*>(buffer + pos); if (cookie->fCurrent == NULL) ############################################################################ Commit: 7cac2f6e50588ad130d2770ada1b1981569a1602 Author: Pawel Dziepak <pdziepak@xxxxxxxxxxx> Date: Fri Jul 20 02:09:16 2012 UTC nfs4: Local creation of node should not invalidate the cache ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp b/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp index a3065aa..dbb10f0 100644 --- a/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp @@ -87,9 +87,9 @@ DirectoryCache::Trash() fTrashed = true; } -// TODO: separate AddEntry() for Name and Directory Cache are needed + status_t -DirectoryCache::AddEntry(const char* name, ino_t node) +DirectoryCache::AddEntry(const char* name, ino_t node, bool created) { NameCacheEntry* entry = new(std::nothrow) NameCacheEntry(name, node); if (entry == NULL) @@ -101,6 +101,19 @@ DirectoryCache::AddEntry(const char* name, ino_t node) fNameCache.Add(entry); + if (created && fDirectoryCache != NULL) { + MutexLocker _(fDirectoryCache->fLock); + NameCacheEntry* entry = new(std::nothrow) NameCacheEntry(name, node); + if (entry == NULL) + return B_NO_MEMORY; + if (entry->fName == NULL) { + delete entry; + return B_NO_MEMORY; + } + + fDirectoryCache->fEntries.Add(entry); + } + return entry_cache_add(fInode->GetFileSystem()->DevId(), fInode->ID(), name, node); } diff --git a/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.h b/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.h index 0e9b07b..9e880f6 100644 --- a/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.h +++ b/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.h @@ -46,7 +46,8 @@ public: void ResetAndLock(); void Trash(); - status_t AddEntry(const char* name, ino_t node); + status_t AddEntry(const char* name, ino_t node, + bool created = false); void RemoveEntry(const char* name); void SetSnapshot(DirectoryCacheSnapshot* snapshot); @@ -68,7 +69,6 @@ private: SinglyLinkedList<NameCacheEntry> fNameCache; DirectoryCacheSnapshot* fDirectoryCache; - //mutex fDirectoryCacheLock; Inode* fInode; diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp index f49a0c2..3d87f36 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp @@ -281,6 +281,10 @@ Inode::Link(Inode* dir, const char* name) req.PutFH(dir->fInfo.fHandle); req.Link(name); + req.LookUp(name); + Attribute attr[] = { FATTR4_FILEID }; + req.GetAttr(attr, sizeof(attr) / sizeof(Attribute)); + status_t result = request.Send(); if (result != B_OK) return result; @@ -310,10 +314,27 @@ Inode::Link(Inode* dir, const char* name) if (result != B_OK) return result; + result = reply.LookUp(); + if (result != B_OK) + return result; + + AttrValue* values; + uint32 count; + result = reply.GetAttr(&values, &count); + if (result != B_OK) + return result; + + uint32 fileID; + if (count == 0) + fileID = fFileSystem->AllocFileId(); + else + fileID = values[1].fData.fValue64; + + fFileSystem->Root()->MakeInfoInvalid(); + if (fCache->Lock() == B_OK) { if (atomic && fCache->ChangeInfo() == before) { - // TODO: update cache - //fCache->AddEntry(name, ); + fCache->AddEntry(name, fileID, true); fCache->SetChangeInfo(after); } else if (fCache->ChangeInfo() != before) fCache->Trash(); @@ -418,6 +439,10 @@ Inode::Rename(Inode* from, Inode* to, const char* fromName, const char* toName) req.PutFH(to->fInfo.fHandle); req.Rename(fromName, toName); + Attribute attr[] = { FATTR4_FILEID }; + req.GetAttr(attr, sizeof(attr) / sizeof(Attribute)); + req.LookUp(toName); + status_t result = request.Send(); if (result != B_OK) return result; @@ -445,6 +470,26 @@ Inode::Rename(Inode* from, Inode* to, const char* fromName, const char* toName) bool fromAtomic, toAtomic; result = reply.Rename(&fromBefore, &fromAfter, fromAtomic, &toBefore, &toAfter, toAtomic); + if (result != B_OK) + return result; + + result = reply.LookUp(); + if (result != B_OK) + return result; + + AttrValue* values; + uint32 count; + result = reply.GetAttr(&values, &count); + if (result != B_OK) + return result; + + uint32 fileID; + if (count == 0) + fileID = from->fFileSystem->AllocFileId(); + else + fileID = values[1].fData.fValue64; + + from->fFileSystem->Root()->MakeInfoInvalid(); if (from->fCache->Lock() == B_OK) { if (fromAtomic && from->fCache->ChangeInfo() == fromBefore) { @@ -457,15 +502,14 @@ Inode::Rename(Inode* from, Inode* to, const char* fromName, const char* toName) if (to->fCache->Lock() == B_OK) { if (toAtomic && to->fCache->ChangeInfo() == toBefore) { - // TODO: update cache - //fCache->AddEntry(toName, ); + to->fCache->AddEntry(toName, fileID, true); to->fCache->SetChangeInfo(toAfter); } else if (to->fCache->ChangeInfo() != toBefore) to->fCache->Trash(); to->fCache->Unlock(); - }; + } - return result; + return B_OK; } while (true); } @@ -505,6 +549,9 @@ Inode::CreateLink(const char* name, const char* path, int mode) req.Create(NF4LNK, name, cattr, i, path); + Attribute attr[] = { FATTR4_FILEID }; + req.GetAttr(attr, sizeof(attr) / sizeof(Attribute)); + status_t result = request.Send(); if (result != B_OK) return result; @@ -523,20 +570,33 @@ Inode::CreateLink(const char* name, const char* path, int mode) uint64 before, after; bool atomic; result = reply.Create(&before, &after, atomic); + if (result != B_OK) + return result; + + AttrValue* values; + uint32 count; + result = reply.GetAttr(&values, &count); + if (result != B_OK) + return result; + + uint32 fileID; + if (count == 0) + fileID = fFileSystem->AllocFileId(); + else + fileID = values[1].fData.fValue64; fFileSystem->Root()->MakeInfoInvalid(); if (fCache->Lock() == B_OK) { if (atomic && fCache->ChangeInfo() == before) { - // TODO: update cache - //fCache->AddEntry(name, ); + fCache->AddEntry(name, fileID, true); fCache->SetChangeInfo(after); } else if (fCache->ChangeInfo() != before) fCache->Trash(); fCache->Unlock(); } - return result; + return B_OK; } while (true); } diff --git a/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp b/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp index 2c84afb..28addc3 100644 --- a/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp @@ -52,6 +52,9 @@ Inode::CreateDir(const char* name, int mode) req.Create(NF4DIR, name, cattr, i); + Attribute attr[] = { FATTR4_FILEID }; + req.GetAttr(attr, sizeof(attr) / sizeof(Attribute)); + status_t result = request.Send(); if (result != B_OK) return result; @@ -70,20 +73,33 @@ Inode::CreateDir(const char* name, int mode) uint64 before, after; bool atomic; result = reply.Create(&before, &after, atomic); + if (result != B_OK) + return result; + + AttrValue* values; + uint32 count; + result = reply.GetAttr(&values, &count); + if (result != B_OK) + return result; + + uint32 fileID; + if (count == 0) + fileID = fFileSystem->AllocFileId(); + else + fileID = values[1].fData.fValue64; fFileSystem->Root()->MakeInfoInvalid(); if (fCache->Lock() == B_OK) { if (atomic && fCache->ChangeInfo() == before) { - // TODO: update cache - //fCache->AddEntry(name, ); + fCache->AddEntry(name, fileID, true); fCache->SetChangeInfo(after); } else if (fCache->ChangeInfo() != before) fCache->Trash(); fCache->Unlock(); } - return result; + return B_OK; } while (true); }