diff options
Diffstat (limited to 'include/rtems/rfs/rtems-rfs-file.h')
-rw-r--r-- | include/rtems/rfs/rtems-rfs-file.h | 416 |
1 files changed, 416 insertions, 0 deletions
diff --git a/include/rtems/rfs/rtems-rfs-file.h b/include/rtems/rfs/rtems-rfs-file.h new file mode 100644 index 0000000000..772e846143 --- /dev/null +++ b/include/rtems/rfs/rtems-rfs-file.h @@ -0,0 +1,416 @@ +/** + * @file + * + * @brief RTEMS File System File Support + * + * @ingroup rtems_rfs + * + * RTEMS File System File Support + * + * This file provides the support functions. + */ + +/* + * 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.org/license/LICENSE. + */ + +#if !defined (_RTEMS_RFS_FILE_H_) +#define _RTEMS_RFS_FILE_H_ + +#include <rtems/libio_.h> + +#include <rtems/rfs/rtems-rfs-block.h> +#include <rtems/rfs/rtems-rfs-data.h> +#include <rtems/rfs/rtems-rfs-file-system.h> +#include <rtems/rfs/rtems-rfs-inode.h> + +/** + * File data that is shared by various file handles accessing the same file. We + * hold various inode values common to the file that can change frequently so + * the inode is not thrashed yet we meet the requirements of the POSIX + * standard. The stat call needs to check the shared file data. + */ +typedef struct _rtems_rfs_file_shared +{ + /** + * The shared parts are maintained as a list. + */ + rtems_chain_node link; + + /** + * Reference count the users of this data. + */ + int references; + + /** + * The inode for the file. + */ + rtems_rfs_inode_handle inode; + + /** + * The block map for the file. The handle holds the file's position not the + * map. + */ + rtems_rfs_block_map map; + + /** + * The size of the file as taken from the inode. The map's size and + * this size should be the same. + */ + rtems_rfs_block_size size; + + /** + * The access time. The last time the file was read. + */ + rtems_rfs_time atime; + + /** + * The modified time. The last time the file was written too. + */ + rtems_rfs_time mtime; + + /** + * The change time. The last time the inode was written too. + */ + rtems_rfs_time ctime; + + /** + * Hold a pointer to the file system data so users can take the handle and + * use it without the needing to hold the file system data pointer. + */ + rtems_rfs_file_system* fs; + +} rtems_rfs_file_shared; + +/** + * Get the atime. + * + * @param[in] shared is a pointer to the shared file data. + * + * @retval atime The atime. + */ +static inline rtems_rfs_time +rtems_rfs_file_shared_get_atime (rtems_rfs_file_shared* shared) +{ + return shared->atime; +} + +/** + * Get the mtime. + * + * @param[in] shared is a pointer to the shared file data. + * + * @retval mtime The mtime. + */ +static inline rtems_rfs_time +rtems_rfs_file_shared_get_mtime (rtems_rfs_file_shared* shared) +{ + return shared->mtime; +} + +/** + * Get the ctime. + * + * @param[in] shared is a pointer to the shared file data. + * + * @retval ctime The ctime. + */ +static inline rtems_rfs_time +rtems_rfs_file_shared_get_ctime (rtems_rfs_file_shared* shared) +{ + return shared->ctime; +} + +/** + * Get the block count. + * + * @param[in] shared is a pointer to the shared file data. + * + * @retval count The block count. + */ +static inline uint32_t +rtems_rfs_file_shared_get_block_count (rtems_rfs_file_shared* shared) +{ + return shared->size.count; +} + +/** + * Get the block offset. + * + * @param shared is a pointer to the shared file data. + * + * @retval offset The block offset. + */ +static inline uint16_t +rtems_rfs_file_shared_get_block_offset (rtems_rfs_file_shared* shared) +{ + return shared->size.offset; +} + +/** + * Calculate the size of data. + * + * @param[in] fs is the file system data. + * @param[in] shared is a pointer to the shared file data. + * + * @retval data The data size in bytes. + */ +static inline rtems_rfs_pos +rtems_rfs_file_shared_get_size (rtems_rfs_file_system* fs, + rtems_rfs_file_shared* shared) +{ + return rtems_rfs_block_get_size (fs, &shared->size); +} + +/** + * File flags. + */ +#define RTEMS_RFS_FILE_NO_ATIME_UPDATE (1 << 0) /**< Do not update the atime + * field in the inode if + * set. */ +#define RTEMS_RFS_FILE_NO_MTIME_UPDATE (1 << 1) /**< Do not update the mtime + * field in the inode if + * set. */ +#define RTEMS_RFS_FILE_NO_LENGTH_UPDATE (1 << 2) /**< Do not update the position + * field in the inode if + * set. */ + +/** + * File data used to managed an open file. + */ +typedef struct _rtems_rfs_file_handle +{ + /** + * Special flags that can be controlled by the fctrl call. + */ + int flags; + + /** + * The buffer of data at the file's position. + */ + rtems_rfs_buffer_handle buffer; + + /** + * The block position of this file handle. + */ + rtems_rfs_block_pos bpos; + + /** + * Pointer to the shared file data. + */ + rtems_rfs_file_shared* shared; + +} rtems_rfs_file_handle; + +/** + * Access the data in the buffer. + */ +#define rtems_rfs_file_data(_f) \ + (rtems_rfs_buffer_data (&(_f)->buffer) + (_f)->bpos.boff) + +/** + * Return the file system data pointer given a file handle. + */ +#define rtems_rfs_file_fs(_f) ((_f)->shared->fs) + +/** + * Return the file's inode handle pointer given a file handle. + */ +#define rtems_rfs_file_inode(_f) (&(_f)->shared->inode) + +/** + * Return the file's block map pointer given a file handle. + */ +#define rtems_rfs_file_map(_f) (&(_f)->shared->map) + +/** + * Return the file's block position pointer given a file handle. + */ +#define rtems_rfs_file_bpos(_f) (&(_f)->bpos) + +/** + * Return the file's block number given a file handle. + */ +#define rtems_rfs_file_block(_f) ((_f)->bpos.bno) + +/** + * Return the file's block offset given a file handle. + */ +#define rtems_rfs_file_block_offset(_f) ((_f)->bpos.boff) + +/** + * Set the file's block position given a file position (absolute). + */ +#define rtems_rfs_file_set_bpos(_f, _p) \ + rtems_rfs_block_get_bpos (rtems_rfs_file_fs (_f), _p, (&(_f)->bpos)) + +/** + * Return the file's buffer handle pointer given a file handle. + */ +#define rtems_rfs_file_buffer(_f) (&(_f)->buffer) + +/** + * Update the access time field of the inode when reading if flagged to do so. + */ +#define rtems_rfs_file_update_atime(_f) \ + (((_f)->flags & RTEMS_RFS_FILE_NO_ATIME_UPDATE) == 0) + +/** + * Update the modified time field of the inode when writing if flagged to do so. + */ +#define rtems_rfs_file_update_mtime(_f) \ + (((_f)->flags & RTEMS_RFS_FILE_NO_MTIME_UPDATE) == 0) + +/** + * Update the length field of the inode. + */ +#define rtems_rfs_file_update_length(_f) \ + (((_f)->flags & RTEMS_RFS_FILE_NO_LENGTH_UPDATE) == 0) + +/** + * Return the shared size varable. + */ +#define rtems_rfs_file_get_size(_f) \ + (&(_f)->shared->size) + +/** + * Return the size of file. + */ +#define rtems_rfs_file_size(_f) \ + rtems_rfs_file_shared_get_size (rtems_rfs_file_fs (_f), (_f)->shared) + +/** + * Return the file block count. + */ +#define rtems_rfs_file_size_count(_f) \ + rtems_rfs_file_shared_get_block_count ((_f)->shared) + +/** + * Return the file block offset. + */ +#define rtems_rfs_file_size_offset(_f) \ + rtems_rfs_file_shared_get_block_offset ((_f)->shared) + +/** + * Open a file handle. + * + * @param[in] fs is the file system. + * @param[in] ino is the inode number of the file to be opened. + * @param[out] handle will be filled in with the handle pointer. + * + * @retval 0 Successful operation. + * @retval error_code An error occurred. + */ +int rtems_rfs_file_open (rtems_rfs_file_system* fs, + rtems_rfs_ino ino, + int oflag, + rtems_rfs_file_handle** handle); + +/** + * Close an open file handle. + * + * @param[in] fs is the file system. + * @param[in] handle is the open file handle. + * + * @retval 0 Successful operation. + * @retval error_code An error occurred. + */ +int rtems_rfs_file_close (rtems_rfs_file_system* fs, + rtems_rfs_file_handle* handle); + +/** + * Start I/O on a block of a file. This call only requests the block from the + * media if reading and makes the buffer available to you the via the + * rtems_rfs_file_data interface after the call. The available amount data is + * taken from the current file position until the end of the block. The file + * position is not adujsted until the I/O ends. An I/O request cannot perform + * I/O past the end of a block so the call returns the amount of data + * available. + * + * @param[in] handle is the file handle. + * @param[in] available is the amount of data available for I/O. + * @param[in] read is the I/O operation is a read so the block is read from the media. + * + * @retval 0 Successful operation. + * @retval error_code An error occurred. + */ +int rtems_rfs_file_io_start (rtems_rfs_file_handle* handle, + size_t* available, + bool read); + +/** + * End the I/O. Any buffers held in the file handle and returned to the + * cache. If inode updating is not disable and the I/O is a read the atime + * field is updated and if a write I/O the mtime is updated. + * + * If the file's position is updated by the size amount. + * + * @param[in] handle is the file handle. + * @param[in] size is the amount of data read or written. + * @param[in] read is the I/O was a read if true else it was a write. + * + * @retval 0 Successful operation. + * @retval error_code An error occurred. + */ +int rtems_rfs_file_io_end (rtems_rfs_file_handle* handle, + size_t size, + bool read); + +/** + * Release the I/O resources without any changes. If data has changed in the + * buffer and the buffer was not already released as modified the data will be + * lost. + * + * @param[in] handle is the file handle. + * + * @retval 0 Successful operation. + * @retval error_code An error occurred. + */ +int rtems_rfs_file_io_release (rtems_rfs_file_handle* handle); + +/** + * The file to the position returning the old position. The position is + * abolute. + * + * @param[in] handle The file handle. + * @param[in] pos is the position to seek to. + * @param[out] new_pos will contain the actual position. + * + * @retval 0 Successful operation. + * @retval error_code An error occurred. + */ +int rtems_rfs_file_seek (rtems_rfs_file_handle* handle, + rtems_rfs_pos pos, + rtems_rfs_pos* new_pos); + +/** + * Set the size of the file to the new size. This can extend the file to a new + * size. + * + * @param[in] handle is the file handle. + * @param[in] size is the new size of the file. + * @retval 0 Successful operation. + * @retval error_code An error occurred. + */ +int rtems_rfs_file_set_size (rtems_rfs_file_handle* handle, + rtems_rfs_pos size); + +/** + * Return the shared file data for an ino. + * + * @param[in] fs is the file system data. + * @param[in] ino is the inode number to locate the data for. + * @return rtems_rfs_file_shared* The shared data or NULL is not located. + * + * @retval shared The shared data. + * @retval NULL No shared file data is located. + */ +rtems_rfs_file_shared* rtems_rfs_file_get_shared (rtems_rfs_file_system* fs, + rtems_rfs_ino ino); + + +#endif |