From 5c03270bea6a91f10dd57d80df860cf307693231 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 25 Apr 2007 12:07:30 +0000 Subject: [PATCH] Added block_cache_sync_etc() that allows you to sync single blocks. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20811 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/drivers/fs_cache.h | 10 +++-- .../userlandfs/server/haiku_block_cache.cpp | 37 ++++++++++++++++++- .../userlandfs/server/haiku_fs_cache.h | 9 +++-- .../userlandfs/server/haiku_kernel_emu.cpp | 8 ++++ src/system/kernel/cache/block_cache.cpp | 35 +++++++++++++++++- 5 files changed, 89 insertions(+), 10 deletions(-) diff --git a/headers/os/drivers/fs_cache.h b/headers/os/drivers/fs_cache.h index 75f22597fa..a6f165c6e5 100644 --- a/headers/os/drivers/fs_cache.h +++ b/headers/os/drivers/fs_cache.h @@ -1,11 +1,12 @@ -/* File System File and Block Caches - * - * Copyright 2004-2005, Haiku Inc. All Rights Reserved. +/* + * Copyright 2004-2007, Haiku Inc. All Rights Reserved. * Distributed under the terms of the MIT License. */ #ifndef _FS_CACHE_H #define _FS_CACHE_H +//! File System File and Block Caches + #include @@ -37,7 +38,8 @@ extern void block_cache_delete(void *_cache, bool allowWrites); extern void *block_cache_create(int fd, off_t numBlocks, size_t blockSize, bool readOnly); extern status_t block_cache_sync(void *_cache); - +extern status_t block_cache_sync_etc(void *_cache, off_t blockNumber, + size_t numBlocks); extern status_t block_cache_make_writable(void *_cache, off_t blockNumber, int32 transaction); extern void *block_cache_get_writable_etc(void *_cache, off_t blockNumber, diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/haiku_block_cache.cpp b/src/add-ons/kernel/file_systems/userlandfs/server/haiku_block_cache.cpp index 2c1e12ac32..a6d07c5c92 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/haiku_block_cache.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/server/haiku_block_cache.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2004-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. + * Copyright 2004-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved. * Distributed under the terms of the MIT License. */ @@ -16,7 +16,7 @@ #include "haiku_hash.h" #include "kernel_emu.h" -// ToDo: this is a naive but growing implementation to test the API: +// TODO: this is a naive but growing implementation to test the API: // 1) block reading/writing is not at all optimized for speed, it will // just read and write single blocks. // 2) the locking could be improved; getting a block should not need to @@ -1060,6 +1060,39 @@ block_cache_sync(void *_cache) } +status_t +block_cache_sync_etc(void *_cache, off_t blockNumber, size_t numBlocks) +{ + block_cache *cache = (block_cache *)_cache; + + // we will sync all dirty blocks to disk that have a completed + // transaction or no transaction only + + if (blockNumber < 0 || blockNumber >= cache->max_blocks) { + panic("block_cache_sync_etc: invalid block number %Ld (max %Ld)", + blockNumber, cache->max_blocks - 1); + return NULL; + } + + BenaphoreLocker locker(&cache->lock); + + for (; numBlocks > 0; numBlocks--, blockNumber++) { + cached_block *block = (cached_block *)hash_lookup(cache->hash, + &blockNumber); + if (block == NULL) + continue; + if (block->previous_transaction != NULL + || (block->transaction == NULL && block->is_dirty)) { + status_t status = write_cached_block(cache, block); + if (status != B_OK) + return status; + } + } + + return B_OK; +} + + status_t block_cache_make_writable(void *_cache, off_t blockNumber, int32 transaction) { diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/haiku_fs_cache.h b/src/add-ons/kernel/file_systems/userlandfs/server/haiku_fs_cache.h index 48439d1272..f0c98cdd85 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/haiku_fs_cache.h +++ b/src/add-ons/kernel/file_systems/userlandfs/server/haiku_fs_cache.h @@ -1,11 +1,12 @@ -/* File System File and Block Caches - * - * Copyright 2004-2005, Haiku Inc. All Rights Reserved. +/* + * Copyright 2004-2007, Haiku Inc. All Rights Reserved. * Distributed under the terms of the MIT License. */ #ifndef USERLAND_FS_HAIKU_FS_CACHE_H #define USERLAND_FS_HAIKU_FS_CACHE_H +//! File System File and Block Caches + #include @@ -37,6 +38,8 @@ extern void block_cache_delete(void *_cache, bool allowWrites); extern void *block_cache_create(int fd, off_t numBlocks, size_t blockSize, bool readOnly); extern status_t block_cache_sync(void *_cache); +extern status_t block_cache_sync_etc(void *_cache, off_t blockNumber, + size_t numBlocks); extern status_t block_cache_make_writable(void *_cache, off_t blockNumber, int32 transaction); diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/haiku_kernel_emu.cpp b/src/add-ons/kernel/file_systems/userlandfs/server/haiku_kernel_emu.cpp index ffe8ef412a..9904b06020 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/haiku_kernel_emu.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/server/haiku_kernel_emu.cpp @@ -265,6 +265,14 @@ block_cache_sync(void *_cache) return UserlandFS::HaikuKernelEmu::block_cache_sync(_cache); } +// block_cache_sync_etc +status_t +block_cache_sync_etc(void *_cache, off_t blockNumber, size_t numBlocks) +{ + return UserlandFS::HaikuKernelEmu::block_cache_sync_etc(_cache, + blockNumber, numBlocks); +} + // block_cache_make_writable status_t block_cache_make_writable(void *_cache, off_t blockNumber, int32 transaction) diff --git a/src/system/kernel/cache/block_cache.cpp b/src/system/kernel/cache/block_cache.cpp index 94fa4904bf..235d623efa 100644 --- a/src/system/kernel/cache/block_cache.cpp +++ b/src/system/kernel/cache/block_cache.cpp @@ -23,7 +23,7 @@ #include -// ToDo: this is a naive but growing implementation to test the API: +// TODO: this is a naive but growing implementation to test the API: // 1) block reading/writing is not at all optimized for speed, it will // just read and write single blocks. // 2) the locking could be improved; getting a block should not need to @@ -1171,6 +1171,39 @@ block_cache_sync(void *_cache) } +extern "C" status_t +block_cache_sync_etc(void *_cache, off_t blockNumber, size_t numBlocks) +{ + block_cache *cache = (block_cache *)_cache; + + // we will sync all dirty blocks to disk that have a completed + // transaction or no transaction only + + if (blockNumber < 0 || blockNumber >= cache->max_blocks) { + panic("block_cache_sync_etc: invalid block number %Ld (max %Ld)", + blockNumber, cache->max_blocks - 1); + return NULL; + } + + BenaphoreLocker locker(&cache->lock); + + for (; numBlocks > 0; numBlocks--, blockNumber++) { + cached_block *block = (cached_block *)hash_lookup(cache->hash, + &blockNumber); + if (block == NULL) + continue; + if (block->previous_transaction != NULL + || (block->transaction == NULL && block->is_dirty)) { + status_t status = write_cached_block(cache, block); + if (status != B_OK) + return status; + } + } + + return B_OK; +} + + extern "C" status_t block_cache_make_writable(void *_cache, off_t blockNumber, int32 transaction) {