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

  • From: pdziepak-github.nfs4 <community@xxxxxxxxxxxx>
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 15 Aug 2012 04:49:12 +0200 (CEST)

added 2 changesets to branch 'refs/remotes/pdziepak-github/nfs4'
old head: ff4d16ded4782a2967ffa2413761c078516b2ae6
new head: c0344ea198e280a3e8f23191262e2d7fffe9ff0c

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

70472e1: nfs4: Add basic emulation of named attributes

c0344ea: nfs4: Get correct change value for attribute directories

                                    [ Pawel Dziepak <pdziepak@xxxxxxxxxxx> ]

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

7 files changed, 176 insertions(+), 59 deletions(-)
.../kernel/file_systems/nfs4/DirectoryCache.cpp    |    2 +-
src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp  |   81 ++++++++++++--
.../kernel/file_systems/nfs4/InodeRegular.cpp      |   49 ++++++--
src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp |   92 ++++++++++------
src/add-ons/kernel/file_systems/nfs4/NFS4Inode.h   |    7 +-
src/add-ons/kernel/file_systems/nfs4/OpenState.cpp |    3 +-
.../kernel/file_systems/nfs4/ReplyInterpreter.cpp  |    1 +

############################################################################

Commit:      70472e11d37500a8cb434906f20254046bef0f5e

Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Wed Aug 15 02:11:25 2012 UTC

nfs4: Add basic emulation of named attributes

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

diff --git a/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp 
b/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp
index d78d28f..33e7822 100644
--- a/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp
+++ b/src/add-ons/kernel/file_systems/nfs4/InodeDir.cpp
@@ -62,22 +62,41 @@ Inode::OpenAttrDir(OpenDirCookie* cookie)
 status_t
 Inode::LoadAttrDirHandle()
 {
-       if (!fFileSystem->NamedAttrs())
-               return B_UNSUPPORTED;
+       if (fInfo.fAttrDir.fSize != 0)
+               return B_OK;
 
-       if (fInfo.fAttrDir.fSize == 0) {
-               FileHandle handle;
+       FileHandle handle;
+       status_t result;
+       if (!fFileSystem->NamedAttrs()) {
+               char* attrDir
+                       = reinterpret_cast<char*>(malloc(strlen(fInfo.fName) + 
32));
+               if (attrDir == NULL)
+                       return B_NO_MEMORY;
+               strcpy(attrDir, ".");
+               strcat(attrDir, fInfo.fName);
+               strcat(attrDir, "-haiku-attrs");
+
+               result = NFS4Inode::LookUp(attrDir, NULL, NULL, &handle, true);
+               if (result == B_ENTRY_NOT_FOUND) {
+                       ChangeInfo change;
+                       struct stat st;
+                       Stat(&st);
+                       st.st_mode |= S_IXUSR | S_IXGRP | S_IXOTH;
+                       result = NFS4Inode::CreateObject(attrDir, NULL, 
st.st_mode, NF4DIR,
+                               &change, NULL, &handle, true);
+               }
 
-               status_t result = NFS4Inode::OpenAttrDir(&handle);
+               free(attrDir);
+       } else {
+               result = NFS4Inode::OpenAttrDir(&handle);
                if (result == B_UNSUPPORTED)
                        fFileSystem->SetNamedAttrs(false);
-
-               if (result != B_OK)
-                       return result;
-
-               fInfo.fAttrDir = handle;
        }
 
+       if (result != B_OK)
+               return result;
+
+       fInfo.fAttrDir = handle;
        return B_OK;
 }
 
@@ -156,6 +175,31 @@ Inode::ReadDirUp(struct dirent* de, uint32 pos, uint32 
size)
 }
 
 
+static char*
+FileToAttrName(const char* path)
+{
+       char* name = strdup(path);
+       if (name == NULL)
+               return NULL;
+
+       char* current = strpbrk(name, "#$");
+       while (current != NULL) {
+               switch (*current) {
+                       case '#':
+                               *current = '/';
+                               break;
+                       case '$':
+                               *current = ':';
+                               break;
+               }
+               current = strpbrk(name, "#$");
+       }
+
+       return name;
+}
+
+
+
 status_t
 Inode::GetDirSnapshot(DirectoryCacheSnapshot** _snapshot,
        OpenDirCookie* cookie, uint64* _change, bool attribute)
@@ -189,6 +233,9 @@ Inode::GetDirSnapshot(DirectoryCacheSnapshot** _snapshot,
                        if (*fsid != fFileSystem->FsId())
                                continue;
 
+                       if (strstr(dirents[i].fName, "-haiku-attrs") != NULL)
+                               continue;
+
                        ino_t id;
                        if (!attribute) {
                                if (dirents[i].fAttrCount == 2)
@@ -198,7 +245,19 @@ Inode::GetDirSnapshot(DirectoryCacheSnapshot** _snapshot,
                        } else
                                id = 0;
        
-                       NameCacheEntry* entry = new 
NameCacheEntry(dirents[i].fName, id);
+                       const char* name = dirents[i].fName;
+                       if (attribute)
+                               name = FileToAttrName(name);
+                       if (name == NULL) {
+                               delete snapshot;
+                               delete[] dirents;
+                               return B_NO_MEMORY;
+                       }
+
+                       NameCacheEntry* entry = new NameCacheEntry(name, id);
+                       if (attribute)
+                               free(const_cast<char*>(name));
+
                        if (entry == NULL || entry->fName == NULL) {
                                if (entry->fName == NULL)
                                        delete entry;
diff --git a/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp 
b/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp
index 5490ee0..921d52a 100644
--- a/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp
+++ b/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp
@@ -11,6 +11,7 @@
 
 #include <string.h>
 
+#include <AutoDeleter.h>
 #include <fs_cache.h>
 #include <NodeMonitor.h>
 
@@ -192,9 +193,33 @@ Inode::Close(OpenFileCookie* cookie)
 }
 
 
+static char*
+AttrToFileName(const char* path)
+{
+       char* name = strdup(path);
+       if (name == NULL)
+               return NULL;
+
+       char* current = strpbrk(name, "/:");
+       while (current != NULL) {
+               switch (*current) {
+                       case '/':
+                               *current = '#';
+                               break;
+                       case ':':
+                               *current = '$';
+                               break;
+               }
+               current = strpbrk(name, "/:");
+       }
+
+       return name;
+}
+
+
 status_t
-Inode::OpenAttr(const char* name, int mode, OpenAttrCookie* cookie, bool 
create,
-       int32 type)
+Inode::OpenAttr(const char* _name, int mode, OpenAttrCookie* cookie,
+       bool create, int32 type)
 {
        (void)type;
 
@@ -202,6 +227,11 @@ Inode::OpenAttr(const char* name, int mode, 
OpenAttrCookie* cookie, bool create,
        if (result != B_OK)
                return result;
 
+       char* name = AttrToFileName(_name);
+       if (name == NULL)
+               return B_NO_MEMORY;
+       MemoryDeleter nameDeleter(name);
+
        OpenDelegationData data;
        data.fType = OPEN_DELEGATE_NONE;
 
@@ -209,8 +239,9 @@ Inode::OpenAttr(const char* name, int mode, OpenAttrCookie* 
cookie, bool create,
        if (state == NULL)
                return B_NO_MEMORY;
 
-       state->fInfo.fName = name;
+       state->fInfo.fName = strdup(name);
        state->fInfo.fParent = fInfo.fAttrDir;
+       state->fFileSystem = fFileSystem;
        result = NFS4Inode::OpenAttr(state, name, mode, &data, create);
        if (result != B_OK) {
                delete state;
@@ -225,8 +256,7 @@ Inode::OpenAttr(const char* name, int mode, OpenAttrCookie* 
cookie, bool create,
 
        if (data.fType != OPEN_DELEGATE_NONE) {
                Delegation* delegation
-                       = new(std::nothrow) Delegation(data, this, 
fOpenState->fClientID,
-                               true);
+                       = new(std::nothrow) Delegation(data, this, 
state->fClientID, true);
                if (delegation != NULL) {
                        delegation->fInfo = state->fInfo;
                        delegation->fFileSystem = fFileSystem;
@@ -235,7 +265,7 @@ Inode::OpenAttr(const char* name, int mode, OpenAttrCookie* 
cookie, bool create,
                }
        }
 
-       if ((mode & O_TRUNC) == O_TRUNC) {
+       if (create || (mode & O_TRUNC) == O_TRUNC) {
                struct stat st;
                st.st_size = 0;
                WriteStat(&st, B_STAT_SIZE, cookie);
@@ -248,8 +278,11 @@ Inode::OpenAttr(const char* name, int mode, 
OpenAttrCookie* cookie, bool create,
 status_t
 Inode::CloseAttr(OpenAttrCookie* cookie)
 {
-       cookie->fOpenState->fDelegation->GiveUp();
-       fFileSystem->RemoveDelegation(cookie->fOpenState->fDelegation);
+       if (cookie->fOpenState->fDelegation != NULL) {
+               cookie->fOpenState->fDelegation->GiveUp();
+               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 62a9acc..6f66c32 100644
--- a/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp
+++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp
@@ -107,17 +107,22 @@ NFS4Inode::Access(uint32* allowed)
 
 status_t
 NFS4Inode::LookUp(const char* name, uint64* change, uint64* fileID,
-       FileHandle* handle)
+       FileHandle* handle, bool parent)
 {
        do {
                RPC::Server* serv = fFileSystem->Server();
                Request request(serv);
                RequestBuilder& req = request.Builder();
 
-               req.PutFH(fInfo.fHandle);
+               if (parent)
+                       req.PutFH(fInfo.fParent);
+               else
+                       req.PutFH(fInfo.fHandle);
 
-               Attribute dirAttr[] = { FATTR4_CHANGE };
-               req.GetAttr(dirAttr, sizeof(dirAttr) / sizeof(Attribute));
+               if (change != NULL) {
+                       Attribute dirAttr[] = { FATTR4_CHANGE };
+                       req.GetAttr(dirAttr, sizeof(dirAttr) / 
sizeof(Attribute));
+               }
 
                if (!strcmp(name, ".."))
                        req.LookUpUp();
@@ -142,12 +147,14 @@ NFS4Inode::LookUp(const char* name, uint64* change, 
uint64* fileID,
 
                AttrValue* values;
                uint32 count;
-               result = reply.GetAttr(&values, &count);
-               if (result != B_OK)
-                       return result;
+               if (change != NULL) {
+                       result = reply.GetAttr(&values, &count);
+                       if (result != B_OK)
+                               return result;
 
-               *change = values[0].fData.fValue64;
-               delete[] values;
+                       *change = values[0].fData.fValue64;
+                       delete[] values;
+               }
 
                if (!strcmp(name, ".."))
                        result = reply.LookUpUp();
@@ -170,10 +177,13 @@ NFS4Inode::LookUp(const char* name, uint64* change, 
uint64* fileID,
                        return B_ENTRY_NOT_FOUND;
                }
 
-               if (count < 2 || values[1].fAttribute != FATTR4_FILEID)
-                       *fileID = fFileSystem->AllocFileId();
-               else
-                       *fileID = values[1].fData.fValue64;
+               if (fileID != NULL) {
+                       if (count < 2 || values[1].fAttribute != FATTR4_FILEID)
+                               *fileID = fFileSystem->AllocFileId();
+                       else
+                               *fileID = values[1].fData.fValue64;
+               }
+
                delete[] values;
 
                return B_OK;
@@ -536,11 +546,11 @@ NFS4Inode::OpenFile(OpenState* state, int mode, 
OpenDelegationData* delegation)
 
                ReplyInterpreter& reply = request.Reply();
 
+               sequence += IncrementSequence(reply.NFS4Error());
+
                if (HandleErrors(reply.NFS4Error(), serv, NULL, state, 
&sequence))
                        continue;
 
-               sequence += IncrementSequence(reply.NFS4Error());
-
                // Verify if the file we want to open is the file this Inode
                // represents.
                if (fFileSystem->IsAttrSupported(FATTR4_FILEID) ||
@@ -617,11 +627,11 @@ NFS4Inode::OpenAttr(OpenState* state, const char* name, 
int mode,
 
                ReplyInterpreter& reply = request.Reply();
 
-               if (HandleErrors(reply.NFS4Error(), serv, NULL, state))
-                       continue;
-
                sequence += IncrementSequence(reply.NFS4Error());
 
+               if (HandleErrors(reply.NFS4Error(), serv, NULL, state, 
&sequence))
+                       continue;
+
                reply.PutFH();
                result = reply.Open(state->fStateID, &state->fStateSeq, 
&confirm,
                        delegation);
@@ -639,7 +649,7 @@ NFS4Inode::OpenAttr(OpenState* state, const char* name, int 
mode,
        state->fOpened = true;
 
        if (confirm)
-               result = ConfirmOpen(fInfo.fHandle, state, &sequence);
+               result = ConfirmOpen(state->fInfo.fHandle, state, &sequence);
 
        fFileSystem->OpenOwnerSequenceUnlock(sequence);
        return result;
@@ -714,14 +724,18 @@ NFS4Inode::WriteFile(OpenStateCookie* cookie, OpenState* 
state, uint64 position,
 
 status_t
 NFS4Inode::CreateObject(const char* name, const char* path, int mode,
-       FileType type, ChangeInfo* changeInfo, uint64* fileID, FileHandle* 
handle)
+       FileType type, ChangeInfo* changeInfo, uint64* fileID, FileHandle* 
handle,
+       bool parent)
 {
        do {
                RPC::Server* serv = fFileSystem->Server();
                Request request(serv);
                RequestBuilder& req = request.Builder();
 
-               req.PutFH(fInfo.fHandle);
+               if (parent)
+                       req.PutFH(fInfo.fParent);
+               else
+                       req.PutFH(fInfo.fHandle);
 
                uint32 i = 0;
                AttrValue cattr[1];
@@ -742,8 +756,11 @@ NFS4Inode::CreateObject(const char* name, const char* 
path, int mode,
                }
 
                req.GetFH();
-               Attribute attr[] = { FATTR4_FILEID };
-               req.GetAttr(attr, sizeof(attr) / sizeof(Attribute));
+
+               if (fileID != NULL) {
+                       Attribute attr[] = { FATTR4_FILEID };
+                       req.GetAttr(attr, sizeof(attr) / sizeof(Attribute));
+               }
 
                status_t result = request.Send();
                if (result != B_OK)
@@ -764,18 +781,20 @@ NFS4Inode::CreateObject(const char* name, const char* 
path, int mode,
                if (result != B_OK)
                        return result;
 
-               AttrValue* values;
-               uint32 count;
-               result = reply.GetAttr(&values, &count);
-               if (result != B_OK)
-                       return result;
+               if (fileID != NULL) {
+                       AttrValue* values;
+                       uint32 count;
+                       result = reply.GetAttr(&values, &count);
+                       if (result != B_OK)
+                               return result;
 
-               if (count == 0)
-                       *fileID = fFileSystem->AllocFileId();
-               else
-                       *fileID = values[0].fData.fValue64;
+                       if (count == 0)
+                               *fileID = fFileSystem->AllocFileId();
+                       else
+                               *fileID = values[0].fData.fValue64;
 
-               delete[] values;
+                       delete[] values;
+               }
 
                return B_OK;
        } while (true);
diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.h 
b/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.h
index 110cce7..fcb1090 100644
--- a/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.h
+++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.h
@@ -31,7 +31,7 @@ protected:
                        status_t        CommitWrites();
 
                        status_t        LookUp(const char* name, uint64* 
change, uint64* fileID,
-                                                       FileHandle* handle);
+                                                       FileHandle* handle, 
bool parent = false);
 
                        status_t        Link(Inode* dir, const char* name,
                                                        ChangeInfo* changeInfo);
@@ -65,7 +65,8 @@ protected:
 
                        status_t        CreateObject(const char* name, const 
char* path,
                                                        int mode, FileType 
type, ChangeInfo* changeInfo,
-                                                       uint64* fileID, 
FileHandle* handle);
+                                                       uint64* fileID, 
FileHandle* handle,
+                                                       bool parent = false);
                        status_t        RemoveObject(const char* name, FileType 
type,
                                                        ChangeInfo* changeInfo, 
uint64* fileID);
 
diff --git a/src/add-ons/kernel/file_systems/nfs4/OpenState.cpp 
b/src/add-ons/kernel/file_systems/nfs4/OpenState.cpp
index b311ceb..7de9b42 100644
--- a/src/add-ons/kernel/file_systems/nfs4/OpenState.cpp
+++ b/src/add-ons/kernel/file_systems/nfs4/OpenState.cpp
@@ -32,7 +32,8 @@ OpenState::OpenState()
 
 OpenState::~OpenState()
 {
-       fFileSystem->RemoveOpenFile(this);
+       if (fOpened)
+               fFileSystem->RemoveOpenFile(this);
        Close();
 
        mutex_destroy(&fLock);
diff --git a/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp 
b/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp
index 5812827..6f04552 100644
--- a/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp
+++ b/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp
@@ -34,6 +34,7 @@ FSLocations::~FSLocations()
 
 AttrValue::AttrValue()
        :
+       fAttribute(0),
        fFreePointer(false)
 {
 }

############################################################################

Commit:      c0344ea198e280a3e8f23191262e2d7fffe9ff0c

Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Wed Aug 15 02:22:18 2012 UTC

nfs4: Get correct change value for attribute directories

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

diff --git a/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp 
b/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp
index e7062c0..325a764 100644
--- a/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp
+++ b/src/add-ons/kernel/file_systems/nfs4/DirectoryCache.cpp
@@ -179,7 +179,7 @@ status_t
 DirectoryCache::Revalidate()
 {
        uint64 change;
-       if (fInode->GetChangeInfo(&change) == B_OK && change == fChange) {
+       if (fInode->GetChangeInfo(&change, true) == B_OK && change == fChange) {
                fExpireTime = system_time() + kExpirationTime;
                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 6f66c32..145c50f 100644
--- a/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp
+++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp
@@ -14,14 +14,17 @@
 
 
 status_t
-NFS4Inode::GetChangeInfo(uint64* change)
+NFS4Inode::GetChangeInfo(uint64* change, bool attrDir)
 {
        do {
                RPC::Server* serv = fFileSystem->Server();
                Request request(serv);
                RequestBuilder& req = request.Builder();
 
-               req.PutFH(fInfo.fHandle);
+               if (attrDir)
+                       req.PutFH(fInfo.fAttrDir);
+               else
+                       req.PutFH(fInfo.fHandle);
 
                Attribute attr[] = { FATTR4_CHANGE };
                req.GetAttr(attr, sizeof(attr) / sizeof(Attribute));
diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.h 
b/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.h
index fcb1090..62db373 100644
--- a/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.h
+++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.h
@@ -22,7 +22,7 @@
 
 class NFS4Inode : protected NFS4Object {
 public:
-                       status_t        GetChangeInfo(uint64* change);
+                       status_t        GetChangeInfo(uint64* change, bool 
attrDir = false);
                        status_t        ReadLink(void* buffer, size_t* length);
 
 protected:


Other related posts: