haiku/headers/os/drivers/fs_cache.h

107 lines
4.0 KiB
C
Raw Normal View History

/*
* Copyright 2004-2008, 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 <fs_interface.h>
/* transaction events */
enum {
TRANSACTION_WRITTEN = 0x01,
TRANSACTION_ABORTED = 0x02,
TRANSACTION_ENDED = 0x04,
TRANSACTION_IDLE = 0x08
};
/* file map modes */
enum {
FILE_MAP_CACHE_ON_DEMAND = 0x01, /* default mode */
FILE_MAP_CACHE_ALL = 0x02
};
typedef void (*transaction_notification_hook)(int32 id, int32 event,
void *data);
#ifdef __cplusplus
extern "C" {
#endif
/* transactions */
extern int32 cache_start_transaction(void *_cache);
extern status_t cache_sync_transaction(void *_cache, int32 id);
extern status_t cache_end_transaction(void *_cache, int32 id,
transaction_notification_hook hook, void *data);
extern status_t cache_abort_transaction(void *_cache, int32 id);
extern int32 cache_detach_sub_transaction(void *_cache, int32 id,
transaction_notification_hook hook, void *data);
extern status_t cache_abort_sub_transaction(void *_cache, int32 id);
extern status_t cache_start_sub_transaction(void *_cache, int32 id);
extern status_t cache_add_transaction_listener(void *_cache, int32 id,
int32 events, transaction_notification_hook hook,
void *data);
extern status_t cache_remove_transaction_listener(void *_cache, int32 id,
transaction_notification_hook hook, void *data);
extern status_t cache_next_block_in_transaction(void *_cache, int32 id,
* cache_detach_sub_transaction() didn't really work: it did not put all needed blocks into the new transaction, but it would set that transaction on all blocks of the old transaction, too. Also, it did not correctly update the num_blocks/sub_num_blocks fields of the old transaction. Even worse, it did return B_OK instead of the ID of the new transaction... * get_writable_cached_block() did not correctly maintain the number of blocks in the sub transaction. * write_cached_block() did not free the original_data of a block when it wrote it back as part of a previous transaction. * Changed "cookie" for cache_next_block_in_transaction() to "long", so it will be 64 bits when needed. * Improved the API for detaching sub transactions: you can now get the blocks of only the main (parent) transaction as well, added new cache_block_in_main_transaction() function. * BFS now flushes the log when there is no space left for the current transaction. * _WriteTransactionToLog() allocated a "vecs" array, but never freed it. * _WriteTransactionToLog() now also supports detaching the current sub transaction if the whole thing is getting too large (it will now also panic if that doesn't work out). * Removed a useless optimization: making the blocks available in the cache isn't really needed, as all blocks in a transaction are locked into the cache, anyway. * Implemented Transaction::WriteBlocks(). * Minor cleanup, removed some dead code, fixed warnings in the fs_shell's block_cache when compiled with debug output on. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23610 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-01-18 20:07:18 +03:00
bool mainOnly, long *_cookie, off_t *_blockNumber,
void **_data, void **_unchangedData);
extern int32 cache_blocks_in_transaction(void *_cache, int32 id);
* cache_detach_sub_transaction() didn't really work: it did not put all needed blocks into the new transaction, but it would set that transaction on all blocks of the old transaction, too. Also, it did not correctly update the num_blocks/sub_num_blocks fields of the old transaction. Even worse, it did return B_OK instead of the ID of the new transaction... * get_writable_cached_block() did not correctly maintain the number of blocks in the sub transaction. * write_cached_block() did not free the original_data of a block when it wrote it back as part of a previous transaction. * Changed "cookie" for cache_next_block_in_transaction() to "long", so it will be 64 bits when needed. * Improved the API for detaching sub transactions: you can now get the blocks of only the main (parent) transaction as well, added new cache_block_in_main_transaction() function. * BFS now flushes the log when there is no space left for the current transaction. * _WriteTransactionToLog() allocated a "vecs" array, but never freed it. * _WriteTransactionToLog() now also supports detaching the current sub transaction if the whole thing is getting too large (it will now also panic if that doesn't work out). * Removed a useless optimization: making the blocks available in the cache isn't really needed, as all blocks in a transaction are locked into the cache, anyway. * Implemented Transaction::WriteBlocks(). * Minor cleanup, removed some dead code, fixed warnings in the fs_shell's block_cache when compiled with debug output on. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23610 a95241bf-73f2-0310-859d-f6bbb57e9c96
2008-01-18 20:07:18 +03:00
extern int32 cache_blocks_in_main_transaction(void *_cache, int32 id);
extern int32 cache_blocks_in_sub_transaction(void *_cache, int32 id);
/* block cache */
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,
off_t base, off_t length, int32 transaction);
extern void *block_cache_get_writable(void *_cache, off_t blockNumber,
int32 transaction);
extern void *block_cache_get_empty(void *_cache, off_t blockNumber,
int32 transaction);
extern const void *block_cache_get_etc(void *_cache, off_t blockNumber,
off_t base, off_t length);
extern const void *block_cache_get(void *_cache, off_t blockNumber);
extern status_t block_cache_set_dirty(void *_cache, off_t blockNumber,
bool isDirty, int32 transaction);
extern void block_cache_put(void *_cache, off_t blockNumber);
/* file cache */
* Extracted file_map API out of the file cache - it's now an optional service that can be used by file systems. * Changed the way the file cache works: instead of reading/writing to the underlying device directly, it can now be used for any data source, ie. also network file systems. * As a result, the former pages_io() moved to the VFS layer, and can now be called by a file system via {read|write}_file_io_vec_pages() (naming suggestions are always welcomed :-)). It now gets an FD, and uses that to communicate with the device (via its fs_{read|write}_pages() hooks). * The file_cache_{read|write}() functions must now be called without holding an I/O relevant file system lock. That allows the file cache to prepare the pages without colliding with the page writer, IOW the "mayBlock" flag can go into the attic again (yay!). * This also results in a much better performance when the system does I/O and is low on memory, as the page writer can now finally write back some pages, and that even without maxing out the CPU :) * The API changes put slightly more burden on the fs_{read|write}_pages() hooks, but in combination with the file_map it's still pretty straight forward. It just will have to dispatch the call to the underlying device directly, usually it will just call its fs_{read|write}_pages() hooks via the above mentioned calls. * Ported BFS and FAT to the new API, the latter has not been tested, though. * Also ported the API changes to the fs_shell. I also completely removed its file cache level page handling - the downside is that device access is no longer cached (ie. depends on the host OS now), the upside is that the code is greatly simplified. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22886 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-11-11 00:19:52 +03:00
extern void *file_cache_create(dev_t mountID, ino_t vnodeID, off_t size);
extern void file_cache_delete(void *_cacheRef);
extern void file_cache_enable(void *_cacheRef);
extern bool file_cache_is_enabled(void *_cacheRef);
extern status_t file_cache_disable(void *_cacheRef);
extern status_t file_cache_set_size(void *_cacheRef, off_t size);
extern status_t file_cache_sync(void *_cache);
* Extracted file_map API out of the file cache - it's now an optional service that can be used by file systems. * Changed the way the file cache works: instead of reading/writing to the underlying device directly, it can now be used for any data source, ie. also network file systems. * As a result, the former pages_io() moved to the VFS layer, and can now be called by a file system via {read|write}_file_io_vec_pages() (naming suggestions are always welcomed :-)). It now gets an FD, and uses that to communicate with the device (via its fs_{read|write}_pages() hooks). * The file_cache_{read|write}() functions must now be called without holding an I/O relevant file system lock. That allows the file cache to prepare the pages without colliding with the page writer, IOW the "mayBlock" flag can go into the attic again (yay!). * This also results in a much better performance when the system does I/O and is low on memory, as the page writer can now finally write back some pages, and that even without maxing out the CPU :) * The API changes put slightly more burden on the fs_{read|write}_pages() hooks, but in combination with the file_map it's still pretty straight forward. It just will have to dispatch the call to the underlying device directly, usually it will just call its fs_{read|write}_pages() hooks via the above mentioned calls. * Ported BFS and FAT to the new API, the latter has not been tested, though. * Also ported the API changes to the fs_shell. I also completely removed its file cache level page handling - the downside is that device access is no longer cached (ie. depends on the host OS now), the upside is that the code is greatly simplified. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22886 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-11-11 00:19:52 +03:00
extern status_t file_cache_read(void *_cacheRef, void *cookie, off_t offset,
void *bufferBase, size_t *_size);
extern status_t file_cache_write(void *_cacheRef, void *cookie, off_t offset,
const void *buffer, size_t *_size);
* Extracted file_map API out of the file cache - it's now an optional service that can be used by file systems. * Changed the way the file cache works: instead of reading/writing to the underlying device directly, it can now be used for any data source, ie. also network file systems. * As a result, the former pages_io() moved to the VFS layer, and can now be called by a file system via {read|write}_file_io_vec_pages() (naming suggestions are always welcomed :-)). It now gets an FD, and uses that to communicate with the device (via its fs_{read|write}_pages() hooks). * The file_cache_{read|write}() functions must now be called without holding an I/O relevant file system lock. That allows the file cache to prepare the pages without colliding with the page writer, IOW the "mayBlock" flag can go into the attic again (yay!). * This also results in a much better performance when the system does I/O and is low on memory, as the page writer can now finally write back some pages, and that even without maxing out the CPU :) * The API changes put slightly more burden on the fs_{read|write}_pages() hooks, but in combination with the file_map it's still pretty straight forward. It just will have to dispatch the call to the underlying device directly, usually it will just call its fs_{read|write}_pages() hooks via the above mentioned calls. * Ported BFS and FAT to the new API, the latter has not been tested, though. * Also ported the API changes to the fs_shell. I also completely removed its file cache level page handling - the downside is that device access is no longer cached (ie. depends on the host OS now), the upside is that the code is greatly simplified. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22886 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-11-11 00:19:52 +03:00
/* file map */
extern void *file_map_create(dev_t mountID, ino_t vnodeID, off_t size);
* Extracted file_map API out of the file cache - it's now an optional service that can be used by file systems. * Changed the way the file cache works: instead of reading/writing to the underlying device directly, it can now be used for any data source, ie. also network file systems. * As a result, the former pages_io() moved to the VFS layer, and can now be called by a file system via {read|write}_file_io_vec_pages() (naming suggestions are always welcomed :-)). It now gets an FD, and uses that to communicate with the device (via its fs_{read|write}_pages() hooks). * The file_cache_{read|write}() functions must now be called without holding an I/O relevant file system lock. That allows the file cache to prepare the pages without colliding with the page writer, IOW the "mayBlock" flag can go into the attic again (yay!). * This also results in a much better performance when the system does I/O and is low on memory, as the page writer can now finally write back some pages, and that even without maxing out the CPU :) * The API changes put slightly more burden on the fs_{read|write}_pages() hooks, but in combination with the file_map it's still pretty straight forward. It just will have to dispatch the call to the underlying device directly, usually it will just call its fs_{read|write}_pages() hooks via the above mentioned calls. * Ported BFS and FAT to the new API, the latter has not been tested, though. * Also ported the API changes to the fs_shell. I also completely removed its file cache level page handling - the downside is that device access is no longer cached (ie. depends on the host OS now), the upside is that the code is greatly simplified. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22886 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-11-11 00:19:52 +03:00
extern void file_map_delete(void *_map);
extern void file_map_set_size(void *_map, off_t size);
extern void file_map_invalidate(void *_map, off_t offset, off_t size);
extern status_t file_map_set_mode(void *_map, uint32 mode);
* Extracted file_map API out of the file cache - it's now an optional service that can be used by file systems. * Changed the way the file cache works: instead of reading/writing to the underlying device directly, it can now be used for any data source, ie. also network file systems. * As a result, the former pages_io() moved to the VFS layer, and can now be called by a file system via {read|write}_file_io_vec_pages() (naming suggestions are always welcomed :-)). It now gets an FD, and uses that to communicate with the device (via its fs_{read|write}_pages() hooks). * The file_cache_{read|write}() functions must now be called without holding an I/O relevant file system lock. That allows the file cache to prepare the pages without colliding with the page writer, IOW the "mayBlock" flag can go into the attic again (yay!). * This also results in a much better performance when the system does I/O and is low on memory, as the page writer can now finally write back some pages, and that even without maxing out the CPU :) * The API changes put slightly more burden on the fs_{read|write}_pages() hooks, but in combination with the file_map it's still pretty straight forward. It just will have to dispatch the call to the underlying device directly, usually it will just call its fs_{read|write}_pages() hooks via the above mentioned calls. * Ported BFS and FAT to the new API, the latter has not been tested, though. * Also ported the API changes to the fs_shell. I also completely removed its file cache level page handling - the downside is that device access is no longer cached (ie. depends on the host OS now), the upside is that the code is greatly simplified. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22886 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-11-11 00:19:52 +03:00
extern status_t file_map_translate(void *_map, off_t offset, size_t size,
struct file_io_vec *vecs, size_t *_count, size_t align);
* Extracted file_map API out of the file cache - it's now an optional service that can be used by file systems. * Changed the way the file cache works: instead of reading/writing to the underlying device directly, it can now be used for any data source, ie. also network file systems. * As a result, the former pages_io() moved to the VFS layer, and can now be called by a file system via {read|write}_file_io_vec_pages() (naming suggestions are always welcomed :-)). It now gets an FD, and uses that to communicate with the device (via its fs_{read|write}_pages() hooks). * The file_cache_{read|write}() functions must now be called without holding an I/O relevant file system lock. That allows the file cache to prepare the pages without colliding with the page writer, IOW the "mayBlock" flag can go into the attic again (yay!). * This also results in a much better performance when the system does I/O and is low on memory, as the page writer can now finally write back some pages, and that even without maxing out the CPU :) * The API changes put slightly more burden on the fs_{read|write}_pages() hooks, but in combination with the file_map it's still pretty straight forward. It just will have to dispatch the call to the underlying device directly, usually it will just call its fs_{read|write}_pages() hooks via the above mentioned calls. * Ported BFS and FAT to the new API, the latter has not been tested, though. * Also ported the API changes to the fs_shell. I also completely removed its file cache level page handling - the downside is that device access is no longer cached (ie. depends on the host OS now), the upside is that the code is greatly simplified. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22886 a95241bf-73f2-0310-859d-f6bbb57e9c96
2007-11-11 00:19:52 +03:00
#ifdef __cplusplus
}
#endif
#endif /* _FS_CACHE_H */