* 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) bool partialTransfer, size_t bytesTransferred)
{ {
Inode* inode = (Inode*)cookie; 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()); rw_lock_read_unlock(&inode->Lock());
return B_OK; return B_OK;
@@ -450,6 +455,9 @@ bfs_io(fs_volume* _volume, fs_vnode* _node, void* _cookie, io_request* request)
if (inode->FileCache() == NULL) if (inode->FileCache() == NULL)
RETURN_ERROR(B_BAD_VALUE); 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. // We lock the node here and will unlock it in the "finished" hook.
rw_lock_read_lock(&inode->Lock()); 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; file_cookie* cookie = new(std::nothrow) file_cookie;
if (cookie == NULL) if (cookie == NULL)
RETURN_ERROR(B_NO_MEMORY); RETURN_ERROR(B_NO_MEMORY);
ObjectDeleter<file_cookie> cookieDeleter(cookie);
// initialize the cookie // initialize the cookie
cookie->open_mode = openMode; 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_size = inode->Size();
cookie->last_notification = system_time(); 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? // Should we truncate the file?
if ((openMode & O_TRUNC) != 0) { if ((openMode & O_TRUNC) != 0) {
if ((openMode & O_RWMASK) == O_RDONLY) 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); inode->WriteLockInTransaction(transaction);
status_t status = inode->SetFileSize(transaction, 0); status_t status = inode->SetFileSize(transaction, 0);
if (status >= B_OK) if (status < B_OK)
status = inode->WriteBack(transaction); return status;
if (status < B_OK) { status = inode->WriteBack(transaction);
// bfs_free_cookie() is only called if this function is successful if (status < B_OK)
delete cookie;
return status; return status;
}
transaction.Done(); transaction.Done();
} }
fileCacheEnabler.Detach();
cookieDeleter.Detach();
*_cookie = cookie; *_cookie = cookie;
return B_OK; return B_OK;
} }
@@ -1306,6 +1324,9 @@ bfs_free_cookie(fs_volume* _volume, fs_vnode* _node, void* _cookie)
volume->Allocator().StopChecking(NULL); volume->Allocator().StopChecking(NULL);
} }
if ((cookie->open_mode & O_NOCACHE) != 0 && inode->FileCache() != NULL)
file_cache_enable(inode->FileCache());
delete cookie; delete cookie;
return B_OK; return B_OK;
} }
@@ -11,9 +11,11 @@
#include <new> #include <new>
#include "fssh_api_wrapper.h" #include "fssh_api_wrapper.h"
#include "fssh_auto_deleter.h"
#else // !BFS_SHELL #else // !BFS_SHELL
#include <AutoDeleter.h>
#include <util/AutoLock.h> #include <util/AutoLock.h>
#include <util/DoublyLinkedList.h> #include <util/DoublyLinkedList.h>
#include <util/kernel_cpp.h> #include <util/kernel_cpp.h>