* Added support for O_NOCACHE/O_DIRECT.

* bfs_open() was leaking the already allocated cookie in several error
  conditions.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26780 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2008-08-04 03:18:10 +00:00
parent 7491000f20
commit 88a2565650
2 changed files with 30 additions and 7 deletions
@@ -70,6 +70,11 @@ iterative_io_finished_hook(void* cookie, io_request* request, status_t status,
bool partialTransfer, size_t bytesTransferred)
{
Inode* inode = (Inode*)cookie;
#ifndef BFS_SHELL
ktrace_printf("bfs iterative_io_finished_hook(): inode: %p, request: %p, "
"status: %#lx, partial: %d, transferred: %lu", inode, request, status,
partialTransfer, bytesTransferred);
#endif
rw_lock_read_unlock(&inode->Lock());
return B_OK;
@@ -450,6 +455,9 @@ bfs_io(fs_volume* _volume, fs_vnode* _node, void* _cookie, io_request* request)
if (inode->FileCache() == NULL)
RETURN_ERROR(B_BAD_VALUE);
#ifndef BFS_SHELL
ktrace_printf("bfs_io(): inode: %p, request: %p", inode, request);
#endif
// We lock the node here and will unlock it in the "finished" hook.
rw_lock_read_lock(&inode->Lock());
@@ -1123,6 +1131,7 @@ bfs_open(fs_volume* _volume, fs_vnode* _node, int openMode, void** _cookie)
file_cookie* cookie = new(std::nothrow) file_cookie;
if (cookie == NULL)
RETURN_ERROR(B_NO_MEMORY);
ObjectDeleter<file_cookie> cookieDeleter(cookie);
// initialize the cookie
cookie->open_mode = openMode;
@@ -1130,6 +1139,15 @@ bfs_open(fs_volume* _volume, fs_vnode* _node, int openMode, void** _cookie)
cookie->last_size = inode->Size();
cookie->last_notification = system_time();
// Disable the file cache, if requested?
CObjectDeleter<void> fileCacheEnabler(file_cache_enable);
if ((openMode & O_NOCACHE) != 0 && inode->FileCache() != NULL) {
status = file_cache_disable(inode->FileCache());
if (status != B_OK)
return status;
fileCacheEnabler.SetTo(inode->FileCache());
}
// Should we truncate the file?
if ((openMode & O_TRUNC) != 0) {
if ((openMode & O_RWMASK) == O_RDONLY)
@@ -1143,18 +1161,18 @@ bfs_open(fs_volume* _volume, fs_vnode* _node, int openMode, void** _cookie)
inode->WriteLockInTransaction(transaction);
status_t status = inode->SetFileSize(transaction, 0);
if (status >= B_OK)
status = inode->WriteBack(transaction);
if (status < B_OK) {
// bfs_free_cookie() is only called if this function is successful
delete cookie;
if (status < B_OK)
return status;
status = inode->WriteBack(transaction);
if (status < B_OK)
return status;
}
transaction.Done();
}
fileCacheEnabler.Detach();
cookieDeleter.Detach();
*_cookie = cookie;
return B_OK;
}
@@ -1306,6 +1324,9 @@ bfs_free_cookie(fs_volume* _volume, fs_vnode* _node, void* _cookie)
volume->Allocator().StopChecking(NULL);
}
if ((cookie->open_mode & O_NOCACHE) != 0 && inode->FileCache() != NULL)
file_cache_enable(inode->FileCache());
delete cookie;
return B_OK;
}
@@ -11,9 +11,11 @@
#include <new>
#include "fssh_api_wrapper.h"
#include "fssh_auto_deleter.h"
#else // !BFS_SHELL
#include <AutoDeleter.h>
#include <util/AutoLock.h>
#include <util/DoublyLinkedList.h>
#include <util/kernel_cpp.h>