[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, 10 Aug 2012 02:49:12 +0200 (CEST)

added 1 changeset to branch 'refs/remotes/pdziepak-github/nfs4'
old head: 0e0d53c7995f23e83364ec628c9623041e2b22bc
new head: b1fd656d454ab89fbfdac09fda1b6aafd81bbe89

----------------------------------------------------------------------------

b1fd656: nfs4: Fix server reboot recovery

                                    [ Pawel Dziepak <pdziepak@xxxxxxxxxxx> ]

----------------------------------------------------------------------------

Commit:      b1fd656d454ab89fbfdac09fda1b6aafd81bbe89

Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Fri Aug 10 00:34:41 2012 UTC

----------------------------------------------------------------------------

14 files changed, 73 insertions(+), 41 deletions(-)
.../kernel/file_systems/nfs4/Delegation.cpp        |    2 +-
src/add-ons/kernel/file_systems/nfs4/Delegation.h  |    8 ++++
.../kernel/file_systems/nfs4/FileSystem.cpp        |   22 +++--------
src/add-ons/kernel/file_systems/nfs4/FileSystem.h  |    4 +-
src/add-ons/kernel/file_systems/nfs4/Inode.cpp     |    8 ++--
src/add-ons/kernel/file_systems/nfs4/Inode.h       |    9 +++++
.../kernel/file_systems/nfs4/InodeRegular.cpp      |    1 -
src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp |    2 +-
.../kernel/file_systems/nfs4/NFS4Object.cpp        |    9 ++++-
src/add-ons/kernel/file_systems/nfs4/NFS4Object.h  |    3 +-
.../kernel/file_systems/nfs4/NFS4Server.cpp        |    6 ++-
src/add-ons/kernel/file_systems/nfs4/OpenState.cpp |   33 +++++++++++++---
src/add-ons/kernel/file_systems/nfs4/OpenState.h   |    6 +--
.../kernel/file_systems/nfs4/ReplyInterpreter.cpp  |    1 +

----------------------------------------------------------------------------

diff --git a/src/add-ons/kernel/file_systems/nfs4/Delegation.cpp 
b/src/add-ons/kernel/file_systems/nfs4/Delegation.cpp
index 19ea2f2..a0ce499 100644
--- a/src/add-ons/kernel/file_systems/nfs4/Delegation.cpp
+++ b/src/add-ons/kernel/file_systems/nfs4/Delegation.cpp
@@ -53,7 +53,7 @@ Delegation::ReturnDelegation()
 
                ReplyInterpreter& reply = request.Reply();
 
-               if (HandleErrors(reply.NFS4Error(), serv))
+               if (HandleErrors(reply.NFS4Error(), serv, NULL, 
fInode->GetOpenState()))
                        continue;
 
                reply.PutFH();
diff --git a/src/add-ons/kernel/file_systems/nfs4/Delegation.h 
b/src/add-ons/kernel/file_systems/nfs4/Delegation.h
index f901173..807d526 100644
--- a/src/add-ons/kernel/file_systems/nfs4/Delegation.h
+++ b/src/add-ons/kernel/file_systems/nfs4/Delegation.h
@@ -25,6 +25,7 @@ public:
 
        status_t                        GiveUp(bool truncate = false);
 
+       inline  void            SetData(const OpenDelegationData& data);
        inline  Inode*          GetInode();
        inline  OpenDelegation Type();
 
@@ -39,6 +40,13 @@ private:
 };
 
 
+inline void
+Delegation::SetData(const OpenDelegationData& data)
+{
+       fData = data;
+}
+
+
 inline Inode*
 Delegation::GetInode()
 {
diff --git a/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp 
b/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp
index ecc56b2..d211299 100644
--- a/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp
+++ b/src/add-ons/kernel/file_systems/nfs4/FileSystem.cpp
@@ -25,7 +25,6 @@ FileSystem::FileSystem()
        :
        fNext(NULL),
        fPrev(NULL),
-       fOpenFiles(NULL),
        fOpenCount(0),
        fOpenOwnerSequence(0),
        fPath(NULL),
@@ -267,7 +266,7 @@ FileSystem::Migrate(const RPC::Server* serv)
 }
 
 
