2007-04-25 16:07:30 +04:00
|
|
|
/*
|
2008-01-13 20:18:29 +03:00
|
|
|
* Copyright 2004-2008, Haiku Inc. All Rights Reserved.
|
2004-11-12 19:35:24 +03:00
|
|
|
* Distributed under the terms of the MIT License.
|
|
|
|
*/
|
2004-09-04 21:15:22 +04:00
|
|
|
#ifndef _FS_CACHE_H
|
|
|
|
#define _FS_CACHE_H
|
|
|
|
|
2007-07-05 18:48:16 +04:00
|
|
|
/*! File System File and Block Caches */
|
2007-04-25 16:07:30 +04:00
|
|
|
|
2004-09-04 21:15:22 +04:00
|
|
|
|
|
|
|
#include <fs_interface.h>
|
|
|
|
|
|
|
|
|
2008-04-03 18:14:27 +04:00
|
|
|
/* transaction events */
|
2008-01-13 20:18:29 +03:00
|
|
|
enum {
|
2008-04-03 18:14:27 +04:00
|
|
|
TRANSACTION_WRITTEN = 0x01,
|
|
|
|
TRANSACTION_ABORTED = 0x02,
|
|
|
|
TRANSACTION_ENDED = 0x04,
|
|
|
|
TRANSACTION_IDLE = 0x08
|
2008-01-13 20:18:29 +03:00
|
|
|
};
|
|
|
|
|
2008-08-04 12:28:17 +04:00
|
|
|
/* file map modes */
|
|
|
|
enum {
|
|
|
|
FILE_MAP_CACHE_ON_DEMAND = 0x01, /* default mode */
|
|
|
|
FILE_MAP_CACHE_ALL = 0x02
|
|
|
|
};
|
|
|
|
|
2008-01-13 20:18:29 +03:00
|
|
|
typedef void (*transaction_notification_hook)(int32 id, int32 event,
|
|
|
|
void *data);
|
2004-11-10 04:57:38 +03:00
|
|
|
|
2004-09-04 21:15:22 +04:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
2008-04-02 13:37:22 +04:00
|
|
|
#endif
|
2004-09-04 21:15:22 +04:00
|
|
|
|
2004-11-10 04:57:38 +03:00
|
|
|
/* transactions */
|
2008-11-04 17:49:33 +03:00
|
|
|
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,
|
2007-02-25 02:05:18 +03:00
|
|
|
transaction_notification_hook hook, void *data);
|
2008-11-04 17:49:33 +03:00
|
|
|
extern status_t cache_abort_transaction(void *cache, int32 id);
|
|
|
|
extern int32 cache_detach_sub_transaction(void *cache, int32 id,
|
2007-02-25 02:05:18 +03:00
|
|
|
transaction_notification_hook hook, void *data);
|
2008-11-04 17:49:33 +03:00
|
|
|
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,
|
2008-04-03 18:14:27 +04:00
|
|
|
int32 events, transaction_notification_hook hook,
|
|
|
|
void *data);
|
2008-11-04 17:49:33 +03:00
|
|
|
extern status_t cache_remove_transaction_listener(void *cache, int32 id,
|
2008-01-13 20:18:29 +03:00
|
|
|
transaction_notification_hook hook, void *data);
|
2008-11-04 17:49:33 +03:00
|
|
|
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);
|
2008-11-04 17:49:33 +03:00
|
|
|
extern int32 cache_blocks_in_transaction(void *cache, int32 id);
|
|
|
|
extern int32 cache_blocks_in_main_transaction(void *cache, int32 id);
|
|
|
|
extern int32 cache_blocks_in_sub_transaction(void *cache, int32 id);
|
2004-11-10 04:57:38 +03:00
|
|
|
|
|
|
|
/* block cache */
|
2008-11-04 17:49:33 +03:00
|
|
|
extern void block_cache_delete(void *cache, bool allowWrites);
|
2007-02-25 02:05:18 +03:00
|
|
|
extern void *block_cache_create(int fd, off_t numBlocks, size_t blockSize,
|
|
|
|
bool readOnly);
|
2008-11-04 17:49:33 +03:00
|
|
|
extern status_t block_cache_sync(void *cache);
|
|
|
|
extern status_t block_cache_sync_etc(void *cache, off_t blockNumber,
|
2007-04-25 16:07:30 +04:00
|
|
|
size_t numBlocks);
|
2008-11-04 17:49:33 +03:00
|
|
|
extern void block_cache_discard(void *cache, off_t blockNumber,
|
|
|
|
size_t numBlocks);
|
|
|
|
extern status_t block_cache_make_writable(void *cache, off_t blockNumber,
|
2007-02-25 02:05:18 +03:00
|
|
|
int32 transaction);
|
2008-11-04 17:49:33 +03:00
|
|
|
extern void *block_cache_get_writable_etc(void *cache, off_t blockNumber,
|
2007-02-25 02:05:18 +03:00
|
|
|
off_t base, off_t length, int32 transaction);
|
2008-11-04 17:49:33 +03:00
|
|
|
extern void *block_cache_get_writable(void *cache, off_t blockNumber,
|
2007-02-25 02:05:18 +03:00
|
|
|
int32 transaction);
|
2008-11-04 17:49:33 +03:00
|
|
|
extern void *block_cache_get_empty(void *cache, off_t blockNumber,
|
2007-02-25 02:05:18 +03:00
|
|
|
int32 transaction);
|
2008-11-04 17:49:33 +03:00
|
|
|
extern const void *block_cache_get_etc(void *cache, off_t blockNumber,
|
2007-02-25 02:05:18 +03:00
|
|
|
off_t base, off_t length);
|
2008-11-04 17:49:33 +03:00
|
|
|
extern const void *block_cache_get(void *cache, off_t blockNumber);
|
|
|
|
extern status_t block_cache_set_dirty(void *cache, off_t blockNumber,
|
2007-02-25 02:05:18 +03:00
|
|
|
bool isDirty, int32 transaction);
|
2008-11-04 17:49:33 +03:00
|
|
|
extern void block_cache_put(void *cache, off_t blockNumber);
|
2004-11-10 04:57:38 +03:00
|
|
|
|
2004-09-04 21:15:22 +04:00
|
|
|
/* 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);
|
2008-11-04 17:49:33 +03:00
|
|
|
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);
|
|
|
|
|
|
|
|
extern status_t file_cache_read(void *cacheRef, void *cookie, off_t offset,
|
* 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
|
|
|
void *bufferBase, size_t *_size);
|
2008-11-04 17:49:33 +03:00
|
|
|
extern status_t file_cache_write(void *cacheRef, void *cookie, off_t offset,
|
2007-02-25 02:05:18 +03:00
|
|
|
const void *buffer, size_t *_size);
|
2004-09-04 21:15:22 +04:00
|
|
|
|
* 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 */
|
2007-11-13 13:34:48 +03:00
|
|
|
extern void *file_map_create(dev_t mountID, ino_t vnodeID, off_t size);
|
2008-11-04 17:49:33 +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);
|
|
|
|
extern status_t file_map_translate(void *map, off_t offset, size_t size,
|
2008-08-31 03:06:28 +04:00
|
|
|
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
|
|
|
|
2008-09-08 09:08:37 +04:00
|
|
|
/* entry cache */
|
|
|
|
extern status_t entry_cache_add(dev_t mountID, ino_t dirID, const char* name,
|
|
|
|
ino_t nodeID);
|
|
|
|
extern status_t entry_cache_remove(dev_t mountID, ino_t dirID,
|
|
|
|
const char* name);
|
|
|
|
|
2004-09-04 21:15:22 +04:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
2008-04-02 13:37:22 +04:00
|
|
|
#endif
|
2004-09-04 21:15:22 +04:00
|
|
|
|
|
|
|
#endif /* _FS_CACHE_H */
|