diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.h b/src/add-ons/kernel/file_systems/nfs4/Inode.h index 110efa83bf..692bfec298 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 c55210d7ce..c1f6bf86ab 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 31e82c2670..8ba791de2a 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 0fdf732f0b..56ba582894 100644 --- a/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp @@ -125,6 +125,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) { diff --git a/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.h b/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.h index 27a60d73b4..ed3a2695a1 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 738f854d75..d4b676cf00 100644 --- a/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/RequestBuilder.cpp @@ -89,6 +89,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 17800c9eca..b3b7998955 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 15c0d00590..b1d0bd61e6 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(_cookie); file_cache_sync(inode->FileCache()); + inode->Commit(); inode->Close(cookie); delete cookie;