[haiku-commits] BRANCH pdziepak-github.nfs4 - src/add-ons/kernel/file_systems/nfs4

  • From: pdziepak-github.nfs4 <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 20 Jul 2012 04:49:08 +0200 (CEST)

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);
 }
 


Other related posts: