1/*
2	Copyright 1999-2001, Be Incorporated.   All Rights Reserved.
3	This file may be used under the terms of the Be Sample Code License.
4*/
5
6#ifndef _CACHE_H_
7#define _CACHE_H_
8
9#include <BeBuild.h>
10
11typedef struct hash_ent {
12	int              dev;
13	off_t            bnum;
14	off_t            hash_val;
15	void            *data;
16	struct hash_ent *next;
17} hash_ent;
18
19
20typedef struct hash_table {
21    hash_ent **table;
22    int        max;
23    int        mask;          /* == max - 1 */
24    int        num_elements;
25} hash_table;
26
27
28#define HT_DEFAULT_MAX   128
29
30
31typedef struct cache_ent {
32	int               dev;
33	off_t             block_num;
34	int               bsize;
35	volatile int      flags;
36
37	void             *data;
38	void             *clone;         /* copy of data by set_block_info() */
39	int               lock;
40
41	void            (*func)(off_t bnum, size_t num_blocks, void *arg);
42	off_t             logged_bnum;
43	void             *arg;
44
45	struct cache_ent *next,          /* points toward mru end of list */
46	                 *prev;          /* points toward lru end of list */
47
48} cache_ent;
49
50#define CE_NORMAL    0x0000     /* a nice clean pristine page */
51#define CE_DIRTY     0x0002     /* needs to be written to disk */
52#define CE_BUSY      0x0004     /* this block has i/o happening, don't touch it */
53
54
55typedef struct cache_ent_list {
56	cache_ent *lru;              /* tail of the list */
57	cache_ent *mru;              /* head of the list */
58} cache_ent_list;
59
60
61typedef struct block_cache {
62	struct lock		lock;
63	int			 	flags;
64    int				cur_blocks;
65	int				max_blocks;
66	hash_table		ht;
67
68	cache_ent_list	normal,       /* list of "normal" blocks (clean & dirty) */
69					locked;       /* list of clean and locked blocks */
70} block_cache;
71
72#if 0   /* XXXdbg -- need to deal with write through caches */
73#define DC_WRITE_THROUGH    0x0001  /* cache is write-through (for floppies) */
74#endif
75
76#define ALLOW_WRITES  1
77#define NO_WRITES     0
78
79extern _IMPEXP_KERNEL int   init_block_cache(int max_blocks, int flags);
80extern _IMPEXP_KERNEL void  shutdown_block_cache(void);
81
82extern _IMPEXP_KERNEL void  force_cache_flush(int dev, int prefer_log_blocks);
83extern _IMPEXP_KERNEL int   flush_blocks(int dev, off_t bnum, int nblocks);
84extern _IMPEXP_KERNEL int   flush_device(int dev, int warn_locked);
85
86extern _IMPEXP_KERNEL int   init_cache_for_device(int fd, off_t max_blocks);
87extern _IMPEXP_KERNEL int   remove_cached_device_blocks(int dev, int allow_write);
88
89extern _IMPEXP_KERNEL void *get_block(int dev, off_t bnum, int bsize);
90extern _IMPEXP_KERNEL void *get_empty_block(int dev, off_t bnum, int bsize);
91extern _IMPEXP_KERNEL int   release_block(int dev, off_t bnum);
92extern _IMPEXP_KERNEL int   mark_blocks_dirty(int dev, off_t bnum, int nblocks);
93
94
95extern _IMPEXP_KERNEL int  cached_read(int dev, off_t bnum, void *data, off_t num_blocks, int bsize);
96extern _IMPEXP_KERNEL int  cached_write(int dev, off_t bnum, const void *data,
97				  off_t num_blocks, int bsize);
98extern _IMPEXP_KERNEL int  cached_write_locked(int dev, off_t bnum, const void *data,
99						 off_t num_blocks, int bsize);
100extern _IMPEXP_KERNEL int  set_blocks_info(int dev, off_t *blocks, int nblocks,
101					 void (*func)(off_t bnum, size_t nblocks, void *arg),
102					 void *arg);
103
104
105extern _IMPEXP_KERNEL size_t read_phys_blocks (int fd, off_t bnum, void *data, uint num_blocks, int bsize);
106extern _IMPEXP_KERNEL size_t write_phys_blocks(int fd, off_t bnum, void *data, uint num_blocks, int bsize);
107
108#endif /* _CACHE_H_ */
109