1285612Sdelphij/*
2181834Sroberto	Copyright 1999-2001, Be Incorporated.   All Rights Reserved.
3285612Sdelphij	This file may be used under the terms of the Be Sample Code License.
4285612Sdelphij*/
5285612Sdelphij
6285612Sdelphij#ifndef _CACHE_H_
7285612Sdelphij#define _CACHE_H_
8285612Sdelphij
9285612Sdelphij#include <BeBuild.h>
10285612Sdelphij
11285612Sdelphijtypedef struct hash_ent {
12285612Sdelphij	int              dev;
13285612Sdelphij	off_t            bnum;
14285612Sdelphij	off_t            hash_val;
15285612Sdelphij	void            *data;
16285612Sdelphij	struct hash_ent *next;
17285612Sdelphij} hash_ent;
18285612Sdelphij
19285612Sdelphij
20285612Sdelphijtypedef struct hash_table {
21285612Sdelphij    hash_ent **table;
22285612Sdelphij    int        max;
23285612Sdelphij    int        mask;          /* == max - 1 */
24285612Sdelphij    int        num_elements;
25285612Sdelphij} hash_table;
26285612Sdelphij
27285612Sdelphij
28285612Sdelphij#define HT_DEFAULT_MAX   128
29285612Sdelphij
30285612Sdelphij
31181834Srobertotypedef struct cache_ent {
32285612Sdelphij	int               dev;
33181834Sroberto	off_t             block_num;
34181834Sroberto	int               bsize;
35181834Sroberto	volatile int      flags;
36181834Sroberto
37181834Sroberto	void             *data;
38181834Sroberto	void             *clone;         /* copy of data by set_block_info() */
39285612Sdelphij	int               lock;
40181834Sroberto
41181834Sroberto	void            (*func)(off_t bnum, size_t num_blocks, void *arg);
42285612Sdelphij	off_t             logged_bnum;
43181834Sroberto	void             *arg;
44181834Sroberto
45285612Sdelphij	struct cache_ent *next,          /* points toward mru end of list */
46285612Sdelphij	                 *prev;          /* points toward lru end of list */
47285612Sdelphij
48285612Sdelphij} cache_ent;
49285612Sdelphij
50285612Sdelphij#define CE_NORMAL    0x0000     /* a nice clean pristine page */
51181834Sroberto#define CE_DIRTY     0x0002     /* needs to be written to disk */
52181834Sroberto#define CE_BUSY      0x0004     /* this block has i/o happening, don't touch it */
53181834Sroberto
54285612Sdelphij
55285612Sdelphijtypedef struct cache_ent_list {
56181834Sroberto	cache_ent *lru;              /* tail of the list */
57285612Sdelphij	cache_ent *mru;              /* head of the list */
58285612Sdelphij} cache_ent_list;
59181834Sroberto
60285612Sdelphij
61181834Srobertotypedef struct block_cache {
62285612Sdelphij	struct lock		lock;
63285612Sdelphij	int			 	flags;
64285612Sdelphij    int				cur_blocks;
65181834Sroberto	int				max_blocks;
66285612Sdelphij	hash_table		ht;
67285612Sdelphij
68285612Sdelphij	cache_ent_list	normal,       /* list of "normal" blocks (clean & dirty) */
69285612Sdelphij					locked;       /* list of clean and locked blocks */
70285612Sdelphij} block_cache;
71285612Sdelphij
72285612Sdelphij#if 0   /* XXXdbg -- need to deal with write through caches */
73285612Sdelphij#define DC_WRITE_THROUGH    0x0001  /* cache is write-through (for floppies) */
74285612Sdelphij#endif
75285612Sdelphij
76285612Sdelphij#define ALLOW_WRITES  1
77285612Sdelphij#define NO_WRITES     0
78285612Sdelphij
79285612Sdelphijextern _IMPEXP_KERNEL int   init_block_cache(int max_blocks, int flags);
80285612Sdelphijextern _IMPEXP_KERNEL void  shutdown_block_cache(void);
81285612Sdelphij
82285612Sdelphijextern _IMPEXP_KERNEL void  force_cache_flush(int dev, int prefer_log_blocks);
83285612Sdelphijextern _IMPEXP_KERNEL int   flush_blocks(int dev, off_t bnum, int nblocks);
84285612Sdelphijextern _IMPEXP_KERNEL int   flush_device(int dev, int warn_locked);
85285612Sdelphij
86285612Sdelphijextern _IMPEXP_KERNEL int   init_cache_for_device(int fd, off_t max_blocks);
87285612Sdelphijextern _IMPEXP_KERNEL int   remove_cached_device_blocks(int dev, int allow_write);
88285612Sdelphij
89285612Sdelphijextern _IMPEXP_KERNEL void *get_block(int dev, off_t bnum, int bsize);
90285612Sdelphijextern _IMPEXP_KERNEL void *get_empty_block(int dev, off_t bnum, int bsize);
91285612Sdelphijextern _IMPEXP_KERNEL int   release_block(int dev, off_t bnum);
92285612Sdelphijextern _IMPEXP_KERNEL int   mark_blocks_dirty(int dev, off_t bnum, int nblocks);
93285612Sdelphij
94285612Sdelphij
95285612Sdelphijextern _IMPEXP_KERNEL int  cached_read(int dev, off_t bnum, void *data, off_t num_blocks, int bsize);
96285612Sdelphijextern _IMPEXP_KERNEL int  cached_write(int dev, off_t bnum, const void *data,
97285612Sdelphij				  off_t num_blocks, int bsize);
98285612Sdelphijextern _IMPEXP_KERNEL int  cached_write_locked(int dev, off_t bnum, const void *data,
99285612Sdelphij						 off_t num_blocks, int bsize);
100285612Sdelphijextern _IMPEXP_KERNEL int  set_blocks_info(int dev, off_t *blocks, int nblocks,
101285612Sdelphij					 void (*func)(off_t bnum, size_t nblocks, void *arg),
102285612Sdelphij					 void *arg);
103285612Sdelphij
104285612Sdelphij
105285612Sdelphijextern _IMPEXP_KERNEL size_t read_phys_blocks (int fd, off_t bnum, void *data, uint num_blocks, int bsize);
106285612Sdelphijextern _IMPEXP_KERNEL size_t write_phys_blocks(int fd, off_t bnum, void *data, uint num_blocks, int bsize);
107285612Sdelphij
108285612Sdelphij#endif /* _CACHE_H_ */
109285612Sdelphij