-OpenState*
+DoublyLinkedList<OpenState>&
 FileSystem::OpenFilesLock()
 {
        mutex_lock(&fOpenLock);
@@ -287,11 +286,8 @@ FileSystem::AddOpenFile(OpenState* state)
 {
        MutexLocker _(fOpenLock);
 
-       state->fPrev = NULL;
-       state->fNext = fOpenFiles;
-       if (fOpenFiles != NULL)
-               fOpenFiles->fPrev = state;
-       fOpenFiles = state;
+       fOpenFiles.InsertBefore(fOpenFiles.Head(), state);
+
        NFSServer()->IncUsage();
 }
 
@@ -300,13 +296,9 @@ void
 FileSystem::RemoveOpenFile(OpenState* state)
 {
        MutexLocker _(fOpenLock);
-       if (state == fOpenFiles)
-               fOpenFiles = state->fNext;
 
-       if (state->fNext)
-               state->fNext->fPrev = state->fPrev;
-       if (state->fPrev)
-               state->fPrev->fNext = state->fNext;
+       fOpenFiles.Remove(state);
+
        NFSServer()->DecUsage();
 }
 
@@ -335,8 +327,6 @@ FileSystem::AddDelegation(Delegation* delegation)
 
        fHandleToDelegation.Remove(delegation->fInfo.fHandle);
        fHandleToDelegation.Insert(delegation->fInfo.fHandle, delegation);
-
-       NFSServer()->IncUsage();
 }
 
 
@@ -347,8 +337,6 @@ FileSystem::RemoveDelegation(Delegation* delegation)
 
        fDelegationList.Remove(delegation);
        fHandleToDelegation.Remove(delegation->fInfo.fHandle);
-
-       NFSServer()->DecUsage();
 }
 
 
diff --git a/src/add-ons/kernel/file_systems/nfs4/FileSystem.h 
b/src/add-ons/kernel/file_systems/nfs4/FileSystem.h
index adfea0a..b055e3b 100644
--- a/src/add-ons/kernel/file_systems/nfs4/FileSystem.h
+++ b/src/add-ons/kernel/file_systems/nfs4/FileSystem.h
@@ -30,7 +30,7 @@ public:
 
                        status_t                        Migrate(const 
RPC::Server* serv);
 
-                       OpenState*                      OpenFilesLock();
+                       DoublyLinkedList<OpenState>&    OpenFilesLock();
                        void                            OpenFilesUnlock();
        inline  uint32                          OpenFilesCount();
                        void                            AddOpenFile(OpenState* 
state);
@@ -73,7 +73,7 @@ private:
                        DoublyLinkedList<Delegation>    fDelegationList;
                        AVLTreeMap<FileHandle, Delegation*> fHandleToDelegation;
 
-                       OpenState*                      fOpenFiles;
+                       DoublyLinkedList<OpenState>             fOpenFiles;
                        uint32                          fOpenCount;
                        mutex                           fOpenLock;
 
diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp 
b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp
index cd7f14b..02ea63e 100644
--- a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp
+++ b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp
@@ -857,9 +857,9 @@ Inode::RecallReadDelegation()
 void
 Inode::ReturnDelegation(bool truncate)
 {
-       fMetaCache.UnlockValid();
-
        fDelegation->GiveUp(truncate);
+
+       fMetaCache.UnlockValid();
        fFileSystem->RemoveDelegation(fDelegation);
 
        MutexLocker stateLocker(fStateLock);
@@ -874,10 +874,8 @@ Inode::ReturnDelegation(bool truncate)
 void
 Inode::ReleaseOpenState()
 {
-       if (fOpenState->ReleaseReference() == 1) {
-               fFileSystem->RemoveOpenFile(fOpenState);
+       if (fOpenState->ReleaseReference() == 1)
                fOpenState = NULL;
-       }
 }
 
 
diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.h 
b/src/add-ons/kernel/file_systems/nfs4/Inode.h
index e5a477a..ab8feec 100644
--- a/src/add-ons/kernel/file_systems/nfs4/Inode.h
+++ b/src/add-ons/kernel/file_systems/nfs4/Inode.h
@@ -37,6 +37,8 @@ public:
        inline                  uint64          Change();
        inline                  bool            Dirty();
 
+       inline                  OpenState*      GetOpenState();
+
                                        void            
SetDelegation(Delegation* delegation);
                                        void            RecallDelegation(bool 
truncate = false);
                                        void            RecallReadDelegation();
@@ -230,5 +232,12 @@ Inode::Dirty()
 }
 
 
+inline OpenState*
+Inode::GetOpenState()
+{
+       return fOpenState;
+}
+
+
 #endif // INODE_H
 
diff --git a/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp 
b/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp
index 2eb1a1b..5490ee0 100644
--- a/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp
+++ b/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp
@@ -252,7 +252,6 @@ Inode::CloseAttr(OpenAttrCookie* cookie)
        fFileSystem->RemoveDelegation(cookie->fOpenState->fDelegation);
        delete cookie->fOpenState->fDelegation;
        delete cookie->fOpenState;
-
        return B_OK;
 }
 
diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp 
b/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp
index 565b502..4f4dc73 100644
--- a/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp
+++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp
@@ -553,7 +553,7 @@ NFS4Inode::OpenFile(OpenState* state, int mode, 
OpenDelegationData* delegation)
 
                ReplyInterpreter& reply = request.Reply();
 
