From e743e243206509ccb41281a1aab140597bfb40b7 Mon Sep 17 00:00:00 2001 From: Pawel Dziepak Date: Sun, 5 Aug 2012 22:49:44 +0200 Subject: [PATCH] nfs4: Move cache management inside Inode class --- .../kernel/file_systems/nfs4/Inode.cpp | 7 +++ src/add-ons/kernel/file_systems/nfs4/Inode.h | 17 ++++++- .../kernel/file_systems/nfs4/InodeRegular.cpp | 51 ++++++++++++++++++- .../kernel/file_systems/nfs4/NFS4Inode.h | 2 +- .../file_systems/nfs4/kernel_interface.cpp | 35 +++++-------- 5 files changed, 85 insertions(+), 27 deletions(-) diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp index edfbddffde..a573f4989d 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp @@ -24,6 +24,7 @@ Inode::Inode() : fCache(NULL), fFileCache(NULL), + fMaxFileSize(0), fOpenState(NULL), fWriteDirty(false) { @@ -638,6 +639,9 @@ Inode::AcquireLock(OpenFileCookie* cookie, const struct flock* lock, status_t Inode::ReleaseLock(OpenFileCookie* cookie, const struct flock* lock) { + file_cache_sync(fFileCache); + Commit(); + LockInfo* prev = NULL; thread_info info; @@ -673,6 +677,9 @@ Inode::ReleaseLock(OpenFileCookie* cookie, const struct flock* lock) status_t Inode::ReleaseAllLocks(OpenFileCookie* cookie) { + file_cache_sync(fFileCache); + Commit(); + MutexLocker _(cookie->fLocksLock); LockInfo* linfo = cookie->fLocks; while (linfo != NULL) { diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.h b/src/add-ons/kernel/file_systems/nfs4/Inode.h index 58250e7521..a44c12b584 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.h +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.h @@ -32,6 +32,8 @@ public: inline void* FileCache(); status_t RevalidateFileCache(); + inline uint64 MaxFileSize(); + status_t LookUp(const char* name, ino_t* id); status_t Access(int mode); @@ -57,10 +59,15 @@ 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, bool* eof); + void* buffer, size_t* length); status_t Write(OpenFileCookie* cookie, off_t pos, const void* buffer, size_t *_length); + status_t ReadDirect(OpenFileCookie* cookie, off_t pos, + void* buffer, size_t* length, bool* eof); + status_t WriteDirect(OpenFileCookie* cookie, off_t pos, + const void* buffer, size_t *_length); + status_t CreateDir(const char* name, int mode); status_t OpenDir(OpenDirCookie* cookie); status_t ReadDir(void* buffer, uint32 size, @@ -109,6 +116,7 @@ private: uint64 fChange; void* fFileCache; mutex fFileCacheLock; + uint64 fMaxFileSize; OpenState* fOpenState; mutex fStateLock; @@ -171,5 +179,12 @@ Inode::SetOpenState(OpenState* state) } +inline uint64 +Inode::MaxFileSize() +{ + return fMaxFileSize; +} + + #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 c82c507da5..34ca35e1f8 100644 --- a/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/InodeRegular.cpp @@ -135,6 +135,9 @@ Inode::Open(int mode, OpenFileCookie* cookie) status_t Inode::Close(OpenFileCookie* cookie) { + file_cache_sync(fFileCache); + Commit(); + fFileSystem->RemoveOpenFile(cookie); MutexLocker _(fStateLock); @@ -147,12 +150,15 @@ Inode::Close(OpenFileCookie* cookie) status_t -Inode::Read(OpenFileCookie* cookie, off_t pos, void* buffer, size_t* _length, +Inode::ReadDirect(OpenFileCookie* cookie, off_t pos, void* buffer, size_t* _length, bool* eof) { *eof = false; uint32 size = 0; + uint32 ioSize = fFileSystem->Root()->IOSize(); + *_length = min_c(ioSize, *_length); + status_t result; while (size < *_length && !*eof) { uint32 len = *_length - size; @@ -175,12 +181,25 @@ Inode::Read(OpenFileCookie* cookie, off_t pos, void* buffer, size_t* _length, status_t -Inode::Write(OpenFileCookie* cookie, off_t pos, const void* _buffer, +Inode::Read(OpenFileCookie* cookie, off_t pos, void* buffer, size_t* _length) +{ + bool eof = false; + if ((cookie->fMode & O_NOCACHE) != 0) + return ReadDirect(cookie, pos, buffer, _length, &eof); + return file_cache_read(fFileCache, cookie, pos, buffer, _length); +} + + +status_t +Inode::WriteDirect(OpenFileCookie* cookie, off_t pos, const void* _buffer, size_t *_length) { uint32 size = 0; const char* buffer = reinterpret_cast(_buffer); + uint32 ioSize = fFileSystem->Root()->IOSize(); + *_length = min_c(ioSize, *_length); + fWriteDirty = true; while (size < *_length) { @@ -206,6 +225,34 @@ Inode::Write(OpenFileCookie* cookie, off_t pos, const void* _buffer, } +status_t +Inode::Write(OpenFileCookie* cookie, off_t pos, const void* _buffer, + size_t *_length) +{ + struct stat st; + status_t result = Stat(&st); + if (result != B_OK) + return result; + + if ((cookie->fMode & O_APPEND) != 0) + pos = st.st_size; + + uint64 fileSize = max_c(st.st_size, pos + *_length); + fMaxFileSize = max_c(fMaxFileSize, fileSize); + + if ((cookie->fMode & O_NOCACHE) != 0) { + WriteDirect(cookie, pos, _buffer, _length); + Commit(); + } + + result = file_cache_set_size(fFileCache, fileSize); + if (result != B_OK) + return result; + + return file_cache_write(fFileCache, cookie, pos, _buffer, _length); +} + + status_t Inode::Commit() { diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.h b/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.h index dbcf90a1c8..968e6705b5 100644 --- a/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.h +++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.h @@ -33,7 +33,7 @@ protected: status_t LookUp(const char* name, uint64* change, uint64* fileID, FileHandle* handle); - status_t Link(Inode* dir, const char* name,s + status_t Link(Inode* dir, const char* name, ChangeInfo* changeInfo); static status_t Rename(Inode* from, Inode* to, const char* fromName, 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 d1a447bc09..4804c6cce7 100644 --- a/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp @@ -230,7 +230,7 @@ nfs4_read_pages(fs_volume* _volume, fs_vnode* vnode, void* _cookie, off_t pos, do { size_t bytesRead = bytesLeft; - result = inode->Read(cookie, pos, buffer, &bytesRead, &eof); + result = inode->ReadDirect(cookie, pos, buffer, &bytesRead, &eof); if (result != B_OK) return result; @@ -255,15 +255,17 @@ nfs4_write_pages(fs_volume* _volume, fs_vnode* vnode, void* _cookie, off_t pos, OpenFileCookie* cookie = reinterpret_cast(_cookie); status_t result; - uint32 ioSize = inode->GetFileSystem()->Root()->IOSize(); for (size_t i = 0; i < count; i++) { - size_t bytesLeft = vecs[i].iov_len; + uint64 bytesLeft = vecs[i].iov_len; + if (pos + bytesLeft > inode->MaxFileSize()) + bytesLeft = inode->MaxFileSize() - pos; + char* buffer = reinterpret_cast(vecs[i].iov_base); do { - size_t bytesWritten = min_c(ioSize, bytesLeft); + size_t bytesWritten = bytesLeft; - result = inode->Write(cookie, pos, buffer, &bytesWritten); + result = inode->WriteDirect(cookie, pos, buffer, &bytesWritten); if (result != B_OK) return result; @@ -468,8 +470,6 @@ nfs4_free_cookie(fs_volume* volume, fs_vnode* vnode, void* _cookie) return B_OK; OpenFileCookie* cookie = reinterpret_cast(_cookie); - file_cache_sync(inode->FileCache()); - inode->Commit(); inode->Close(cookie); delete cookie; @@ -479,7 +479,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(vnode->private_node); @@ -490,7 +490,9 @@ nfs4_read(fs_volume* volume, fs_vnode* vnode, void* cookie, off_t pos, if (inode->Type() == S_IFLNK) return B_BAD_VALUE; - return file_cache_read(inode->FileCache(), cookie, pos, buffer, length); + OpenFileCookie* cookie = reinterpret_cast(_cookie); + + return inode->Read(cookie, pos, buffer, length); } @@ -508,17 +510,7 @@ nfs4_write(fs_volume* volume, fs_vnode* vnode, void* _cookie, off_t pos, OpenFileCookie* cookie = reinterpret_cast(_cookie); - 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; - - return file_cache_write(inode->FileCache(), cookie, pos, _buffer, length); + return inode->Write(cookie, pos, _buffer, length); } @@ -627,9 +619,6 @@ nfs4_release_lock(fs_volume* volume, fs_vnode* vnode, void* _cookie, OpenFileCookie* cookie = reinterpret_cast(_cookie); - file_cache_sync(inode->FileCache()); - inode->Commit(); - if (lock != NULL) return inode->ReleaseLock(cookie, lock); else