|
|
/**
* @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
|