1 |
1026 |
ivang |
/* bdbuf.h -- block device buffer management
|
2 |
|
|
*
|
3 |
|
|
* Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
|
4 |
|
|
* Author: Victor V. Vengerov <vvv@oktet.ru>
|
5 |
|
|
*
|
6 |
|
|
* @(#) bdbuf.h,v 1.3 2002/04/03 13:56:34 joel Exp
|
7 |
|
|
*/
|
8 |
|
|
|
9 |
|
|
#ifndef __RTEMS_LIBBLOCK_BDBUF_H__
|
10 |
|
|
#define __RTEMS_LIBBLOCK_BDBUF_H__
|
11 |
|
|
|
12 |
|
|
#ifdef __cplusplus
|
13 |
|
|
extern "C" {
|
14 |
|
|
#endif
|
15 |
|
|
|
16 |
|
|
#include <rtems.h>
|
17 |
|
|
#include <rtems/libio.h>
|
18 |
|
|
#include <chain.h>
|
19 |
|
|
|
20 |
|
|
#include "rtems/blkdev.h"
|
21 |
|
|
#include "rtems/diskdevs.h"
|
22 |
|
|
|
23 |
|
|
|
24 |
|
|
/*
|
25 |
|
|
* To manage buffers we using Buffer Descriptors.
|
26 |
|
|
* To speed-up buffer lookup descriptors are organized in AVL-Tree.
|
27 |
|
|
* The fields 'dev' and 'block' are search key.
|
28 |
|
|
*/
|
29 |
|
|
|
30 |
|
|
/* Buffer descriptors
|
31 |
|
|
* Descriptors organized in AVL-tree to speedup buffer lookup.
|
32 |
|
|
* dev and block fields are search key in AVL-tree.
|
33 |
|
|
* Modified buffers, free buffers and used buffers linked in 'mod', 'free' and
|
34 |
|
|
* 'lru' chains appropriately.
|
35 |
|
|
*/
|
36 |
|
|
|
37 |
|
|
typedef struct bdbuf_buffer {
|
38 |
|
|
Chain_Node link; /* Link in the lru, mod or free chains */
|
39 |
|
|
|
40 |
|
|
struct bdbuf_avl_node {
|
41 |
|
|
signed char cache; /* Cache */
|
42 |
|
|
|
43 |
|
|
struct bdbuf_buffer* left; /* Left Child */
|
44 |
|
|
struct bdbuf_buffer* right; /* Right Child */
|
45 |
|
|
|
46 |
|
|
signed char bal; /* The balance of the sub-tree */
|
47 |
|
|
} avl;
|
48 |
|
|
|
49 |
|
|
dev_t dev; /* device number */
|
50 |
|
|
blkdev_bnum block; /* block number on the device */
|
51 |
|
|
|
52 |
|
|
char *buffer; /* Pointer to the buffer memory area */
|
53 |
|
|
rtems_status_code status; /* Last I/O operation completion status */
|
54 |
|
|
int error; /* If status != RTEMS_SUCCESSFUL, this field contains
|
55 |
|
|
errno value which can be used by user later */
|
56 |
|
|
boolean modified:1; /* =1 if buffer was modified */
|
57 |
|
|
boolean in_progress:1; /* =1 if exchange with disk is in progress;
|
58 |
|
|
need to wait on semaphore */
|
59 |
|
|
boolean actual:1; /* Buffer contains actual data */
|
60 |
|
|
int use_count; /* Usage counter; incremented when somebody use
|
61 |
|
|
this buffer; decremented when buffer released
|
62 |
|
|
without modification or when buffer is flushed
|
63 |
|
|
by swapout task */
|
64 |
|
|
|
65 |
|
|
rtems_bdpool_id pool; /* Identifier of buffer pool to which this buffer
|
66 |
|
|
belongs */
|
67 |
|
|
CORE_mutex_Control transfer_sema;
|
68 |
|
|
/* Transfer operation semaphore */
|
69 |
|
|
} bdbuf_buffer;
|
70 |
|
|
|
71 |
|
|
|
72 |
|
|
|
73 |
|
|
/* bdbuf_config structure describes block configuration (size,
|
74 |
|
|
* amount, memory location) for buffering layer
|
75 |
|
|
*/
|
76 |
|
|
typedef struct rtems_bdbuf_config {
|
77 |
|
|
int size; /* Size of block */
|
78 |
|
|
int num; /* Number of blocks of appropriate size */
|
79 |
|
|
char *mem_area; /* Pointer to the blocks location or NULL, in this
|
80 |
|
|
case memory for blocks will be allocated by
|
81 |
|
|
Buffering Layer with the help of RTEMS partition
|
82 |
|
|
manager */
|
83 |
|
|
} rtems_bdbuf_config;
|
84 |
|
|
|
85 |
|
|
extern rtems_bdbuf_config rtems_bdbuf_configuration[];
|
86 |
|
|
extern int rtems_bdbuf_configuration_size;
|
87 |
|
|
|
88 |
|
|
/* rtems_bdbuf_init --
|
89 |
|
|
* Prepare buffering layer to work - initialize buffer descritors
|
90 |
|
|
* and (if it is neccessary) buffers. Buffers will be allocated accoriding
|
91 |
|
|
* to the configuration table, each entry describes kind of block and
|
92 |
|
|
* amount requested. After initialization all blocks is placed into
|
93 |
|
|
* free elements lists.
|
94 |
|
|
*
|
95 |
|
|
* PARAMETERS:
|
96 |
|
|
* conf_table - pointer to the buffers configuration table
|
97 |
|
|
* size - number of entries in configuration table
|
98 |
|
|
*
|
99 |
|
|
* RETURNS:
|
100 |
|
|
* RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
|
101 |
|
|
* or error code if error is occured)
|
102 |
|
|
*/
|
103 |
|
|
rtems_status_code
|
104 |
|
|
rtems_bdbuf_init(rtems_bdbuf_config *conf_table, int size);
|
105 |
|
|
|
106 |
|
|
|
107 |
|
|
/* rtems_bdbuf_get --
|
108 |
|
|
* Obtain block buffer. If specified block already cached (i.e. there's
|
109 |
|
|
* block in the _modified_, or _recently_used_), return address
|
110 |
|
|
* of appropriate buffer descriptor and increment reference counter to 1.
|
111 |
|
|
* If block is not cached, allocate new buffer and return it. Data
|
112 |
|
|
* shouldn't be read to the buffer from media; buffer may contains
|
113 |
|
|
* arbitrary data. This primitive may be blocked if there are no free
|
114 |
|
|
* buffer descriptors available and there are no unused non-modified
|
115 |
|
|
* (or synchronized with media) buffers available.
|
116 |
|
|
*
|
117 |
|
|
* PARAMETERS:
|
118 |
|
|
* device - device number (constructed of major and minor device number)
|
119 |
|
|
* block - linear media block number
|
120 |
|
|
* bd - address of variable to store pointer to the buffer descriptor
|
121 |
|
|
*
|
122 |
|
|
* RETURNS:
|
123 |
|
|
* RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
|
124 |
|
|
* or error code if error is occured)
|
125 |
|
|
*
|
126 |
|
|
* SIDE EFFECTS:
|
127 |
|
|
* bufget_sema semaphore obtained by this primitive.
|
128 |
|
|
*/
|
129 |
|
|
rtems_status_code
|
130 |
|
|
rtems_bdbuf_get(dev_t device, blkdev_bnum block, bdbuf_buffer **bdb_ptr);
|
131 |
|
|
|
132 |
|
|
/* rtems_bdbuf_read --
|
133 |
|
|
* (Similar to the rtems_bdbuf_get, except reading data from media)
|
134 |
|
|
* Obtain block buffer. If specified block already cached, return address
|
135 |
|
|
* of appropriate buffer and increment reference counter to 1. If block is
|
136 |
|
|
* not cached, allocate new buffer and read data to it from the media.
|
137 |
|
|
* This primitive may be blocked on waiting until data to be read from
|
138 |
|
|
* media, if there are no free buffer descriptors available and there are
|
139 |
|
|
* no unused non-modified (or synchronized with media) buffers available.
|
140 |
|
|
*
|
141 |
|
|
* PARAMETERS:
|
142 |
|
|
* device - device number (consists of major and minor device number)
|
143 |
|
|
* block - linear media block number
|
144 |
|
|
* bd - address of variable to store pointer to the buffer descriptor
|
145 |
|
|
*
|
146 |
|
|
* RETURNS:
|
147 |
|
|
* RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
|
148 |
|
|
* or error code if error is occured)
|
149 |
|
|
*
|
150 |
|
|
* SIDE EFFECTS:
|
151 |
|
|
* bufget_sema and transfer_sema semaphores obtained by this primitive.
|
152 |
|
|
*/
|
153 |
|
|
rtems_status_code
|
154 |
|
|
rtems_bdbuf_read(dev_t device, blkdev_bnum block, bdbuf_buffer **bdb_ptr);
|
155 |
|
|
|
156 |
|
|
/* rtems_bdbuf_release --
|
157 |
|
|
* Release buffer allocated before. This primitive decrease the
|
158 |
|
|
* usage counter. If it is zero, further destiny of buffer depends on
|
159 |
|
|
* 'modified' status. If buffer was modified, it is placed to the end of
|
160 |
|
|
* mod list and flush task waken up. If buffer was not modified,
|
161 |
|
|
* it is placed to the end of lru list, and bufget_sema released, allowing
|
162 |
|
|
* to reuse this buffer.
|
163 |
|
|
*
|
164 |
|
|
* PARAMETERS:
|
165 |
|
|
* bd_buf - pointer to the bdbuf_buffer structure previously obtained using
|
166 |
|
|
* get/read primitive.
|
167 |
|
|
*
|
168 |
|
|
* RETURNS:
|
169 |
|
|
* RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
|
170 |
|
|
* or error code if error is occured)
|
171 |
|
|
*
|
172 |
|
|
* SIDE EFFECTS:
|
173 |
|
|
* flush_sema and bufget_sema semaphores may be released by this primitive.
|
174 |
|
|
*/
|
175 |
|
|
rtems_status_code
|
176 |
|
|
rtems_bdbuf_release(bdbuf_buffer *bd_buf);
|
177 |
|
|
|
178 |
|
|
/* rtems_bdbuf_release_modified --
|
179 |
|
|
* Release buffer allocated before, assuming that it is _modified_ by
|
180 |
|
|
* it's owner. This primitive decrease usage counter for buffer, mark
|
181 |
|
|
* buffer descriptor as modified. If usage counter is 0, insert it at
|
182 |
|
|
* end of mod chain and release flush_sema semaphore to activate the
|
183 |
|
|
* flush task.
|
184 |
|
|
*
|
185 |
|
|
* PARAMETERS:
|
186 |
|
|
* bd_buf - pointer to the bdbuf_buffer structure previously obtained using
|
187 |
|
|
* get/read primitive.
|
188 |
|
|
*
|
189 |
|
|
* RETURNS:
|
190 |
|
|
* RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
|
191 |
|
|
* or error code if error is occured)
|
192 |
|
|
*
|
193 |
|
|
* SIDE EFFECTS:
|
194 |
|
|
* flush_sema semaphore may be released by this primitive.
|
195 |
|
|
*/
|
196 |
|
|
rtems_status_code
|
197 |
|
|
rtems_bdbuf_release_modified(bdbuf_buffer *bd_buf);
|
198 |
|
|
|
199 |
|
|
/* rtems_bdbuf_sync --
|
200 |
|
|
* Wait until specified buffer synchronized with disk. Invoked on exchanges
|
201 |
|
|
* critical for data consistency on the media. This primitive mark owned
|
202 |
|
|
* block as modified, decrease usage counter. If usage counter is 0,
|
203 |
|
|
* block inserted to the mod chain and flush_sema semaphore released.
|
204 |
|
|
* Finally, primitives blocked on transfer_sema semaphore.
|
205 |
|
|
*
|
206 |
|
|
* PARAMETERS:
|
207 |
|
|
* bd_buf - pointer to the bdbuf_buffer structure previously obtained using
|
208 |
|
|
* get/read primitive.
|
209 |
|
|
*
|
210 |
|
|
* RETURNS:
|
211 |
|
|
* RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
|
212 |
|
|
* or error code if error is occured)
|
213 |
|
|
*
|
214 |
|
|
* SIDE EFFECTS:
|
215 |
|
|
* Primitive may be blocked on transfer_sema semaphore.
|
216 |
|
|
*/
|
217 |
|
|
rtems_status_code
|
218 |
|
|
rtems_bdbuf_sync(bdbuf_buffer *bd_buf);
|
219 |
|
|
|
220 |
|
|
/* rtems_bdbuf_syncdev --
|
221 |
|
|
* Synchronize with disk all buffers containing the blocks belonging to
|
222 |
|
|
* specified device.
|
223 |
|
|
*
|
224 |
|
|
* PARAMETERS:
|
225 |
|
|
* dev - block device number
|
226 |
|
|
*
|
227 |
|
|
* RETURNS:
|
228 |
|
|
* RTEMS status code (RTEMS_SUCCESSFUL if operation completed successfully
|
229 |
|
|
* or error code if error is occured)
|
230 |
|
|
*/
|
231 |
|
|
rtems_status_code
|
232 |
|
|
rtems_bdbuf_syncdev(dev_t dev);
|
233 |
|
|
|
234 |
|
|
/* rtems_bdbuf_find_pool --
|
235 |
|
|
* Find first appropriate buffer pool. This primitive returns the index
|
236 |
|
|
* of first buffer pool which block size is greater than or equal to
|
237 |
|
|
* specified size.
|
238 |
|
|
*
|
239 |
|
|
* PARAMETERS:
|
240 |
|
|
* block_size - requested block size
|
241 |
|
|
* pool - placeholder for result
|
242 |
|
|
*
|
243 |
|
|
* RETURNS:
|
244 |
|
|
* RTEMS status code: RTEMS_SUCCESSFUL if operation completed successfully,
|
245 |
|
|
* RTEMS_INVALID_SIZE if specified block size is invalid (not a power
|
246 |
|
|
* of 2), RTEMS_NOT_DEFINED if buffer pool for this or greater block size
|
247 |
|
|
* is not configured.
|
248 |
|
|
*/
|
249 |
|
|
rtems_status_code
|
250 |
|
|
rtems_bdbuf_find_pool(int block_size, rtems_bdpool_id *pool);
|
251 |
|
|
|
252 |
|
|
/* rtems_bdbuf_get_pool_info --
|
253 |
|
|
* Obtain characteristics of buffer pool with specified number.
|
254 |
|
|
*
|
255 |
|
|
* PARAMETERS:
|
256 |
|
|
* pool - buffer pool number
|
257 |
|
|
* block_size - block size for which buffer pool is configured returned
|
258 |
|
|
* there
|
259 |
|
|
* blocks - number of buffers in buffer pool returned there
|
260 |
|
|
*
|
261 |
|
|
* RETURNS:
|
262 |
|
|
* RTEMS status code: RTEMS_SUCCESSFUL if operation completed successfully,
|
263 |
|
|
* RTEMS_INVALID_NUMBER if appropriate buffer pool is not configured.
|
264 |
|
|
*
|
265 |
|
|
* NOTE:
|
266 |
|
|
* Buffer pools enumerated contiguously starting from 0.
|
267 |
|
|
*/
|
268 |
|
|
rtems_status_code
|
269 |
|
|
rtems_bdbuf_get_pool_info(rtems_bdpool_id pool, int *block_size, int *blocks);
|
270 |
|
|
|
271 |
|
|
#ifdef __cplusplus
|
272 |
|
|
}
|
273 |
|
|
#endif
|
274 |
|
|
|
275 |
|
|
#endif
|