From a4e05e618a467d1af0433cde51683a33580ce6cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 6 Sep 2004 22:56:52 +0000 Subject: [PATCH] Added a "cookie" parameter to the fs_read|write|has_page[s](). Implemented bfs_get_file_map(). Now uses the brand new file cache for the file data streams. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@8877 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/file_systems/bfs/Inode.cpp | 3 + src/add-ons/kernel/file_systems/bfs/Inode.h | 5 ++ src/add-ons/kernel/file_systems/bfs/Jamfile | 2 +- .../file_systems/bfs/kernel_interface.cpp | 72 ++++++++++++++++--- 4 files changed, 72 insertions(+), 10 deletions(-) diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.cpp b/src/add-ons/kernel/file_systems/bfs/Inode.cpp index 24668cb6d1..26a22e89c8 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Inode.cpp @@ -11,6 +11,7 @@ #include "Stream.h" #include "Index.h" +#include #include #include @@ -223,6 +224,8 @@ Inode::Initialize() if (IsContainer()) fTree = new BPlusTree(this); + + fCache = NULL; } diff --git a/src/add-ons/kernel/file_systems/bfs/Inode.h b/src/add-ons/kernel/file_systems/bfs/Inode.h index afd898a4fa..2eaf972396 100644 --- a/src/add-ons/kernel/file_systems/bfs/Inode.h +++ b/src/add-ons/kernel/file_systems/bfs/Inode.h @@ -176,6 +176,10 @@ class Inode : public CachedBlock { off_t OldSize() { return fOldSize; } off_t OldLastModified() { return fOldLastModified; } + // file cache + void *FileCache() const { return fCache; } + void SetFileCache(void *cache) { fCache = cache; } + private: Inode(const Inode &); Inode &operator=(const Inode &); @@ -205,6 +209,7 @@ class Inode : public CachedBlock { ReadWriteLock fLock; off_t fOldSize; // we need those values to ensure we will remove off_t fOldLastModified; // the correct keys from the indices + void *fCache; mutable SimpleLock fSmallDataLock; Chain fIterators; diff --git a/src/add-ons/kernel/file_systems/bfs/Jamfile b/src/add-ons/kernel/file_systems/bfs/Jamfile index d1990522f5..3275f790a8 100644 --- a/src/add-ons/kernel/file_systems/bfs/Jamfile +++ b/src/add-ons/kernel/file_systems/bfs/Jamfile @@ -23,7 +23,7 @@ oldOPTIM = $(OPTIM) ; bfsAddOnName = bfs ; } else { bfsAddOnName = obfs ; - } + } if $(DEBUG) = 0 { # the gcc on BeOS doesn't compile BFS correctly with -O2 or more 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 737eaa9d8b..1a40d1fa89 100644 --- a/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/bfs/kernel_interface.cpp @@ -1,7 +1,7 @@ /* kernel_interface - file system interface to BeOS' vnode layer ** ** Copyright 2001-2004, Axel Dörfler, axeld@pinc-software.de -** This file may be used under the terms of the OpenBeOS License. +** This file may be used under the terms of the Haiku License. */ @@ -21,6 +21,7 @@ #include #include #include +#include #ifndef _IMPEXP_KERNEL # define _IMPEXP_KERNEL @@ -241,8 +242,12 @@ restartIfBusy: } else status = inode->InitCheck(false); - if (status == B_OK) + if (status == B_OK) { + if (inode->IsFile() && inode->FileCache() == NULL) + inode->SetFileCache(file_cache_create(volume->ID(), inode->ID(), inode->Size(), volume->Device())); + *_node = inode; + } return status; } @@ -307,7 +312,7 @@ bfs_remove_vnode(void *_ns, void *_node, bool reenter) static bool -bfs_can_page(fs_volume _fs, fs_vnode _v) +bfs_can_page(fs_volume _fs, fs_vnode _v, fs_cookie _cookie) { // ToDo: we're obviously not even asked... return false; @@ -315,7 +320,7 @@ bfs_can_page(fs_volume _fs, fs_vnode _v) static status_t -bfs_read_pages(fs_volume _fs, fs_vnode _node, off_t pos, +bfs_read_pages(fs_volume _fs, fs_vnode _node, fs_cookie _cookie, off_t pos, const iovec *vecs, size_t count, size_t *_numBytes) { Inode *inode = (Inode *)_node; @@ -324,7 +329,8 @@ bfs_read_pages(fs_volume _fs, fs_vnode _node, off_t pos, RETURN_ERROR(B_BAD_VALUE); ReadLocked locked(inode->Lock()); - + return file_cache_read_pages(inode->FileCache(), pos, vecs, count, _numBytes); +#if 0 for (uint32 i = 0; i < count; i++) { if (pos >= inode->Size()) { memset(vecs[i].iov_base, 0, vecs[i].iov_len); @@ -347,16 +353,64 @@ bfs_read_pages(fs_volume _fs, fs_vnode _node, off_t pos, } return B_OK; +#endif } static status_t -bfs_write_pages(fs_volume _fs, fs_vnode _v, off_t pos, const iovec *vecs, size_t count, size_t *_numBytes) +bfs_write_pages(fs_volume _fs, fs_vnode _v, fs_cookie _cookie, off_t pos, + const iovec *vecs, size_t count, size_t *_numBytes) { return EPERM; } +static status_t +bfs_get_file_map(fs_volume _fs, fs_vnode _node, off_t offset, size_t size, + struct file_io_vec *vecs, size_t *_count) +{ + Volume *volume = (Volume *)_fs; + Inode *inode = (Inode *)_node; + + int32 blockShift = volume->BlockShift(); + size_t index = 0, max = *_count; + block_run run; + off_t fileOffset; + + FUNCTION_START(("offset = %Ld, size = %lu\n", offset, size)); + + while (true) { + status_t status = inode->FindBlockRun(offset, run, fileOffset); + if (status != B_OK) + return status; + + vecs[index].offset = volume->ToOffset(run) + offset - fileOffset; + vecs[index].length = (run.Length() << blockShift) - offset + fileOffset; + + offset += vecs[index].length; + + // are we already done? + if (size <= vecs[index].length + || offset >= inode->Size()) { + *_count = index + 1; + return B_OK; + } + + size -= vecs[index].length; + index++; + + if (index >= max) { + // we're out of file_io_vecs; let's bail out + *_count = index; + return B_BUFFER_OVERFLOW; + } + } + + // can never get here + return B_ERROR; +} + + // #pragma mark - @@ -1090,7 +1144,7 @@ bfs_read(void *_ns, void *_node, void *_cookie, off_t pos, void *buffer, size_t } ReadLocked locked(inode->Lock()); - return inode->ReadAt(pos, (uint8 *)buffer, _length); + return file_cache_read(inode->FileCache(), pos, buffer, _length); } @@ -2006,8 +2060,8 @@ static file_system_info sBeFileSystem = { &bfs_can_page, &bfs_read_pages, &bfs_write_pages, - - NULL, // get_file_map() + + &bfs_get_file_map, // get file map &bfs_ioctl, // ioctl &bfs_fsync, // sync