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