From 6b9a91eb660bb88915f900678e3f3609b71135d1 Mon Sep 17 00:00:00 2001 From: Pawel Dziepak Date: Fri, 20 Jul 2012 03:56:12 +0200 Subject: [PATCH] nfs4: ReadDir sholud not including '..' and '.' --- src/add-ons/kernel/file_systems/nfs4/Cookie.h | 1 + .../kernel/file_systems/nfs4/InodeDir.cpp | 66 +++++++++++-------- 2 files changed, 40 insertions(+), 27 deletions(-) diff --git a/src/add-ons/kernel/file_systems/nfs4/Cookie.h b/src/add-ons/kernel/file_systems/nfs4/Cookie.h index 38a77d3ad4..c5b0528ce4 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 05af489268..2c84afbd69 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(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(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(_buffer); uint32 pos = 0; + uint32 i = 0; + bool overflow = false; + + if (cookie->fSpecial == 0 && i < *_count) { + struct dirent* de = reinterpret_cast(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(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(buffer + pos); if (cookie->fCurrent == NULL)