From 88a2565650749a2ee9436f0e5f2a2077d21bf03e Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Mon, 4 Aug 2008 03:18:10 +0000 Subject: [PATCH] * 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 --- .../file_systems/bfs/kernel_interface.cpp | 35 +++++++++++++++---- .../file_systems/bfs/system_dependencies.h | 2 ++ 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp index 623a4f345d..abc83527cd 100644 --- a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp @@ -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 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 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; } diff --git a/src/add-ons/kernel/file_systems/bfs/system_dependencies.h b/src/add-ons/kernel/file_systems/bfs/system_dependencies.h index f7e5b6c5ad..6e8989670a 100644 --- a/src/add-ons/kernel/file_systems/bfs/system_dependencies.h +++ b/src/add-ons/kernel/file_systems/bfs/system_dependencies.h @@ -11,9 +11,11 @@ #include #include "fssh_api_wrapper.h" +#include "fssh_auto_deleter.h" #else // !BFS_SHELL +#include #include #include #include