diff options
Diffstat (limited to 'cpukit/libfs/src/rfs/rtems-rfs-buffer.h')
-rw-r--r-- | cpukit/libfs/src/rfs/rtems-rfs-buffer.h | 262 |
1 files changed, 262 insertions, 0 deletions
diff --git a/cpukit/libfs/src/rfs/rtems-rfs-buffer.h b/cpukit/libfs/src/rfs/rtems-rfs-buffer.h new file mode 100644 index 0000000000..480bce360d --- /dev/null +++ b/cpukit/libfs/src/rfs/rtems-rfs-buffer.h @@ -0,0 +1,262 @@ +/* + * COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ +/** + * @file + * + * @ingroup rtems-rfs + * + * RTEMS File Systems Buffer Management. + * + * These functions map blocks to the media interface layers. + */ + +#if !defined (_RTEMS_RFS_BUFFER_H_) +#define _RTEMS_RFS_BUFFER_H_ + +#include <errno.h> + +#include <rtems/rfs/rtems-rfs-file-system-fwd.h> +#include <rtems/rfs/rtems-rfs-trace.h> + +/** + * Define the method used to interface to the buffers. It can be libblock or + * device I/O. The libblock interface is to the RTEMS cache and block devices + * and device I/O accesses the media via a device file handle. + */ +#if defined (__rtems__) +#define RTEMS_RFS_USE_LIBBLOCK 1 +#endif + +/** + * The RTEMS RFS I/O Layering. + */ +#if RTEMS_RFS_USE_LIBBLOCK +#include <rtems/bdbuf.h> +#include <rtems/error.h> + +typedef rtems_blkdev_bnum rtems_rfs_buffer_block; +typedef rtems_bdbuf_buffer rtems_rfs_buffer; +#define rtems_rfs_buffer_io_request rtems_rfs_buffer_bdbuf_request +#define rtems_rfs_buffer_io_release rtems_rfs_buffer_bdbuf_release + +/** + * Request a buffer from the RTEMS libblock BD buffer cache. + */ +int rtems_rfs_buffer_bdbuf_request (rtems_rfs_file_system* fs, + rtems_rfs_buffer_block block, + bool read, + rtems_rfs_buffer** buffer); +/** + * Release a buffer to the RTEMS libblock BD buffer cache. + */ +int rtems_rfs_buffer_bdbuf_release (rtems_rfs_buffer* handle, + bool modified); +#else /* Device I/O */ +typedef uint32_t rtems_rfs_buffer_block; +typedef struct rtems_rfs_buffer_t +{ + rtems_chain_node link; + rtems_rfs_buffer_block user; + void* buffer; + size_t size; + uint32_t references; +} rtems_rfs_buffer; +#define rtems_rfs_buffer_io_request rtems_rfs_buffer_devceio_request +#define rtems_rfs_buffer_io_release rtems_rfs_uffer_deviceio_release + +/** + * Request a buffer from the device I/O. + */ +int rtems_rfs_buffer_deviceio_request (rtems_rfs_file_system* fs, + rtems_rfs_buffer_block block, + bool read, + rtems_rfs_buffer* buffer); +/** + * Release a buffer to the RTEMS libblock BD buffer cache. + */ +int rtems_rfs_buffer_deviceio_release (rtems_rfs_buffer* handle, + bool modified); +#endif + +/** + * RFS Buffer handle. + */ +typedef struct rtems_rfs_buffer_handle_t +{ + /** + * Has the buffer been modifed? + */ + bool dirty; + + /** + * Block number. The lower layer block number may be absolute and we maybe + * relative to an offset in the disk so hold locally. + */ + rtems_rfs_buffer_block bnum; + + /** + * Reference the buffer descriptor. + */ + rtems_rfs_buffer* buffer; + +} rtems_rfs_buffer_handle; + +/** + * The buffer linkage. + */ +#define rtems_rfs_buffer_link(_h) (&(_h)->buffer->link) + +/** + * Return the start of the data area of the buffer given a handle. + */ +#define rtems_rfs_buffer_data(_h) ((void*)((_h)->buffer->buffer)) + +/** + * Return the size of the buffer given a handle. + */ +#define rtems_rfs_buffer_size(_h) ((_h)->buffer->size) + +/** + * Return the block number. + */ +#define rtems_rfs_buffer_bnum(_h) ((_h)->bnum) + +/** + * Return the buffer dirty status. + */ +#define rtems_rfs_buffer_dirty(_h) ((_h)->dirty) + +/** + * Does the handle have a valid block attached ? + */ +#define rtems_rfs_buffer_handle_has_block(_h) ((_h)->buffer ? true : false) + +/** + * Mark the buffer as dirty. + */ +#define rtems_rfs_buffer_mark_dirty(_h) ((_h)->dirty = true) + +/** + * Return the reference count. + */ +#define rtems_rfs_buffer_refs(_h) ((_h)->buffer->references) + +/** + * Increment the reference count. + */ +#define rtems_rfs_buffer_refs_up(_h) ((_h)->buffer->references += 1) + +/** + * Decrement the reference count. + */ +#define rtems_rfs_buffer_refs_down(_h) ((_h)->buffer->references -= 1) + +/** + * Request a buffer. The buffer can be filled with data from the media (read == + * true) or you can request a buffer to fill with data. + * + * @param fs The file system data. + * @param handle The handle the requested buffer is attached to. + * @param block The block number. + * @param read Read the data from the disk. + * @return int The error number (errno). No error if 0. + */ +int rtems_rfs_buffer_handle_request (rtems_rfs_file_system* fs, + rtems_rfs_buffer_handle* handle, + rtems_rfs_buffer_block block, + bool read); + +/** + * Release a buffer. If the buffer is dirty the buffer is written to disk. The + * result does not indicate if the data was successfully written to the disk as + * this operation may be performed in asynchronously to this release. + * + * @param fs The file system data. + * @param handle The handle the requested buffer is attached to. + * @return int The error number (errno). No error if 0. + */ +int rtems_rfs_buffer_handle_release (rtems_rfs_file_system* fs, + rtems_rfs_buffer_handle* handle); + +/** + * Open a handle. + * + * @param fs The file system data. + * @param handle The buffer handle to open. + * @return int The error number (errno). No error if 0. + */ +static inline int +rtems_rfs_buffer_handle_open (rtems_rfs_file_system* fs, + rtems_rfs_buffer_handle* handle) +{ + handle->dirty = false; + handle->bnum = 0; + handle->buffer = NULL; + return 0; +} + +/** + * Close a handle. + * + * @param fs The file system data. + * @param handle The buffer handle to close. + * @return int The error number (errno). No error if 0. + */ +static inline int +rtems_rfs_buffer_handle_close (rtems_rfs_file_system* fs, + rtems_rfs_buffer_handle* handle) +{ + rtems_rfs_buffer_handle_release (fs, handle); + return 0; +} + +/** + * Open the buffer interface. + * + * @param name The device name to the media. + * @param fs Pointer to the file system data. + * @return int The error number (errno). No error if 0. + */ +int rtems_rfs_buffer_open (const char* name, rtems_rfs_file_system* fs); + +/** + * Close the buffer interface. + * + * @param fs Pointer to the file system data. + * @return int The error number (errno). No error if 0. + */ +int rtems_rfs_buffer_close (rtems_rfs_file_system* fs); + +/** + * Sync all buffers to the media. + * + * @param fs Pointer to the file system data. + * @return int The error number (errno). No error if 0. + */ +int rtems_rfs_buffer_sync (rtems_rfs_file_system* fs); + +/** + * Set the block size of the device. + * + * @param fs Pointer to the file system data. + * @param size The new block size. + * @return int The error number (errno). No error if 0. + */ +int rtems_rfs_buffer_setblksize (rtems_rfs_file_system* fs, size_t size); + +/** + * Release any chained buffers. + * + * @param fs The file system data. + * @return int The error number (errno). No error if 0. + */ +int rtems_rfs_buffers_release (rtems_rfs_file_system* fs); + +#endif |