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;