nfs4: Use existing write cookie, do not send COMMIT if not necessary

This commit is contained in:
Pawel Dziepak
2012-08-03 19:12:22 +02:00
parent 36577ed54b
commit d4a75b9c9f
4 changed files with 44 additions and 24 deletions
@@ -24,7 +24,9 @@ Inode::Inode()
: :
fAttrCacheExpire(0), fAttrCacheExpire(0),
fCache(NULL), fCache(NULL),
fFileCache(NULL) fFileCache(NULL),
fWriteCookie(NULL),
fWriteDirty(false)
{ {
mutex_init(&fAttrCacheLock, NULL); mutex_init(&fAttrCacheLock, NULL);
} }
@@ -31,6 +31,8 @@ public:
inline FileSystem* GetFileSystem() const; inline FileSystem* GetFileSystem() const;
inline void* FileCache(); inline void* FileCache();
inline OpenFileCookie* WriteCookie();
inline void SetWriteCookie(OpenFileCookie* cookie);
status_t GetChangeInfo(uint64* change); status_t GetChangeInfo(uint64* change);
@@ -116,6 +118,9 @@ protected:
DirectoryCache* fCache; DirectoryCache* fCache;
void* fFileCache; void* fFileCache;
OpenFileCookie* fWriteCookie;
bool fWriteDirty;
}; };
@@ -165,5 +170,19 @@ Inode::FileCache()
} }
inline OpenFileCookie*
Inode::WriteCookie()
{
return fWriteCookie;
}
inline void
Inode::SetWriteCookie(OpenFileCookie* cookie)
{
fWriteCookie = cookie;
}
#endif // INODE_H #endif // INODE_H
@@ -384,6 +384,8 @@ Inode::Write(OpenFileCookie* cookie, off_t pos, const void* _buffer,
uint64 fileSize; uint64 fileSize;
const char* buffer = reinterpret_cast<const char*>(_buffer); const char* buffer = reinterpret_cast<const char*>(_buffer);
fWriteDirty = true;
while (size < *_length) { while (size < *_length) {
do { do {
RPC::Server* serv = fFileSystem->Server(); RPC::Server* serv = fFileSystem->Server();
@@ -460,6 +462,9 @@ Inode::Write(OpenFileCookie* cookie, off_t pos, const void* _buffer,
status_t status_t
Inode::Commit() Inode::Commit()
{ {
if (!fWriteDirty)
return B_OK;
do { do {
RPC::Server* serv = fFileSystem->Server(); RPC::Server* serv = fFileSystem->Server();
Request request(serv); Request request(serv);
@@ -221,6 +221,7 @@ nfs4_read_pages(fs_volume* _volume, fs_vnode* vnode, void* _cookie, off_t pos,
OpenFileCookie* cookie = reinterpret_cast<OpenFileCookie*>(_cookie); OpenFileCookie* cookie = reinterpret_cast<OpenFileCookie*>(_cookie);
status_t result; status_t result;
size_t totalRead = 0;
bool eof = false; bool eof = false;
for (size_t i = 0; i < count && !eof; i++) { for (size_t i = 0; i < count && !eof; i++) {
size_t bytesLeft = vecs[i].iov_len; size_t bytesLeft = vecs[i].iov_len;
@@ -232,12 +233,15 @@ nfs4_read_pages(fs_volume* _volume, fs_vnode* vnode, void* _cookie, off_t pos,
if (result != B_OK) if (result != B_OK)
return result; return result;
totalRead += bytesRead;
pos += bytesRead; pos += bytesRead;
buffer += bytesRead; buffer += bytesRead;
bytesLeft -= bytesRead; bytesLeft -= bytesRead;
} while (bytesLeft > 0 && !eof); } while (bytesLeft > 0 && !eof);
} }
*_numBytes = totalRead;
return B_OK; return B_OK;
} }
@@ -247,21 +251,12 @@ nfs4_write_pages(fs_volume* _volume, fs_vnode* vnode, void* _cookie, off_t pos,
const iovec* vecs, size_t count, size_t* _numBytes) const iovec* vecs, size_t count, size_t* _numBytes)
{ {
Inode* inode = reinterpret_cast<Inode*>(vnode->private_node); Inode* inode = reinterpret_cast<Inode*>(vnode->private_node);
bool freeCookie = false;
OpenFileCookie* cookie = reinterpret_cast<OpenFileCookie*>(_cookie); OpenFileCookie* cookie = reinterpret_cast<OpenFileCookie*>(_cookie);
if (cookie == NULL) { if (cookie == NULL) {
cookie = new OpenFileCookie; cookie = inode->WriteCookie();
if (cookie == NULL) if (cookie == NULL)
return B_NO_MEMORY; return B_BAD_VALUE;
status_t result = inode->Open(O_WRONLY, cookie);
if (result != B_OK) {
delete cookie;
return result;
}
freeCookie = true;
} }
status_t result; status_t result;
@@ -274,13 +269,8 @@ nfs4_write_pages(fs_volume* _volume, fs_vnode* vnode, void* _cookie, off_t pos,
size_t bytesWritten = min_c(ioSize, bytesLeft); size_t bytesWritten = min_c(ioSize, bytesLeft);
result = inode->Write(cookie, pos, buffer, &bytesWritten); result = inode->Write(cookie, pos, buffer, &bytesWritten);
if (result != B_OK) { if (result != B_OK)
if (freeCookie) {
inode->Close(cookie);
delete cookie;
}
return result; return result;
}
bytesLeft -= bytesWritten; bytesLeft -= bytesWritten;
pos += bytesWritten; pos += bytesWritten;
@@ -288,11 +278,6 @@ nfs4_write_pages(fs_volume* _volume, fs_vnode* vnode, void* _cookie, off_t pos,
} while (bytesLeft > 0); } while (bytesLeft > 0);
} }
if (freeCookie) {
inode->Close(cookie);
delete cookie;
}
return B_OK; return B_OK;
} }
@@ -326,7 +311,11 @@ static status_t
nfs4_fsync(fs_volume* volume, fs_vnode* vnode) nfs4_fsync(fs_volume* volume, fs_vnode* vnode)
{ {
Inode* inode = reinterpret_cast<Inode*>(vnode->private_node); Inode* inode = reinterpret_cast<Inode*>(vnode->private_node);
return file_cache_sync(inode->FileCache()); status_t result = file_cache_sync(inode->FileCache());
if (result != B_OK)
return result;
return inode->Commit();
} }
@@ -473,6 +462,10 @@ nfs4_free_cookie(fs_volume* volume, fs_vnode* vnode, void* _cookie)
OpenFileCookie* cookie = reinterpret_cast<OpenFileCookie*>(_cookie); OpenFileCookie* cookie = reinterpret_cast<OpenFileCookie*>(_cookie);
file_cache_sync(inode->FileCache()); file_cache_sync(inode->FileCache());
inode->Commit(); inode->Commit();
if (inode->WriteCookie() == cookie)
inode->SetWriteCookie(NULL);
inode->Close(cookie); inode->Close(cookie);
delete cookie; delete cookie;
@@ -520,6 +513,7 @@ nfs4_write(fs_volume* volume, fs_vnode* vnode, void* _cookie, off_t pos,
if (result != B_OK) if (result != B_OK)
return result; return result;
inode->SetWriteCookie(cookie);
return file_cache_write(inode->FileCache(), cookie, pos, _buffer, length); return file_cache_write(inode->FileCache(), cookie, pos, _buffer, length);
} }