-               if (HandleErrors(reply.NFS4Error(), serv, NULL, state))
+               if (HandleErrors(reply.NFS4Error(), serv, NULL, state, 
&sequence))
                        continue;
 
                fFileSystem->OpenOwnerSequenceUnlock();
diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Object.cpp 
b/src/add-ons/kernel/file_systems/nfs4/NFS4Object.cpp
index 6663cc3..fc5aecf 100644
--- a/src/add-ons/kernel/file_systems/nfs4/NFS4Object.cpp
+++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Object.cpp
@@ -16,7 +16,7 @@
 
 bool
 NFS4Object::HandleErrors(uint32 nfs4Error, RPC::Server* serv,
-       OpenStateCookie* cookie, OpenState* state)
+       OpenStateCookie* cookie, OpenState* state, uint32* sequence)
 {
        uint32 leaseTime;
 
@@ -67,7 +67,14 @@ NFS4Object::HandleErrors(uint32 nfs4Error, RPC::Server* serv,
                case NFS4ERR_STALE_CLIENTID:
                case NFS4ERR_STALE_STATEID:
                        if (state != NULL) {
+                               if (sequence != NULL)
+                                       
fFileSystem->OpenOwnerSequenceUnlock(false);
+
                                
fFileSystem->NFSServer()->ServerRebooted(state->fClientID);
+dprintf("returned rebooted\n");
+                               if (sequence != NULL)
+                                       *sequence = 
fFileSystem->OpenOwnerSequenceLock();
+dprintf("locked again\n");
                                return true;
                        }
                        return false;
diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Object.h 
b/src/add-ons/kernel/file_systems/nfs4/NFS4Object.h
index 3af5129..817b1c2 100644
--- a/src/add-ons/kernel/file_systems/nfs4/NFS4Object.h
+++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Object.h
@@ -19,7 +19,8 @@ class OpenState;
 class NFS4Object {
 public:
        bool            HandleErrors(uint32 nfs4Error, RPC::Server* serv,
-                                       OpenStateCookie* cookie = NULL, 
OpenState* state = NULL);
+                                       OpenStateCookie* cookie = NULL, 
OpenState* state = NULL,
+                                       uint32* sequence = NULL);
 
        status_t        ConfirmOpen(const FileHandle& fileHandle, OpenState* 
state);
 
diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Server.cpp 
b/src/add-ons/kernel/file_systems/nfs4/NFS4Server.cpp
index 07acb75..173e527 100644
--- a/src/add-ons/kernel/file_systems/nfs4/NFS4Server.cpp
+++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Server.cpp
@@ -58,11 +58,13 @@ NFS4Server::ServerRebooted(uint64 clientId)
        MutexLocker _(fFSLock);
        FileSystem* fs = fFileSystems;
        while (fs != NULL) {
-               OpenState* current = fs->OpenFilesLock();
+               DoublyLinkedList<OpenState>::Iterator iterator
+                       = fs->OpenFilesLock().GetIterator();
+               OpenState* current = iterator.Next();
                while (current != NULL) {
                        current->Reclaim(fClientId);
 
-                       current = current->fNext;
+                       current = iterator.Next();
                }
                fs->OpenFilesUnlock();
 
diff --git a/src/add-ons/kernel/file_systems/nfs4/OpenState.cpp 
b/src/add-ons/kernel/file_systems/nfs4/OpenState.cpp
index 388b62f..62c93bb 100644
--- a/src/add-ons/kernel/file_systems/nfs4/OpenState.cpp
+++ b/src/add-ons/kernel/file_systems/nfs4/OpenState.cpp
@@ -13,6 +13,7 @@
 
 #include "FileSystem.h"
 #include "Request.h"
+#include "WorkQueue.h"
 
 
 OpenState::OpenState()
@@ -31,7 +32,9 @@ OpenState::OpenState()
 
 OpenState::~OpenState()
 {
+       fFileSystem->RemoveOpenFile(this);
        Close();
+
        mutex_destroy(&fLock);
 
        mutex_destroy(&fLocksLock);
@@ -140,9 +143,10 @@ OpenState::Reclaim(uint64 newClientID)
        if (fClientID == newClientID)
                return B_OK;
        fClientID = newClientID;
-
+dprintf("reclaim start\n");
        _ReclaimOpen(newClientID);
        _ReclaimLocks(newClientID);
+dprintf("reclaim end\n");
        return B_OK;
 }
 
@@ -150,10 +154,16 @@ OpenState::Reclaim(uint64 newClientID)
 status_t
 OpenState::_ReclaimOpen(uint64 newClientID)
 {
+       dprintf("reclaim %s\n", fInfo.fName);
+
        bool confirm;
        OpenDelegationData delegation;
+       delegation.fType = OPEN_DELEGATE_NONE;
+       delegation.fRecall = false;
 
        uint32 sequence = fFileSystem->OpenOwnerSequenceLock();
+       OpenDelegation delegType = fDelegation != NULL ? fDelegation->Type()
+               : OPEN_DELEGATE_NONE;
        do {
                RPC::Server* server = fFileSystem->Server();
                Request request(server);
@@ -162,7 +172,7 @@ OpenState::_ReclaimOpen(uint64 newClientID)
                req.PutFH(fInfo.fHandle);
                req.Open(CLAIM_PREVIOUS, sequence, sModeToAccess(fMode), 
newClientID,
                        OPEN4_NOCREATE, fFileSystem->OpenOwner(), NULL, NULL, 
0, false,
-                       fDelegation->Type());
+                       delegType);
 
                status_t result = request.Send();
                if (result != B_OK) {
@@ -172,7 +182,7 @@ OpenState::_ReclaimOpen(uint64 newClientID)
 
                ReplyInterpreter& reply = request.Reply();
 
-               if (HandleErrors(reply.NFS4Error(), server))
+               if (HandleErrors(reply.NFS4Error(), server, NULL, NULL, 
&sequence))
                        continue;
 
                fFileSystem->OpenOwnerSequenceUnlock();
@@ -182,10 +192,19 @@ OpenState::_ReclaimOpen(uint64 newClientID)
                result = reply.Open(fStateID, &fStateSeq, &confirm, 
&delegation);
                if (result != B_OK)
                        return result;
+
+               break;
        } while (true);
 
-       if (delegation.fRecall)
-               fDelegation->GiveUp();
+       if (fDelegation != NULL)
+               fDelegation->SetData(delegation);
+
+       if (delegation.fRecall) {
+               DelegationRecallArgs* args = new(std::nothrow) 
DelegationRecallArgs;
+               args->fDelegation = fDelegation;
+               args->fTruncate = false;
+               gWorkQueue->EnqueueJob(DelegationRecall, args);
+       }
 
        if (confirm)
                return ConfirmOpen(fInfo.fHandle, this);
@@ -197,6 +216,8 @@ OpenState::_ReclaimOpen(uint64 newClientID)
 status_t
 OpenState::_ReclaimLocks(uint64 newClientID)
 {
+       dprintf("reclaim locks %s\n", fInfo.fName);
+
        MutexLocker _(fLocksLock);
        LockInfo* linfo = fLocks;
        while (linfo != NULL) {
@@ -264,7 +285,7 @@ OpenState::Close()
 
                ReplyInterpreter& reply = request.Reply();
 
-               if (HandleErrors(reply.NFS4Error(), serv, NULL, this))
+               if (HandleErrors(reply.NFS4Error(), serv, NULL, this, 
&sequence))
                        continue;
                fFileSystem->OpenOwnerSequenceUnlock();
 
diff --git a/src/add-ons/kernel/file_systems/nfs4/OpenState.h 
b/src/add-ons/kernel/file_systems/nfs4/OpenState.h
index 8cfdce5..f810528 100644
--- a/src/add-ons/kernel/file_systems/nfs4/OpenState.h
+++ b/src/add-ons/kernel/file_systems/nfs4/OpenState.h
@@ -17,7 +17,8 @@
 #include "NFS4Object.h"
 
 
-struct OpenState : public NFS4Object, public KernelReferenceable {
+struct OpenState : public NFS4Object, public KernelReferenceable,
+       public DoublyLinkedListLinkImpl<OpenState> {
                                                        OpenState();
                                                        ~OpenState();
 
@@ -38,9 +39,6 @@ struct OpenState : public NFS4Object, public 
KernelReferenceable {
                        LockOwner*              fLockOwners;
                        mutex                   fOwnerLock;
 
-                       OpenState*              fNext;
-                       OpenState*              fPrev;
-
                        LockOwner*              GetLockOwner(uint32 owner);
 
                        void                    AddLock(LockInfo* lock);
diff --git a/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp 
b/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp
index b26082d..5812827 100644
--- a/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp
+++ b/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp
@@ -827,6 +827,7 @@ ReplyInterpreter::_NFS4ErrorToHaiku(uint32 x)
                case NFS4ERR_ISDIR:             return B_IS_A_DIRECTORY;
                case NFS4ERR_INVAL:             return B_BAD_VALUE;
                case NFS4ERR_FBIG:              return B_FILE_TOO_LARGE;
+               case NFS4ERR_NOTSUPP:   return B_UNSUPPORTED;
                // ...
                case NFS4ERR_DELAY:
                case NFS4ERR_DENIED:


Other related posts: