[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, 27 Jul 2012 03:49:13 +0200 (CEST)

added 3 changesets to branch 'refs/remotes/pdziepak-github/nfs4'
old head: b5162ff580a35f428ca39bd8beb1c2711c9b820f
new head: 36577ed54ba11c2e9b1a61f66cc2a704e2af7697

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

0bc98af: nfs4: Basic data cache implementation

be4499d: nfs4: Change write policy from write through to write back

36577ed: nfs4: Use unstable writes and commit before close

                                    [ Pawel Dziepak <pdziepak@xxxxxxxxxxx> ]

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

11 files changed, 252 insertions(+), 36 deletions(-)
src/add-ons/kernel/file_systems/nfs4/Inode.cpp     |   29 +++-
src/add-ons/kernel/file_systems/nfs4/Inode.h       |   14 +-
.../kernel/file_systems/nfs4/InodeRegular.cpp      |   39 ++++-
src/add-ons/kernel/file_systems/nfs4/NFS4Defs.h    |    1 +
.../kernel/file_systems/nfs4/ReplyInterpreter.cpp  |   13 ++
.../kernel/file_systems/nfs4/ReplyInterpreter.h    |    1 +
.../kernel/file_systems/nfs4/RequestBuilder.cpp    |   20 ++-
.../kernel/file_systems/nfs4/RequestBuilder.h      |    1 +
src/add-ons/kernel/file_systems/nfs4/RootInode.cpp |   22 +--
src/add-ons/kernel/file_systems/nfs4/RootInode.h   |   13 ++
.../kernel/file_systems/nfs4/kernel_interface.cpp  |  135 ++++++++++++++--

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

Commit:      0bc98afd433d6b193773d937c06048b4ade01cd6

Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Thu Jul 26 23:53:54 2012 UTC

nfs4: Basic data cache implementation

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

diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp 
b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp
index b87792e..607df77 100644
--- a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp
+++ b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp
@@ -12,6 +12,7 @@
 #include <ctype.h>
 #include <string.h>
 
+#include <fs_cache.h>
 #include <NodeMonitor.h>
 
 #include "IdMap.h"
@@ -22,7 +23,8 @@
 Inode::Inode()
        :
        fAttrCacheExpire(0),
-       fCache(NULL)
+       fCache(NULL),
+       fFileCache(NULL)
 {
        mutex_init(&fAttrCacheLock, NULL);
 }
@@ -43,6 +45,7 @@ Inode::CreateInode(FileSystem* fs, const FileInfo &fi, 
Inode** _inode)
        inode->fInfo = fi;
        inode->fFileSystem = fs;
 
+       uint64 size;
        do {
                RPC::Server* serv = fs->Server();
                Request request(serv);
@@ -50,7 +53,8 @@ Inode::CreateInode(FileSystem* fs, const FileInfo &fi, 
Inode** _inode)
 
                req.PutFH(inode->fInfo.fHandle);
 
-               Attribute attr[] = { FATTR4_TYPE, FATTR4_FSID, FATTR4_FILEID };
+               Attribute attr[] = { FATTR4_TYPE, FATTR4_SIZE, FATTR4_FSID,
+                       FATTR4_FILEID };
                req.GetAttr(attr, sizeof(attr) / sizeof(Attribute));
 
                status_t result = request.Send();
@@ -67,14 +71,14 @@ Inode::CreateInode(FileSystem* fs, const FileInfo &fi, 
Inode** _inode)
                AttrValue* values;
                uint32 count;
                result = reply.GetAttr(&values, &count);
-               if (result != B_OK || count < 2)
+               if (result != B_OK || count < 3)
                        return result;
 
                if (fi.fFileId == 0) {
-                       if (count < 3 || values[2].fAttribute != FATTR4_FILEID)
+                       if (count < 4 || values[3].fAttribute != FATTR4_FILEID)
                                inode->fInfo.fFileId = fs->AllocFileId();
                        else
-                               inode->fInfo.fFileId = values[2].fData.fValue64;
+                               inode->fInfo.fFileId = values[3].fData.fValue64;
                } else
                        inode->fInfo.fFileId = fi.fFileId;
 
@@ -84,9 +88,12 @@ Inode::CreateInode(FileSystem* fs, const FileInfo &fi, 
Inode** _inode)
                if (inode->fType == NF4DIR)
                        inode->fCache = new DirectoryCache(inode);
 
+               // FATTR4_SIZE is mandatory
+               size = values[1].fData.fValue64;
+
                // FATTR4_FSID is mandatory
                FileSystemId* fsid =
-                       
reinterpret_cast<FileSystemId*>(values[1].fData.fPointer);
+                       
reinterpret_cast<FileSystemId*>(values[2].fData.fPointer);
                if (*fsid != fs->FsId()) {
                        delete[] values;
                        return B_ENTRY_NOT_FOUND;
@@ -96,13 +103,21 @@ Inode::CreateInode(FileSystem* fs, const FileInfo &fi, 
Inode** _inode)
 
                *_inode = inode;
 
-               return B_OK;
+               break;
        } while (true);
+
+       if (inode->fType == NF4REG)
+               inode->fFileCache = file_cache_create(fs->DevId(), inode->ID(), 
size);
+
+       return B_OK;
 }
 
 
 Inode::~Inode()
 {
+       if (fFileCache != NULL)
+               file_cache_delete(fFileCache);
+
        delete fCache;
        mutex_destroy(&fAttrCacheLock);
 }
diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.h 
b/src/add-ons/kernel/file_systems/nfs4/Inode.h
index 6a7a584..110efa8 100644
--- a/src/add-ons/kernel/file_systems/nfs4/Inode.h
+++ b/src/add-ons/kernel/file_systems/nfs4/Inode.h
@@ -30,6 +30,8 @@ public:
        inline                  const char*     Name() const;
        inline                  FileSystem*     GetFileSystem() const;
 
+       inline                  void*           FileCache();
+
                                        status_t        GetChangeInfo(uint64* 
change);
 
                                        status_t        LookUp(const char* 
name, ino_t* id);
@@ -52,7 +54,7 @@ public:
                                        status_t        Open(int mode, 
OpenFileCookie* cookie);
                                        status_t        Close(OpenFileCookie* 
cookie);
                                        status_t        Read(OpenFileCookie* 
cookie, off_t pos,
-                                                                       void* 
buffer, size_t* length);
+                                                                       void* 
buffer, size_t* length, bool* eof);
                                        status_t        Write(OpenFileCookie* 
cookie, off_t pos,
                                                                        const 
void* buffer, size_t *_length);
 
@@ -111,6 +113,7 @@ protected:
                                        FileSystem*     fFileSystem;
 
                                        DirectoryCache* fCache;
+                                       void*           fFileCache;
 };
 
 
@@ -153,5 +156,12 @@ Inode::GetFileSystem() const
 }
 
 
+inline void*
+Inode::FileCache()
+{
+       return fFileCache;
+}
+
+
 #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 ace10fa..f6718f1 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 <fs_cache.h>
 #include <NodeMonitor.h>
 
 #include "IdMap.h"
@@ -330,13 +331,14 @@ Inode::Close(OpenFileCookie* cookie)
 
 
 status_t
-Inode::Read(OpenFileCookie* cookie, off_t pos, void* buffer, size_t* _length)
+Inode::Read(OpenFileCookie* cookie, off_t pos, void* buffer, size_t* _length,
+       bool* eof)
 {
-       bool eof = false;
+       *eof = false;
        uint32 size = 0;
        uint32 len = 0;
 
-       while (size < *_length && !eof) {
+       while (size < *_length && !*eof) {
                do {
                        RPC::Server* serv = fFileSystem->Server();
                        Request request(serv);
@@ -357,7 +359,7 @@ Inode::Read(OpenFileCookie* cookie, off_t pos, void* 
buffer, size_t* _length)
 
                        reply.PutFH();
                        result = reply.Read(reinterpret_cast<char*>(buffer) + 
size, &len,
-                                               &eof);
+                                               eof);
                        if (result != B_OK)
                                return result;
 
diff --git a/src/add-ons/kernel/file_systems/nfs4/RootInode.cpp 
b/src/add-ons/kernel/file_systems/nfs4/RootInode.cpp
index 82a0340..6d99f30 100644
--- a/src/add-ons/kernel/file_systems/nfs4/RootInode.cpp
+++ b/src/add-ons/kernel/file_systems/nfs4/RootInode.cpp
@@ -16,7 +16,8 @@
 
 RootInode::RootInode()
        :
-       fInfoCacheExpire(0)
+       fInfoCacheExpire(0),
+       fIOSize(0)
 {
        mutex_init(&fInfoCacheLock, NULL);
 }
@@ -90,29 +91,30 @@ RootInode::_UpdateInfo(bool force)
                        next++;
                }
 
-               uint64 io_size = LONGLONG_MAX;
+               uint64 ioSize = LONGLONG_MAX;
                if (count >= next && values[next].fAttribute == FATTR4_MAXREAD) 
{
-                       io_size = min_c(io_size, values[next].fData.fValue64);
+                       ioSize = min_c(ioSize, values[next].fData.fValue64);
                        next++;
                }
 
                if (count >= next && values[next].fAttribute == 
FATTR4_MAXWRITE) {
-                       io_size = min_c(io_size, values[next].fData.fValue64);
+                       ioSize = min_c(ioSize, values[next].fData.fValue64);
                        next++;
                }
 
-               if (io_size == LONGLONG_MAX)
-                       io_size = 32768;
-               fInfoCache.io_size = io_size;
-               fInfoCache.block_size = io_size;
+               if (ioSize == LONGLONG_MAX)
+                       ioSize = 32768;
+               fInfoCache.io_size = ioSize;
+               fInfoCache.block_size = ioSize;
+               fIOSize = ioSize;
 
                if (count >= next && values[next].fAttribute == 
FATTR4_SPACE_FREE) {
-                       fInfoCache.free_blocks = values[next].fData.fValue64 / 
io_size;
+                       fInfoCache.free_blocks = values[next].fData.fValue64 / 
ioSize;
                        next++;
                }
 
                if (count >= next && values[next].fAttribute == 
FATTR4_SPACE_TOTAL) {
-                       fInfoCache.total_blocks = values[next].fData.fValue64 / 
io_size;
+                       fInfoCache.total_blocks = values[next].fData.fValue64 / 
ioSize;
                        next++;
                }
 
diff --git a/src/add-ons/kernel/file_systems/nfs4/RootInode.h 
b/src/add-ons/kernel/file_systems/nfs4/RootInode.h
index 5b01b89..864d49d 100644
--- a/src/add-ons/kernel/file_systems/nfs4/RootInode.h
+++ b/src/add-ons/kernel/file_systems/nfs4/RootInode.h
@@ -22,6 +22,8 @@ public:
                        status_t                        ReadInfo(struct 
fs_info* info);
        inline  void                            MakeInfoInvalid();
 
+       inline  uint32                          IOSize();
+
                        bool                            ProbeMigration();
                        status_t                        
GetLocations(AttrValue** attr);
 
@@ -30,6 +32,8 @@ private:
                        mutex                           fInfoCacheLock;
                        time_t                          fInfoCacheExpire;
 
+                       uint32                          fIOSize;
+
                        status_t                        _UpdateInfo(bool force 
= false);
 
 };
@@ -42,5 +46,14 @@ RootInode::MakeInfoInvalid()
 }
 
 
+inline uint32
+RootInode::IOSize()
+{
+       if (fIOSize == 0)
+               _UpdateInfo(true);
+       return fIOSize;
+}
+
+
 #endif // ROOTINODE_H
 
diff --git a/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp 
b/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp
index fdd79f3..391b57d 100644
--- a/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp
+++ b/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp
@@ -9,6 +9,7 @@
 
 #include <stdio.h>
 
+#include <fs_cache.h>
 #include <fs_interface.h>
 
 #include "Connection.h"
@@ -213,6 +214,59 @@ nfs4_remove_vnode(fs_volume* volume, fs_vnode* vnode, bool 
reenter)
 
 
 static status_t
+nfs4_read_pages(fs_volume* _volume, fs_vnode* vnode, void* _cookie, off_t pos,
+       const iovec* vecs, size_t count, size_t* _numBytes)
+{
+       Inode* inode = reinterpret_cast<Inode*>(vnode->private_node);
+       OpenFileCookie* cookie = reinterpret_cast<OpenFileCookie*>(_cookie);
+
+       status_t result;
+       bool eof = false;
+       for (size_t i = 0; i < count && !eof; i++) {
+               size_t bytesLeft = vecs[i].iov_len;
+               char* buffer = reinterpret_cast<char*>(vecs[i].iov_base);
+
+               do {
+                       size_t bytesRead = bytesLeft;
+                       result = inode->Read(cookie, pos, buffer, &bytesRead, 
&eof);
+                       if (result != B_OK)
+                               return result;
+
+                       pos += bytesRead;
+                       buffer += bytesRead;
+                       bytesLeft -= bytesRead;
+               } while (bytesLeft > 0 && !eof);
+       }
+
+       return B_OK;
+}
+
+
+static status_t
+nfs4_write_pages(fs_volume* _volume, fs_vnode* vnode, void* _cookie, off_t pos,
+       const iovec* vecs, size_t count, size_t* _numBytes)
+{
+       return B_OK;
+}
+
+
+static status_t
+nfs4_io(fs_volume* volume, fs_vnode* vnode, void* cookie, io_request* request)
+{
+       // no asynchronous calls yet
+       return B_UNSUPPORTED;
+}
+
+
+static status_t
+nfs4_get_file_map(fs_volume* volume, fs_vnode* vnode, off_t _offset,
+       size_t size, struct file_io_vec* vecs, size_t* _count)
+{
+       return B_ERROR;
+}
+
+
+static status_t
 nfs4_set_flags(fs_volume* volume, fs_vnode* vnode, void* _cookie, int flags)
 {
        OpenFileCookie* cookie = reinterpret_cast<OpenFileCookie*>(_cookie);
@@ -224,7 +278,7 @@ nfs4_set_flags(fs_volume* volume, fs_vnode* vnode, void* 
_cookie, int flags)
 static status_t
 nfs4_fsync(fs_volume* volume, fs_vnode* vnode)
 {
-       // Currently, there is no cache and all writes are FILE_SYNC4
+       // Currently all writes are FILE_SYNC4
        return B_OK;
 }
 
@@ -378,7 +432,7 @@ nfs4_free_cookie(fs_volume* volume, fs_vnode* vnode, void* 
_cookie)
 
 
 static status_t
-nfs4_read(fs_volume* volume, fs_vnode* vnode, void* _cookie, off_t pos,
+nfs4_read(fs_volume* volume, fs_vnode* vnode, void* cookie, off_t pos,
        void* buffer, size_t* length)
 {
        Inode* inode = reinterpret_cast<Inode*>(vnode->private_node);
@@ -389,15 +443,13 @@ nfs4_read(fs_volume* volume, fs_vnode* vnode, void* 
_cookie, off_t pos,
        if (inode->Type() == S_IFLNK)
                return B_BAD_VALUE;
 
-       OpenFileCookie* cookie = reinterpret_cast<OpenFileCookie*>(_cookie);
-
-       return inode->Read(cookie, pos, buffer, length);
+       return file_cache_read(inode->FileCache(), cookie, pos, buffer, length);
 }
 
 
 static status_t
 nfs4_write(fs_volume* volume, fs_vnode* vnode, void* _cookie, off_t pos,
-       const void* buffer, size_t* length)
+       const void* _buffer, size_t* length)
 {
        Inode* inode = reinterpret_cast<Inode*>(vnode->private_node);
 
@@ -409,7 +461,40 @@ nfs4_write(fs_volume* volume, fs_vnode* vnode, void* 
_cookie, off_t pos,
 
        OpenFileCookie* cookie = reinterpret_cast<OpenFileCookie*>(_cookie);
 
-       return inode->Write(cookie, pos, buffer, length);
+       struct stat stat;
+       status_t result = inode->Stat(&stat);
+       if (result != B_OK)
+               return result;
+
+       uint64 fileSize = max_c(stat.st_size, pos + *length);
+       result = file_cache_set_size(inode->FileCache(), fileSize);
+       if (result != B_OK)
+               return result;
+
+       result = file_cache_write(inode->FileCache(), cookie, pos, _buffer,
+               length);
+       if (result != B_OK)
+               return result;
+
+       uint32 ioSize = inode->GetFileSystem()->Root()->IOSize();
+       size_t bytesLeft = *length;
+       const char* buffer = reinterpret_cast<const char*>(_buffer);
+       do {
+               size_t bytesWritten = min_c(ioSize, bytesLeft);
+               result = inode->Write(cookie, pos, buffer, &bytesWritten);
+               if (result != B_OK)
+                       break;
+
+               bytesLeft -= bytesWritten;
+               pos += bytesWritten;
+               buffer += bytesWritten;
+       } while (bytesLeft > 0);
+
+       if (bytesLeft == *length)
+               return result;
+
+       *length = *length - bytesLeft;
+       return B_OK;
 }
 
 
@@ -582,13 +667,13 @@ fs_vnode_ops gNFSv4VnodeOps = {
 
        /* VM file access */
        NULL,   // can_page()
-       NULL,   // read_pages()
-       NULL,   // write_pages()
+       nfs4_read_pages,
+       nfs4_write_pages,
 
-       NULL,   // io()
+       nfs4_io,
        NULL,   // cancel_io()
 
-       NULL,   // get_file_map()
+       nfs4_get_file_map,
 
        NULL,   // ioctl()
        nfs4_set_flags,

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

Commit:      be4499d19e0c76b87912cd497d945374dc84e294

Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Fri Jul 27 00:23:40 2012 UTC

nfs4: Change write policy from write through to write back

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

diff --git a/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp 
b/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp
index f6718f1..c55210d 100644
--- a/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp
+++ b/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp
@@ -323,7 +323,7 @@ Inode::Close(OpenFileCookie* cookie)
                if (result != B_OK)
                        return result;
 
-               return B_OK;
+               break;
        } while (true);
 
        return B_OK;
@@ -450,6 +450,7 @@ Inode::Write(OpenFileCookie* cookie, off_t pos, const void* 
_buffer,
 
        *_length = size;
 
+       fAttrCache.st_size = max_c(fAttrCache.st_size, *_length + pos);
        fFileSystem->Root()->MakeInfoInvalid();
 
        return B_OK;
diff --git a/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp 
b/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp
index 391b57d..15c0d00 100644
--- a/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp
+++ b/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp
@@ -246,6 +246,53 @@ static status_t
 nfs4_write_pages(fs_volume* _volume, fs_vnode* vnode, void* _cookie, off_t pos,
        const iovec* vecs, size_t count, size_t* _numBytes)
 {
+       Inode* inode = reinterpret_cast<Inode*>(vnode->private_node);
+       bool freeCookie = false;
+       OpenFileCookie* cookie = reinterpret_cast<OpenFileCookie*>(_cookie);
+
+       if (cookie == NULL) {
+               cookie = new OpenFileCookie;
+               if (cookie == NULL)
+                       return B_NO_MEMORY;
+
+               status_t result = inode->Open(O_WRONLY, cookie);
+               if (result != B_OK) {
+                       delete cookie;
+                       return result;
+               }
+
+               freeCookie = true;
+       }
+
+       status_t result;
+       uint32 ioSize = inode->GetFileSystem()->Root()->IOSize();
+       for (size_t i = 0; i < count; i++) {
+               size_t bytesLeft = vecs[i].iov_len;
+               char* buffer = reinterpret_cast<char*>(vecs[i].iov_base);
+
+               do {
+                       size_t bytesWritten = min_c(ioSize, bytesLeft);
+
+                       result = inode->Write(cookie, pos, buffer, 
&bytesWritten);
+                       if (result != B_OK) {
+                               if (freeCookie) {
+                                       inode->Close(cookie);
+                                       delete cookie;
+                               }
+                               return result;
+                       }
+
+                       bytesLeft -= bytesWritten;
+                       pos += bytesWritten;
+                       buffer += bytesWritten;
+               } while (bytesLeft > 0);
+       }
+
+       if (freeCookie) {
+               inode->Close(cookie);
+               delete cookie;
+       }
+
        return B_OK;
 }
 
@@ -278,8 +325,8 @@ nfs4_set_flags(fs_volume* volume, fs_vnode* vnode, void* 
_cookie, int flags)
 static status_t
 nfs4_fsync(fs_volume* volume, fs_vnode* vnode)
 {
-       // Currently all writes are FILE_SYNC4
-       return B_OK;
+       Inode* inode = reinterpret_cast<Inode*>(vnode->private_node);
+       return file_cache_sync(inode->FileCache());
 }
 
 
@@ -424,6 +471,7 @@ nfs4_free_cookie(fs_volume* volume, fs_vnode* vnode, void* 
_cookie)
                return B_OK;
 
        OpenFileCookie* cookie = reinterpret_cast<OpenFileCookie*>(_cookie);
+       file_cache_sync(inode->FileCache());
        inode->Close(cookie);
        delete cookie;
 
@@ -471,30 +519,7 @@ nfs4_write(fs_volume* volume, fs_vnode* vnode, void* 
_cookie, off_t pos,
        if (result != B_OK)
                return result;
 
-       result = file_cache_write(inode->FileCache(), cookie, pos, _buffer,
-               length);
-       if (result != B_OK)
-               return result;
-
-       uint32 ioSize = inode->GetFileSystem()->Root()->IOSize();
-       size_t bytesLeft = *length;
-       const char* buffer = reinterpret_cast<const char*>(_buffer);
-       do {
-               size_t bytesWritten = min_c(ioSize, bytesLeft);
-               result = inode->Write(cookie, pos, buffer, &bytesWritten);
-               if (result != B_OK)
-                       break;
-
-               bytesLeft -= bytesWritten;
-               pos += bytesWritten;
-               buffer += bytesWritten;
-       } while (bytesLeft > 0);
-
-       if (bytesLeft == *length)
-               return result;
-
-       *length = *length - bytesLeft;
-       return B_OK;
+       return file_cache_write(inode->FileCache(), cookie, pos, _buffer, 
length);
 }
 
 

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

Commit:      36577ed54ba11c2e9b1a61f66cc2a704e2af7697

Author:      Pawel Dziepak <pdziepak@xxxxxxxxxxx>
Date:        Fri Jul 27 01:08:46 2012 UTC

nfs4: Use unstable writes and commit before close

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

diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.h 
b/src/add-ons/kernel/file_systems/nfs4/Inode.h
index 110efa8..692bfec 100644
--- a/src/add-ons/kernel/file_systems/nfs4/Inode.h
+++ b/src/add-ons/kernel/file_systems/nfs4/Inode.h
@@ -34,6 +34,8 @@ public:
 
                                        status_t        GetChangeInfo(uint64* 
change);
 
+                                       status_t        Commit();
+
                                        status_t        LookUp(const char* 
name, ino_t* id);
 
                                        status_t        CreateLink(const char* 
name, const char* path,
diff --git a/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp 
b/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp
index c55210d..c1f6bf8 100644
--- a/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp
+++ b/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp
@@ -456,3 +456,29 @@ Inode::Write(OpenFileCookie* cookie, off_t pos, const 
void* _buffer,
        return B_OK;
 }
 
+
+status_t
+Inode::Commit()
+{
+       do {
+               RPC::Server* serv = fFileSystem->Server();
+               Request request(serv);
+               RequestBuilder& req = request.Builder();
+
+               req.PutFH(fInfo.fHandle);
+               req.Commit(0, 0);
+
+               status_t result = request.Send();
+               if (result != B_OK)
+                       return result;
+
+               ReplyInterpreter& reply = request.Reply();
+
+               if (_HandleErrors(reply.NFS4Error(), serv))
+                       continue;
+
+               reply.PutFH();
+               return reply.Commit();
+       } while (true);
+}
+
diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Defs.h 
b/src/add-ons/kernel/file_systems/nfs4/NFS4Defs.h
index 31e82c2..8ba791d 100644
--- a/src/add-ons/kernel/file_systems/nfs4/NFS4Defs.h
+++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Defs.h
@@ -23,6 +23,7 @@ enum Procedure {
 enum Opcode {
        OpAccess                                = 3,
        OpClose                                 = 4,
+       OpCommit                                = 5,
        OpCreate                                = 6,
        OpGetAttr                               = 9,
        OpGetFH                                 = 10,
diff --git a/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp 
b/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp
index 0fdf732..56ba582 100644
--- a/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp
+++ b/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp
@@ -126,6 +126,19 @@ ReplyInterpreter::Close()
 
 
 status_t
+ReplyInterpreter::Commit()
+{
+       status_t res = _OperationError(OpCommit);
+       if (res != B_OK)
+               return res;
+
+       fReply->Stream().GetOpaque(NULL);
+
+       return fReply->Stream().IsEOF() ? B_BAD_VALUE : B_OK;
+}
+
+
+status_t
 ReplyInterpreter::Create(uint64* before, uint64* after, bool& atomic)
 {
        status_t res = _OperationError(OpCreate);
diff --git a/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.h 
b/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.h
index 27a60d7..ed3a269 100644
--- a/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.h
+++ b/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.h
@@ -69,6 +69,7 @@ public:
 
                        status_t        Access(uint32* supported, uint32* 
allowed);
                        status_t        Close();
+                       status_t        Commit();
                        status_t        Create(uint64* before, uint64* after, 
bool& atomic);
                        status_t        GetAttr(AttrValue** attrs, uint32* 
count);
                        status_t        GetFH(FileHandle* fh);
diff --git a/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.cpp 
b/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.cpp
index 738f854..d4b676c 100644
--- a/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.cpp
+++ b/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.cpp
@@ -90,6 +90,24 @@ RequestBuilder::Close(uint32 seq, const uint32* id, uint32 
stateSeq)
 
 
 status_t
+RequestBuilder::Commit(uint64 offset, uint32 count)
+{
+       if (fProcedure != ProcCompound)
+               return B_BAD_VALUE;
+       if (fRequest == NULL)
+               return B_NO_MEMORY;
+
+       fRequest->Stream().AddUInt(OpCommit);
+       fRequest->Stream().AddUHyper(offset);
+       fRequest->Stream().AddUInt(count);
+
+       fOpCount++;
+
+       return B_OK;
+}
+
+
+status_t
 RequestBuilder::Create(FileType type, const char* name, AttrValue* attr,
        uint32 count, const char* path)
 {
@@ -729,7 +747,7 @@ RequestBuilder::Write(const uint32* id, uint32 stateSeq, 
const void* buffer,
        fRequest->Stream().AddUInt(id[1]);
        fRequest->Stream().AddUInt(id[2]);
        fRequest->Stream().AddUHyper(pos);
-       fRequest->Stream().AddInt(FILE_SYNC4);
+       fRequest->Stream().AddInt(UNSTABLE4);
        fRequest->Stream().AddOpaque(buffer, len);
 
        fOpCount++;
diff --git a/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.h 
b/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.h
index 17800c9..b3b7998 100644
--- a/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.h
+++ b/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.h
@@ -33,6 +33,7 @@ public:
                        status_t                                Access();
                        status_t                                Close(uint32 
seq, const uint32* id,
                                                                                
uint32 stateSeq);
+                       status_t                                Commit(uint64 
offset, uint32 count);
                        status_t                                Create(FileType 
type, const char* name,
                                                                                
AttrValue* attr, uint32 count,
                                                                                
const char* path = NULL);
diff --git a/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp 
b/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp
index 15c0d00..b1d0bd6 100644
--- a/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp
+++ b/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp
@@ -472,6 +472,7 @@ nfs4_free_cookie(fs_volume* volume, fs_vnode* vnode, void* 
_cookie)
 
        OpenFileCookie* cookie = reinterpret_cast<OpenFileCookie*>(_cookie);
        file_cache_sync(inode->FileCache());
+       inode->Commit();
        inode->Close(cookie);
        delete cookie;
 


Other related posts: