source: rtems/cpukit/libblock/include/rtems/bdbuf.h @ 796967c

4.115
Last change on this file since 796967c was 796967c, checked in by Sebastian Huber <sebastian.huber@…>, on 02/28/12 at 16:19:49

libblock: Change bdbuf API

The functions

o rtems_bdbuf_get(),
o rtems_bdbuf_read(),
o rtems_bdbuf_syncdev(), and
o rtems_bdbuf_purge_dev(),

use now the disk device instead of the device identifier. This makes
bdbuf independent of rtems_disk_obtain() and rtems_disk_release(). It
is the responsiblity of the file system to obtain the disk device. This
also reduces the overhead to get a buffer.

The key for the AVL tree uses now the disk device instead of the device
identifier. The pointer is interpreted as an unsigned integer. This
reduces the memory overhead and makes the comparison operation a bit
faster.

Removed function rtems_bdbuf_purge_major(). This function was too
destructive and could have unpredictable side effects.

  • Property mode set to 100644
File size: 22.6 KB
RevLine 
[b80dd59d]1/**
[57aa979]2 * @file
[e51bd96]3 *
[4670d91]4 * @ingroup rtems_bdbuf
5 *
[57aa979]6 * Block device buffer management.
[b80dd59d]7 */
[33c3b54d]8
[b80dd59d]9/*
[e51bd96]10 * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
11 * Author: Victor V. Vengerov <vvv@oktet.ru>
12 *
[0d15414e]13 * Copyright (C) 2008,2009 Chris Johns <chrisj@rtems.org>
[c21c850e]14 *    Rewritten to remove score mutex access. Fixes many performance
15 *    issues.
[6d612944]16 *    Change to support demand driven variable buffer sizes.
17 *
[1024561]18 * Copyright (c) 2009-2012 embedded brains GmbH.
[c21c850e]19 *
[3d14a45]20 * @(#) bdbuf.h,v 1.9 2005/02/02 00:06:18 joel Exp
[e51bd96]21 */
22
[a6f5d89]23#ifndef _RTEMS_BDBUF_H
24#define _RTEMS_BDBUF_H
[e51bd96]25
26#include <rtems.h>
27#include <rtems/libio.h>
[ebbe119e]28#include <rtems/chain.h>
[e51bd96]29
[90b2c072]30#include <rtems/blkdev.h>
31#include <rtems/diskdevs.h>
[e51bd96]32
[4f971343]33#ifdef __cplusplus
34extern "C" {
35#endif
[b5b07cad]36
[57aa979]37/**
38 * @defgroup rtems_libblock Block Device Library
[c85ab23]39 *
40 * Block device modules.
[57aa979]41 */
[4f971343]42
[57aa979]43/**
44 * @defgroup rtems_bdbuf Block Device Buffer Management
45 *
46 * @ingroup rtems_libblock
47 *
48 * The Block Device Buffer Management implements a cache between the disk
[6d612944]49 * devices and file systems.  The code provides read ahead and write queuing to
50 * the drivers and fast cache look-up using an AVL tree.
[57aa979]51 *
[0d15414e]52 * The block size used by a file system can be set at runtime and must be a
[6d612944]53 * multiple of the disk device block size.  The disk device's physical block
54 * size is called the media block size.  The file system can set the block size
55 * it uses to a larger multiple of the media block size.  The driver must be
[0d15414e]56 * able to handle buffers sizes larger than one media block.
57 *
58 * The user configures the amount of memory to be used as buffers in the cache,
[6d612944]59 * and the minimum and maximum buffer size.  The cache will allocate additional
60 * memory for the buffer descriptors and groups.  There are enough buffer
[0d15414e]61 * descriptors allocated so all the buffer memory can be used as minimum sized
62 * buffers.
63 *
[6d612944]64 * The cache is a single pool of buffers.  The buffer memory is divided into
[0d15414e]65 * groups where the size of buffer memory allocated to a group is the maximum
[6d612944]66 * buffer size.  A group's memory can be divided down into small buffer sizes
67 * that are a multiple of 2 of the minimum buffer size.  A group is the minimum
68 * allocation unit for buffers of a specific size.  If a buffer of maximum size
69 * is request the group will have a single buffer.  If a buffer of minimum size
[0d15414e]70 * is requested the group is divided into minimum sized buffers and the
[6d612944]71 * remaining buffers are held ready for use.  A group keeps track of which
[0d15414e]72 * buffers are with a file system or driver and groups who have buffer in use
[6d612944]73 * cannot be realloced.  Groups with no buffers in use can be taken and
74 * realloced to a new size.  This is how buffers of different sizes move around
[0d15414e]75 * the cache.
76
[6d612944]77 * The buffers are held in various lists in the cache.  All buffers follow this
[0d15414e]78 * state machine:
[33c3b54d]79 *
[57aa979]80 * @dot
[6d612944]81 * digraph state {
[47c2327]82 *   size="16,8";
[5c587596]83 *   f [label="FREE",style="filled",fillcolor="aquamarine"];
84 *   e [label="EMPTY",style="filled",fillcolor="seagreen"];
[6d612944]85 *   c [label="CACHED",style="filled",fillcolor="chartreuse"];
[5c587596]86 *   ac [label="ACCESS CACHED",style="filled",fillcolor="royalblue"];
[6d612944]87 *   am [label="ACCESS MODIFIED",style="filled",fillcolor="royalblue"];
[5c587596]88 *   ae [label="ACCESS EMPTY",style="filled",fillcolor="royalblue"];
[e7fb54e]89 *   ap [label="ACCESS PURGED",style="filled",fillcolor="royalblue"];
[6d612944]90 *   t [label="TRANSFER",style="filled",fillcolor="red"];
[e7fb54e]91 *   tp [label="TRANSFER PURGED",style="filled",fillcolor="red"];
[6d612944]92 *   s [label="SYNC",style="filled",fillcolor="red"];
93 *   m [label="MODIFIED",style="filled",fillcolor="gold"];
94 *   i [label="INITIAL"];
[33c3b54d]95 *
[6d612944]96 *   legend_transfer [label="Transfer Wake-Up",fontcolor="red",shape="none"];
97 *   legend_access [label="Access Wake-Up",fontcolor="royalblue",shape="none"];
[33c3b54d]98 *
[5c587596]99 *   i -> f [label="Init"];
100 *   f -> e [label="Buffer Recycle"];
101 *   e -> ae [label="Get"];
[e7fb54e]102 *   e -> t [label="Read"];
103 *   e -> f [label="Nobody Waits"];
[5c587596]104 *   c -> ac [label="Get\nRead"];
[e7fb54e]105 *   c -> e [label="Buffer Recycle\nPurge"];
106 *   c -> f [label="Reallocate\nBlock Size Changed"];
[5c587596]107 *   t -> c [label="Transfer Done",color="red",fontcolor="red"];
[e7fb54e]108 *   t -> e [label="Transfer Error",color="red",fontcolor="red"];
109 *   t -> tp [label="Purge"];
110 *   tp -> e [label="Transfer Done\nTransfer Error",color="red",fontcolor="red"];
[6d612944]111 *   m -> t [label="Swapout"];
112 *   m -> s [label="Block Size Changed"];
113 *   m -> am [label="Get\nRead"];
[e7fb54e]114 *   m -> e [label="Purge"];
[5c587596]115 *   ac -> m [label="Release Modified",color="royalblue",fontcolor="royalblue"];
116 *   ac -> s [label="Sync",color="royalblue",fontcolor="royalblue"];
117 *   ac -> c [label="Release",color="royalblue",fontcolor="royalblue"];
[e7fb54e]118 *   ac -> ap [label="Purge"];
[6d612944]119 *   am -> m [label="Release\nRelease Modified",color="royalblue",fontcolor="royalblue"];
120 *   am -> s [label="Sync",color="royalblue",fontcolor="royalblue"];
[e7fb54e]121 *   am -> ap [label="Purge"];
[5c587596]122 *   ae -> m [label="Release Modified",color="royalblue",fontcolor="royalblue"];
123 *   ae -> s [label="Sync",color="royalblue",fontcolor="royalblue"];
[e7fb54e]124 *   ae -> e [label="Release",color="royalblue",fontcolor="royalblue"];
125 *   ae -> ap [label="Purge"];
126 *   ap -> e [label="Release\nRelease Modified\nSync",color="royalblue",fontcolor="royalblue"];
[6d612944]127 *   s -> t [label="Swapout"];
[e7fb54e]128 *   s -> e [label="Purge",color="red",fontcolor="red"];
[57aa979]129 * }
130 * @enddot
[33c3b54d]131 *
[6d612944]132 * Empty or cached buffers are added to the LRU list and removed from this
133 * queue when a caller requests a buffer.  This is referred to as getting a
134 * buffer in the code and the event get in the state diagram.  The buffer is
135 * assigned to a block and inserted to the AVL based on the block/device key.
136 * If the block is to be read by the user and not in the cache it is transfered
137 * from the disk into memory.  If no buffers are on the LRU list the modified
138 * list is checked.  If buffers are on the modified the swap out task will be
[33c3b54d]139 * woken.  The request blocks until a buffer is available for recycle.
[57aa979]140 *
[6d612944]141 * A block being accessed is given to the file system layer and not accessible
142 * to another requester until released back to the cache.  The same goes to a
143 * buffer in the transfer state.  The transfer state means being read or
144 * written.  If the file system has modifed the block and releases it as
[0d15414e]145 * modified it placed on the cache's modified list and a hold timer
[6d612944]146 * initialised.  The buffer is held for the hold time before being written to
147 * disk.  Buffers are held for a configurable period of time on the modified
[57aa979]148 * list as a write sets the state to transfer and this locks the buffer out
[6d612944]149 * from the file system until the write completes.  Buffers are often accessed
[0d15414e]150 * and modified in a series of small updates so if sent to the disk when
151 * released as modified the user would have to block waiting until it had been
[6d612944]152 * written.  This would be a performance problem.
[57aa979]153 *
[6d612944]154 * The code performs multiple block reads and writes.  Multiple block reads or
155 * read ahead increases performance with hardware that supports it.  It also
156 * helps with a large cache as the disk head movement is reduced.  It however
[57aa979]157 * is a speculative operation so excessive use can remove valuable and needed
[6d612944]158 * blocks from the cache.
[57aa979]159 *
[0d15414e]160 * The cache has the following lists of buffers:
[6d612944]161 *  - LRU: Accessed or transfered buffers released in least recently used
162 *  order.  Empty buffers will be placed to the front.
163 *  - Modified: Buffers waiting to be written to disk.
164 *  - Sync: Buffers to be synchronized with the disk.
[57aa979]165 *
[6d612944]166 * A cache look-up will be performed to find a suitable buffer.  A suitable
167 * buffer is one that matches the same allocation size as the device the buffer
168 * is for.  The a buffer's group has no buffers in use with the file system or
169 * driver the group is reallocated.  This means the buffers in the group are
170 * invalidated, resized and placed on the LRU queue.  There is a performance
171 * issue with this design.  The reallocation of a group may forced recently
172 * accessed buffers out of the cache when they should not.  The design should be
173 * change to have groups on a LRU list if they have no buffers in use.
[0d15414e]174 *
[57aa979]175 * @{
176 */
[4f971343]177
[3899a537]178/**
[47c2327]179 * @brief State of a buffer of the cache.
180 *
181 * The state has several implications.  Depending on the state a buffer can be
182 * in the AVL tree, in a list, in use by an entity and a group user or not.
[5c587596]183 *
184 * <table>
185 *   <tr>
186 *     <th>State</th><th>Valid Data</th><th>AVL Tree</th>
187 *     <th>LRU List</th><th>Modified List</th><th>Synchronization List</th>
188 *     <th>Group User</th><th>External User</th>
189 *   </tr>
190 *   <tr>
191 *     <td>FREE</td><td></td><td></td>
192 *     <td>X</td><td></td><td></td><td></td><td></td>
193 *   </tr>
194 *   <tr>
195 *     <td>EMPTY</td><td></td><td>X</td>
[e7fb54e]196 *     <td></td><td></td><td></td><td></td><td></td>
[5c587596]197 *   </tr>
198 *   <tr>
199 *     <td>CACHED</td><td>X</td><td>X</td>
200 *     <td>X</td><td></td><td></td><td></td><td></td>
201 *   </tr>
202 *   <tr>
[e7fb54e]203 *     <td>ACCESS CACHED</td><td>X</td><td>X</td>
204 *     <td></td><td></td><td></td><td>X</td><td>X</td>
205 *   </tr>
206 *   <tr>
207 *     <td>ACCESS MODIFIED</td><td>X</td><td>X</td>
[5c587596]208 *     <td></td><td></td><td></td><td>X</td><td>X</td>
209 *   </tr>
210 *   <tr>
[e7fb54e]211 *     <td>ACCESS EMPTY</td><td></td><td>X</td>
[5c587596]212 *     <td></td><td></td><td></td><td>X</td><td>X</td>
213 *   </tr>
214 *   <tr>
[e7fb54e]215 *     <td>ACCESS PURGED</td><td></td><td>X</td>
[5c587596]216 *     <td></td><td></td><td></td><td>X</td><td>X</td>
217 *   </tr>
218 *   <tr>
219 *     <td>MODIFIED</td><td>X</td><td>X</td>
220 *     <td></td><td>X</td><td></td><td>X</td><td></td>
221 *   </tr>
222 *   <tr>
223 *     <td>SYNC</td><td>X</td><td>X</td>
224 *     <td></td><td></td><td>X</td><td>X</td><td></td>
225 *   </tr>
226 *   <tr>
227 *     <td>TRANSFER</td><td>X</td><td>X</td>
228 *     <td></td><td></td><td></td><td>X</td><td>X</td>
229 *   </tr>
[e7fb54e]230 *   <tr>
231 *     <td>TRANSFER PURGED</td><td></td><td>X</td>
232 *     <td></td><td></td><td></td><td>X</td><td>X</td>
233 *   </tr>
[5c587596]234 * </table>
[e51bd96]235 */
[3899a537]236typedef enum
237{
[6d612944]238  /**
[5c587596]239   * @brief Free.
[6d612944]240   */
[5c587596]241  RTEMS_BDBUF_STATE_FREE = 0,
[6d612944]242
243  /**
[5c587596]244   * @brief Empty.
[6d612944]245   */
[5c587596]246  RTEMS_BDBUF_STATE_EMPTY,
[6d612944]247
248  /**
[47c2327]249   * @brief Cached.
[6d612944]250   */
[47c2327]251  RTEMS_BDBUF_STATE_CACHED,
[6d612944]252
253  /**
[5c587596]254   * @brief Accessed by upper layer with cached data.
[6d612944]255   */
[5c587596]256  RTEMS_BDBUF_STATE_ACCESS_CACHED,
[6d612944]257
258  /**
[5c587596]259   * @brief Accessed by upper layer with modified data.
[6d612944]260   */
261  RTEMS_BDBUF_STATE_ACCESS_MODIFIED,
262
[5c587596]263  /**
264   * @brief Accessed by upper layer with invalid data.
265   */
266  RTEMS_BDBUF_STATE_ACCESS_EMPTY,
267
[e7fb54e]268  /**
269   * @brief Accessed by upper layer with purged data.
270   */
271  RTEMS_BDBUF_STATE_ACCESS_PURGED,
272
[6d612944]273  /**
[47c2327]274   * @brief Modified by upper layer.
[6d612944]275   */
276  RTEMS_BDBUF_STATE_MODIFIED,
277
278  /**
[47c2327]279   * @brief Scheduled for synchronization.
[6d612944]280   */
281  RTEMS_BDBUF_STATE_SYNC,
282
283  /**
[47c2327]284   * @brief In transfer by block device driver.
[6d612944]285   */
[e7fb54e]286  RTEMS_BDBUF_STATE_TRANSFER,
287
288  /**
289   * @brief In transfer by block device driver and purged.
290   */
291  RTEMS_BDBUF_STATE_TRANSFER_PURGED
[3899a537]292} rtems_bdbuf_buf_state;
[e51bd96]293
[0d15414e]294/**
295 * Forward reference to the block.
296 */
297struct rtems_bdbuf_group;
298typedef struct rtems_bdbuf_group rtems_bdbuf_group;
299
[3899a537]300/**
301 * To manage buffers we using buffer descriptors (BD). A BD holds a buffer plus
302 * a range of other information related to managing the buffer in the cache. To
[0d15414e]303 * speed-up buffer lookup descriptors are organized in AVL-Tree. The fields
[796967c]304 * 'dd' and 'block' are search keys.
[e51bd96]305 */
[3899a537]306typedef struct rtems_bdbuf_buffer
307{
[0d15414e]308  rtems_chain_node link;       /**< Link the BD onto a number of lists. */
[e51bd96]309
[3899a537]310  struct rtems_bdbuf_avl_node
311  {
[57aa979]312    struct rtems_bdbuf_buffer* left;   /**< Left Child */
313    struct rtems_bdbuf_buffer* right;  /**< Right Child */
[b5b07cad]314    signed char                cache;  /**< Cache */
[57aa979]315    signed char                bal;    /**< The balance of the sub-tree */
[3899a537]316  } avl;
[e51bd96]317
[796967c]318  const rtems_disk_device *dd;  /**< disk device */
[eb649786]319
[57aa979]320  rtems_blkdev_bnum block;      /**< block number on the device */
[e51bd96]321
[57aa979]322  unsigned char*    buffer;     /**< Pointer to the buffer memory area */
[df6348bb]323
[c42b03f4]324  rtems_bdbuf_buf_state state;           /**< State of the buffer. */
[048dcd2b]325
[c42b03f4]326  uint32_t waiters;              /**< The number of threads waiting on this
[0d15414e]327                                  * buffer. */
328  rtems_bdbuf_group* group;      /**< Pointer to the group of BDs this BD is
329                                  * part of. */
[c42b03f4]330  uint32_t hold_timer;           /**< Timer to indicate how long a buffer
[0d15414e]331                                  * has been held in the cache modified. */
[eb649786]332
333  int   references;              /**< Allow reference counting by owner. */
334  void* user;                    /**< User data. */
[3899a537]335} rtems_bdbuf_buffer;
[e51bd96]336
[3899a537]337/**
[0d15414e]338 * A group is a continuous block of buffer descriptors. A group covers the
339 * maximum configured buffer size and is the allocation size for the buffers to
340 * a specific buffer size. If you allocate a buffer to be a specific size, all
341 * buffers in the group, if there are more than 1 will also be that size. The
342 * number of buffers in a group is a multiple of 2, ie 1, 2, 4, 8, etc.
[3899a537]343 */
[0d15414e]344struct rtems_bdbuf_group
[3899a537]345{
[0d15414e]346  rtems_chain_node    link;          /**< Link the groups on a LRU list if they
347                                      * have no buffers in use. */
348  size_t              bds_per_group; /**< The number of BD allocated to this
349                                      * group. This value must be a multiple of
350                                      * 2. */
351  uint32_t            users;         /**< How many users the block has. */
352  rtems_bdbuf_buffer* bdbuf;         /**< First BD this block covers. */
353};
[3899a537]354
355/**
356 * Buffering configuration definition. See confdefs.h for support on using this
357 * structure.
[e51bd96]358 */
359typedef struct rtems_bdbuf_config {
[0d15414e]360  uint32_t            max_read_ahead_blocks;   /**< Number of blocks to read
361                                                * ahead. */
362  uint32_t            max_write_blocks;        /**< Number of blocks to write
363                                                * at once. */
364  rtems_task_priority swapout_priority;        /**< Priority of the swap out
365                                                * task. */
366  uint32_t            swapout_period;          /**< Period swapout checks buf
367                                                * timers. */
368  uint32_t            swap_block_hold;         /**< Period a buffer is held. */
[b36a7d8]369  size_t              swapout_workers;         /**< The number of worker
[0d15414e]370                                                * threads for the swapout
371                                                * task. */
372  rtems_task_priority swapout_worker_priority; /**< Priority of the swap out
373                                                * task. */
374  size_t              size;                    /**< Size of memory in the
375                                                * cache */
376  uint32_t            buffer_min;              /**< Minimum buffer size. */
377  uint32_t            buffer_max;              /**< Maximum buffer size
378                                                * supported. It is also the
379                                                * allocation size. */
[e51bd96]380} rtems_bdbuf_config;
381
[3899a537]382/**
[57aa979]383 * External reference to the configuration.
384 *
385 * The configuration is provided by the application.
[3899a537]386 */
[0d15414e]387extern const rtems_bdbuf_config rtems_bdbuf_configuration;
[e51bd96]388
[3899a537]389/**
390 * The max_read_ahead_blocks value is altered if there are fewer buffers
391 * than this defined max. This stops thrashing in the cache.
392 */
[6d612944]393#define RTEMS_BDBUF_MAX_READ_AHEAD_BLOCKS_DEFAULT    0
[57aa979]394
395/**
396 * Default maximum number of blocks to write at once.
397 */
[3899a537]398#define RTEMS_BDBUF_MAX_WRITE_BLOCKS_DEFAULT         16
[57aa979]399
400/**
401 * Default swap-out task priority.
402 */
[3899a537]403#define RTEMS_BDBUF_SWAPOUT_TASK_PRIORITY_DEFAULT    15
[57aa979]404
405/**
406 * Default swap-out task swap period in milli seconds.
407 */
408#define RTEMS_BDBUF_SWAPOUT_TASK_SWAP_PERIOD_DEFAULT 250
409
410/**
411 * Default swap-out task block hold time in milli seconds.
412 */
413#define RTEMS_BDBUF_SWAPOUT_TASK_BLOCK_HOLD_DEFAULT  1000
[c9b005a9]414
[0d15414e]415/**
416 * Default swap-out worker tasks. Currently disabled.
417 */
418#define RTEMS_BDBUF_SWAPOUT_WORKER_TASKS_DEFAULT     0
419
420/**
421 * Default swap-out worker task priority. The same as the swapout task.
422 */
423#define RTEMS_BDBUF_SWAPOUT_WORKER_TASK_PRIORITY_DEFAULT \
424                             RTEMS_BDBUF_SWAPOUT_TASK_PRIORITY_DEFAULT
425
426/**
427 * Default size of memory allocated to the cache.
428 */
429#define RTEMS_BDBUF_CACHE_MEMORY_SIZE_DEFAULT (64 * 512)
430
431/**
432 * Default minimum size of buffers.
433 */
434#define RTEMS_BDBUF_BUFFER_MIN_SIZE_DEFAULT (512)
435
436/**
437 * Default maximum size of buffers.
438 */
439#define RTEMS_BDBUF_BUFFER_MAX_SIZE_DEFAULT (4096)
440
[c21c850e]441/**
442 * Prepare buffering layer to work - initialize buffer descritors and (if it is
[0d15414e]443 * neccessary) buffers. After initialization all blocks is placed into the
444 * ready state.
[e51bd96]445 *
[1024561]446 * @retval RTEMS_SUCCESSFUL Successful operation.
447 * @retval RTEMS_CALLED_FROM_ISR Called from an interrupt context.
448 * @retval RTEMS_INVALID_NUMBER The buffer maximum is not an integral multiple
449 * of the buffer minimum.
450 * @retval RTEMS_RESOURCE_IN_USE Already initialized.
451 * @retval RTEMS_UNSATISFIED Not enough resources.
[e51bd96]452 */
453rtems_status_code
[a5fb40cf]454rtems_bdbuf_init (void);
[e51bd96]455
[c21c850e]456/**
457 * Get block buffer for data to be written into. The buffers is set to the
458 * access or modifed access state. If the buffer is in the cache and modified
459 * the state is access modified else the state is access. This buffer contents
460 * are not initialised if the buffer is not already in the cache. If the block
461 * is already resident in memory it is returned how-ever if not in memory the
462 * buffer is not read from disk. This call is used when writing the whole block
463 * on a disk rather than just changing a part of it. If there is no buffers
464 * available this call will block. A buffer obtained with this call will not be
465 * involved in a transfer request and will not be returned to another user
466 * until released. If the buffer is already with a user when this call is made
467 * the call is blocked until the buffer is returned. The highest priority
468 * waiter will obtain the buffer first.
[e51bd96]469 *
[c21c850e]470 * The block number is the linear block number. This is relative to the start
471 * of the partition on the media.
[e51bd96]472 *
[796967c]473 * @param dd [in] The disk device.
[1024561]474 * @param block [in] Linear media block number.
475 * @param bd [out] Reference to the buffer descriptor pointer.
[e51bd96]476 *
[1024561]477 * @retval RTEMS_SUCCESSFUL Successful operation.
478 * @retval RTEMS_NOT_CONFIGURED Not initialized.
479 * @retval RTEMS_INVALID_ID No such device.
480 * @retval RTEMS_INVALID_NUMBER Invalid block size.
[e51bd96]481 */
[c21c850e]482rtems_status_code
[796967c]483rtems_bdbuf_get (
484  const rtems_disk_device *dd,
485  rtems_blkdev_bnum block,
486  rtems_bdbuf_buffer** bd
487);
[c21c850e]488
489/**
490 * Get the block buffer and if not already in the cache read from the disk. If
491 * specified block already cached return. The buffer is set to the access or
492 * modifed access state. If the buffer is in the cache and modified the state
493 * is access modified else the state is access. If block is already being read
494 * from disk for being written to disk this call blocks. If the buffer is
495 * waiting to be written it is removed from modified queue and returned to the
496 * user. If the buffer is not in the cache a new buffer is obtained and the
497 * data read from disk. The call may block until these operations complete. A
498 * buffer obtained with this call will not be involved in a transfer request
499 * and will not be returned to another user until released. If the buffer is
500 * already with a user when this call is made the call is blocked until the
501 * buffer is returned. The highest priority waiter will obtain the buffer
[33c3b54d]502 * first.
[e51bd96]503 *
[796967c]504 * @param dd [in] The disk device.
[1024561]505 * @param block [in] Linear media block number.
506 * @param bd [out] Reference to the buffer descriptor pointer.
[e51bd96]507 *
[1024561]508 * @retval RTEMS_SUCCESSFUL Successful operation.
509 * @retval RTEMS_NOT_CONFIGURED Not initialized.
510 * @retval RTEMS_INVALID_ID No such device.
511 * @retval RTEMS_INVALID_NUMBER Invalid block size.
512 * @retval RTEMS_IO_ERROR IO error.
[e51bd96]513 */
[c21c850e]514rtems_status_code
[796967c]515rtems_bdbuf_read (
516  const rtems_disk_device *dd,
517  rtems_blkdev_bnum block,
518  rtems_bdbuf_buffer** bd
519);
[c21c850e]520
521/**
522 * Release the buffer obtained by a read call back to the cache. If the buffer
523 * was obtained by a get call and was not already in the cache the release
524 * modified call should be used. A buffer released with this call obtained by a
525 * get call may not be in sync with the contents on disk. If the buffer was in
526 * the cache and modified before this call it will be returned to the modified
527 * queue. The buffers is returned to the end of the LRU list.
[e51bd96]528 *
[1024561]529 * @param bd [in] Reference to the buffer descriptor.
[e51bd96]530 *
[1024561]531 * @retval RTEMS_SUCCESSFUL Successful operation.
532 * @retval RTEMS_NOT_CONFIGURED Not initialized.
533 * @retval RTEMS_INVALID_ADDRESS The reference is NULL.
[e51bd96]534 */
[c21c850e]535rtems_status_code
536rtems_bdbuf_release (rtems_bdbuf_buffer* bd);
537
538/**
539 * Release the buffer allocated with a get or read call placing it on the
[f3ea4992]540 * modified list.  If the buffer was not released modified before the hold
[c21c850e]541 * timer is set to the configuration value. If the buffer had been released
542 * modified before but not written to disk the hold timer is not updated. The
543 * buffer will be written to disk when the hold timer has expired, there are
544 * not more buffers available in the cache and a get or read buffer needs one
545 * or a sync call has been made. If the buffer is obtained with a get or read
546 * before the hold timer has expired the buffer will be returned to the user.
[e51bd96]547 *
[1024561]548 * @param bd [in] Reference to the buffer descriptor.
[e51bd96]549 *
[1024561]550 * @retval RTEMS_SUCCESSFUL Successful operation.
551 * @retval RTEMS_NOT_CONFIGURED Not initialized.
552 * @retval RTEMS_INVALID_ADDRESS The reference is NULL.
[e51bd96]553 */
[c21c850e]554rtems_status_code
555rtems_bdbuf_release_modified (rtems_bdbuf_buffer* bd);
556
557/**
558 * Release the buffer as modified and wait until it has been synchronized with
559 * the disk by writing it. This buffer will be the first to be transfer to disk
560 * and other buffers may also be written if the maximum number of blocks in a
561 * requests allows it.
[e51bd96]562 *
[c21c850e]563 * @note This code does not lock the sync mutex and stop additions to the
564 *       modified queue.
565
[1024561]566 * @param bd [in] Reference to the buffer descriptor.
[e51bd96]567 *
[1024561]568 * @retval RTEMS_SUCCESSFUL Successful operation.
569 * @retval RTEMS_NOT_CONFIGURED Not initialized.
570 * @retval RTEMS_INVALID_ADDRESS The reference is NULL.
[e51bd96]571 */
[c21c850e]572rtems_status_code
573rtems_bdbuf_sync (rtems_bdbuf_buffer* bd);
[e51bd96]574
[c21c850e]575/**
576 * Synchronize all modified buffers for this device with the disk and wait
[0d15414e]577 * until the transfers have completed. The sync mutex for the cache is locked
[c21c850e]578 * stopping the addition of any further modifed buffers. It is only the
579 * currently modified buffers that are written.
[e51bd96]580 *
[0d15414e]581 * @note Nesting calls to sync multiple devices will be handled sequentially. A
582 * nested call will be blocked until the first sync request has complete.
[e51bd96]583 *
[796967c]584 * @param dd [in] The disk device.
[c21c850e]585 *
[1024561]586 * @retval RTEMS_SUCCESSFUL Successful operation.
587 * @retval RTEMS_NOT_CONFIGURED Not initialized.
588 * @retval RTEMS_INVALID_ID No such device.
[e51bd96]589 */
[c21c850e]590rtems_status_code
[796967c]591rtems_bdbuf_syncdev (const rtems_disk_device *dd);
[e51bd96]592
[e7fb54e]593/**
[796967c]594 * @brief Purges all buffers corresponding to the disk device @a dd.
[e7fb54e]595 *
596 * This may result in loss of data.
597 */
598void
[796967c]599rtems_bdbuf_purge_dev (const rtems_disk_device *dd);
[e7fb54e]600
[57aa979]601/** @} */
[e51bd96]602
603#ifdef __cplusplus
604}
605#endif
606
607#endif
Note: See TracBrowser for help on using the repository browser.