nfs4: Move cache management inside Inode class

This commit is contained in:
Pawel Dziepak
2012-08-05 22:49:44 +02:00
parent 52aaad172f
commit e743e24320
5 changed files with 85 additions and 27 deletions
@@ -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) {
+16 -1
View File
@@ -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
@@ -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<const char*>(_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()
{
@@ -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,
@@ -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<OpenFileCookie*>(_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<char*>(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<OpenFileCookie*>(_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<Inode*>(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<OpenFileCookie*>(_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<OpenFileCookie*>(_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<OpenFileCookie*>(_cookie);
file_cache_sync(inode->FileCache());
inode->Commit();
if (lock != NULL)
return inode->ReleaseLock(cookie, lock);
else