diff options
Diffstat (limited to 'include/rtems/rfs/rtems-rfs-inode.h')
-rw-r--r-- | include/rtems/rfs/rtems-rfs-inode.h | 728 |
1 files changed, 728 insertions, 0 deletions
diff --git a/include/rtems/rfs/rtems-rfs-inode.h b/include/rtems/rfs/rtems-rfs-inode.h new file mode 100644 index 0000000000..95861ea8a7 --- /dev/null +++ b/include/rtems/rfs/rtems-rfs-inode.h @@ -0,0 +1,728 @@ +/** + * @file + * + * @brief RTEMS File System Information Node + * + * @ingroup rtems_rfs + * + * RTEMS File System Information Node. + * + * The information nodes hold the data about all nodes in the file system. + */ + +/* + * 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_INODE_H_) +#define _RTEMS_RFS_INODE_H_ + +#include <sys/stat.h> + +#include <rtems/rfs/rtems-rfs-data.h> +#include <rtems/rfs/rtems-rfs-file-system.h> + +/** + * The RFS mode definitions. Currently map to the C library ones. + */ +#define RTEMS_RFS_S_ISUID S_ISUID /**< Set user id on execution */ +#define RTEMS_RFS_S_ISGID S_ISGID /**< Set group id on execution */ +#define RTEMS_RFS_S_ISVTX S_ISVTX /**< Save swapped text even after use */ +#define RTEMS_RFS_S_IREAD S_IREAD /**< Read permission, owner */ +#define RTEMS_RFS_S_IWRITE S_IWRITE /**< Write permission, owner */ +#define RTEMS_RFS_S_IEXEC S_IEXEC /**< Execute/search permission, owner */ +#define RTEMS_RFS_S_ENFMT S_ENFMT /**< Enforcement-mode locking */ +#define RTEMS_RFS_S_IFMT S_IFMT /**< Type of file */ +#define RTEMS_RFS_S_IFDIR S_IFDIR /**< Directory */ +#define RTEMS_RFS_S_IFCHR S_IFCHR /**< Character special */ +#define RTEMS_RFS_S_IFBLK S_IFBLK /**< Block special */ +#define RTEMS_RFS_S_IFREG S_IFREG /**< Regular */ +#define RTEMS_RFS_S_IFLNK S_IFLNK /**< Symbolic link */ +#define RTEMS_RFS_S_IFSOCK S_IFSOCK /**< Socket */ +#define RTEMS_RFS_S_IFIFO S_IFIFO /**< Fifo */ +#define RTEMS_RFS_S_IRWXU S_IRWXU +#define RTEMS_RFS_S_IRUSR S_IRUSR /**< Read permission, owner */ +#define RTEMS_RFS_S_IWUSR S_IWUSR /**< Write permission, owner */ +#define RTEMS_RFS_S_IXUSR S_IXUSR /**< Execute/search permission, owner */ +#define RTEMS_RFS_S_IRWXG S_IRWXG +#define RTEMS_RFS_S_IRGRP S_IRGRP /**< Read permission, group */ +#define RTEMS_RFS_S_IWGRP S_IWGRP /**< Write permission, grougroup */ +#define RTEMS_RFS_S_IXGRP S_IXGRP /**< Execute/search permission, group */ +#define RTEMS_RFS_S_IRWXO S_IRWXO +#define RTEMS_RFS_S_IROTH S_IROTH /**< Read permission, other */ +#define RTEMS_RFS_S_IWOTH S_IWOTH /**< Write permission, other */ +#define RTEMS_RFS_S_IXOTH S_IXOTH /**< Execute/search permission, other */ + +#define RTEMS_RFS_S_ISBLK(m) S_ISBLK(m) +#define RTEMS_RFS_S_ISCHR(m) S_ISCHR(m) +#define RTEMS_RFS_S_ISDIR(m) S_ISDIR(m) +#define RTEMS_RFS_S_ISFIFO(m) S_ISFIFO(m) +#define RTEMS_RFS_S_ISREG(m) S_ISREG(m) +#define RTEMS_RFS_S_ISLNK(m) S_ISLNK(m) +#define RTEMS_RFS_S_ISSOCK(m) S_ISSOCK(m) + +/** + * Permissions of a symlink. + */ +#define RTEMS_RFS_S_SYMLINK \ + RTEMS_RFS_S_IFLNK | RTEMS_RFS_S_IRWXU | RTEMS_RFS_S_IRWXG | RTEMS_RFS_S_IRWXO + +/** + * The inode number or ino. + */ +typedef uint32_t rtems_rfs_ino; + +/** + * The time in the file system. + */ +typedef uint32_t rtems_rfs_time; + +/** + * The size of a block value on disk. This include the inodes and indirect + * tables. + */ +typedef uint32_t rtems_rfs_inode_block; + +/** + * The size of the data name field in the inode. + */ +#define RTEMS_RFS_INODE_DATA_NAME_SIZE \ + (RTEMS_RFS_INODE_BLOCKS * sizeof (rtems_rfs_inode_block)) + +/** + * The inode. + */ +typedef struct _rtems_rfs_inode +{ + /** + * The number of links to the inode. + */ + uint16_t links; + + /** + * The mode of the node. + */ + uint16_t mode; + + /** + * The owner of the node. + */ + uint32_t owner; + + /** + * Reserved. + */ + uint16_t flags; + + /** + * Amount of data held in the last block data. + */ + uint16_t block_offset; + + /** + * Number of blocks held by this file. + */ + uint32_t block_count; + + /** + * 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; + + /** + * Blocks. These are the block numbers used by the node or table of + * nodes. The flags indicate the mode the blocks are being held in. In the + * direct table mode the blocks are entries in this table. In the indirect + * mode the blocks point to blocks that hold the block numbers. The data can + * also be a name if it fits. For example a symbolic link. + */ + union + { + rtems_rfs_inode_block blocks[RTEMS_RFS_INODE_BLOCKS]; + uint8_t name[RTEMS_RFS_INODE_DATA_NAME_SIZE]; + } data; + + /** + * The last block map block. Used as the goal when allocating a new block for + * use in the map. + */ + rtems_rfs_inode_block last_map_block; + + /** + * The last data block. Used as the goal when allocating a new block. + */ + rtems_rfs_inode_block last_data_block; + +} rtems_rfs_inode; + +/** + * The size of an inode. + */ +#define RTEMS_RFS_INODE_SIZE (sizeof (rtems_rfs_inode)) + +/** + * RFS Inode Handle. + */ +typedef struct _rtems_rfs_inode_handle +{ + /** + * Handles can be linked as a list for easy processing. + */ + rtems_chain_node link; + + /** + * The ino for this handle. + */ + rtems_rfs_ino ino; + + /** + * The pointer to the inode. + */ + rtems_rfs_inode* node; + + /** + * The buffer that contains this inode. + */ + rtems_rfs_buffer_handle buffer; + + /** + * The block number that holds the inode. + */ + rtems_rfs_buffer_block block; + + /** + * The offset into the block for the inode. + */ + int offset; + + /** + * Number of load requests. + */ + int loads; + +} rtems_rfs_inode_handle; + +/** + * Is the inode loaded ? + */ +#define rtems_rfs_inode_is_loaded(_h) ((_h)->node) + +/** + * Get the inode ino for a handle. + */ +#define rtems_rfs_inode_ino(_h) ((_h)->ino) + +/** + * Get the link count. + * + * @param[in] handle is the inode handle. + * + * @retval links The link count. + */ +static inline uint16_t +rtems_rfs_inode_get_links (rtems_rfs_inode_handle* handle) +{ + uint16_t links; + links = rtems_rfs_read_u16 (&handle->node->links); + if (links == 0xffff) + links = 0; + return links; +} + +/** + * Set the link count. + * + * @param[in] handle is the inode handle. + * @param[in] links are the links. + */ +static inline void +rtems_rfs_inode_set_links (rtems_rfs_inode_handle* handle, uint16_t links) +{ + rtems_rfs_write_u16 (&handle->node->links, links); + rtems_rfs_buffer_mark_dirty (&handle->buffer); +} + +/** + * Get the flags. + * + * @param[in] handle is the inode handle. + * + * @retval flags The flags. + */ +static inline uint16_t +rtems_rfs_inode_get_flags (rtems_rfs_inode_handle* handle) +{ + return rtems_rfs_read_u16 (&handle->node->flags); +} + +/** + * Set the flags. + * + * @param[in] handle is the inode handle. + * @param[in] flags are the flags. + */ +static inline void +rtems_rfs_inode_set_flags (rtems_rfs_inode_handle* handle, uint16_t flags) +{ + rtems_rfs_write_u16 (&handle->node->flags, flags); + rtems_rfs_buffer_mark_dirty (&handle->buffer); +} + +/** + * Get the mode. + * + * @param[in] handle is the inode handle. + * + * @retval mode The mode. + */ +static inline uint16_t +rtems_rfs_inode_get_mode (rtems_rfs_inode_handle* handle) +{ + return rtems_rfs_read_u16 (&handle->node->mode); +} + +/** + * Set the mode. + * + * @param[in] handle is the inode handle. + * @param[in] mode is the mode. + */ +static inline void +rtems_rfs_inode_set_mode (rtems_rfs_inode_handle* handle, uint16_t mode) +{ + rtems_rfs_write_u16 (&handle->node->mode, mode); + rtems_rfs_buffer_mark_dirty (&handle->buffer); +} + +/** + * Get the user id. + * + * @param[in] handle is the inode handle. + * + * @retval uid The used id. + */ +static inline uint16_t +rtems_rfs_inode_get_uid (rtems_rfs_inode_handle* handle) +{ + return rtems_rfs_read_u32 (&handle->node->owner) & 0xffff; +} + +/** + * Get the group id. + * + * @param[in] handle is the inode handle. + * + * @retval gid The grpup id. + */ +static inline uint16_t +rtems_rfs_inode_get_gid (rtems_rfs_inode_handle* handle) +{ + return (rtems_rfs_read_u32 (&handle->node->owner) >> 16) & 0xffff; +} + +/** + * Set the user id and group id. + * + * @param[in] handle is the inode handle. + * @param[in] uid is the user id (uid). + * @param[in] gid is the group id (gid). + */ +static inline void +rtems_rfs_inode_set_uid_gid (rtems_rfs_inode_handle* handle, + uint16_t uid, uint16_t gid) +{ + rtems_rfs_write_u32 (&handle->node->owner, (((uint32_t) gid) << 16) | uid); + rtems_rfs_buffer_mark_dirty (&handle->buffer); +} + +/** + * Get the block offset. + * + * @param[in] handle is the inode handle. + * + * @retval offset The block offset. + */ +static inline uint16_t +rtems_rfs_inode_get_block_offset (rtems_rfs_inode_handle* handle) +{ + return rtems_rfs_read_u16 (&handle->node->block_offset); +} + +/** + * Set the block offset. + * + * @param[in] handle is the inode handle. + * @param[in] block_count is the block offset. + */ +static inline void +rtems_rfs_inode_set_block_offset (rtems_rfs_inode_handle* handle, + uint16_t block_offset) +{ + rtems_rfs_write_u16 (&handle->node->block_offset, block_offset); + rtems_rfs_buffer_mark_dirty (&handle->buffer); +} + +/** + * Get the block count. + * + * @param[in] handle is the inode handle. + * + * @retval count The block count. + */ +static inline uint32_t +rtems_rfs_inode_get_block_count (rtems_rfs_inode_handle* handle) +{ + return rtems_rfs_read_u32 (&handle->node->block_count); +} + +/** + * Set the block count. + * + * @param[in] handle is the inode handle. + * @param[in] block_count is the block count. + */ +static inline void +rtems_rfs_inode_set_block_count (rtems_rfs_inode_handle* handle, uint32_t block_count) +{ + rtems_rfs_write_u32 (&handle->node->block_count, block_count); + rtems_rfs_buffer_mark_dirty (&handle->buffer); +} + +/** + * Get the atime. + * + * @param[in] handle is the inode handle. + * + * @retval atime The atime. + */ +static inline rtems_rfs_time +rtems_rfs_inode_get_atime (rtems_rfs_inode_handle* handle) +{ + return rtems_rfs_read_u32 (&handle->node->atime); +} + +/** + * Set the atime. + * + * @param[in] handle is the inode handle. + * @param[in] atime The atime. + */ +static inline void +rtems_rfs_inode_set_atime (rtems_rfs_inode_handle* handle, + rtems_rfs_time atime) +{ + rtems_rfs_write_u32 (&handle->node->atime, atime); + rtems_rfs_buffer_mark_dirty (&handle->buffer); +} + +/** + * Get the mtime. + * + * @param[in] handle is the inode handle. + * + * @retval mtime The mtime. + */ +static inline rtems_rfs_time +rtems_rfs_inode_get_mtime (rtems_rfs_inode_handle* handle) +{ + return rtems_rfs_read_u32 (&handle->node->mtime); +} + +/** + * Set the mtime. + * + * @param[in] handle is the inode handle. + * @param[in] mtime The mtime. + */ +static inline void +rtems_rfs_inode_set_mtime (rtems_rfs_inode_handle* handle, + rtems_rfs_time mtime) +{ + rtems_rfs_write_u32 (&handle->node->mtime, mtime); + rtems_rfs_buffer_mark_dirty (&handle->buffer); +} + +/** + * Get the ctime. + * + * @param[in] handle is the inode handle. + * + * @retval ctime The ctime. + */ +static inline rtems_rfs_time +rtems_rfs_inode_get_ctime (rtems_rfs_inode_handle* handle) +{ + return rtems_rfs_read_u32 (&handle->node->ctime); +} + +/** + * Set the ctime. + * + * @param[in] handle is the inode handle. + * @param[in] ctime The ctime. + */ +static inline void +rtems_rfs_inode_set_ctime (rtems_rfs_inode_handle* handle, + rtems_rfs_time ctime) +{ + rtems_rfs_write_u32 (&handle->node->ctime, ctime); + rtems_rfs_buffer_mark_dirty (&handle->buffer); +} + +/** + * Get the block number. + * + * @param[in] handle is the inode handle. + * @param[in] block is the block number to return. + * + * @retval block The block number. + */ +static inline uint32_t +rtems_rfs_inode_get_block (rtems_rfs_inode_handle* handle, int block) +{ + return rtems_rfs_read_u32 (&handle->node->data.blocks[block]); +} + +/** + * Set the block number for a given block index. + * + * @param[in] handle is the inode handle. + * @param[in] block is the block index. + * @param[in] bno is the block number. + */ +static inline void +rtems_rfs_inode_set_block (rtems_rfs_inode_handle* handle, int block, uint32_t bno) +{ + rtems_rfs_write_u32 (&handle->node->data.blocks[block], bno); + rtems_rfs_buffer_mark_dirty (&handle->buffer); +} + +/** + * Get the last map block from the inode. + * + * @param[in] handle is the inode handle. + * + * @retval block The last map block number. + */ +static inline uint32_t +rtems_rfs_inode_get_last_map_block (rtems_rfs_inode_handle* handle) +{ + return rtems_rfs_read_u32 (&handle->node->last_map_block); +} + +/** + * Set the last map block. + * + * @param[in] handle is the inode handle. + * @param[in] block_count is last map block number. + */ +static inline void +rtems_rfs_inode_set_last_map_block (rtems_rfs_inode_handle* handle, uint32_t last_map_block) +{ + rtems_rfs_write_u32 (&handle->node->last_map_block, last_map_block); + rtems_rfs_buffer_mark_dirty (&handle->buffer); +} + +/** + * Get the last data block from the inode. + * + * @param[in] handle is the inode handle. + * + * @retval block The last data block number. + * + */ +static inline uint32_t +rtems_rfs_inode_get_last_data_block (rtems_rfs_inode_handle* handle) +{ + return rtems_rfs_read_u32 (&handle->node->last_data_block); +} + +/** + * Set the last data block. + * + * @param[in] handle is the inode handle. + * @param[in] block_count is the last data block number. + */ +static inline void +rtems_rfs_inode_set_last_data_block (rtems_rfs_inode_handle* handle, uint32_t last_data_block) +{ + rtems_rfs_write_u32 (&handle->node->last_data_block, last_data_block); + rtems_rfs_buffer_mark_dirty (&handle->buffer); +} + +/** + * Allocate an inode number and return it. + * + * @param[in] fs is the file system data. + * @param[out] ino will contain the ino. + * + * @retval 0 Successful operation. + * @retval error_code An error occurred. + */ +int rtems_rfs_inode_alloc (rtems_rfs_file_system* fs, + rtems_rfs_bitmap_bit goal, + rtems_rfs_ino* ino); + +/** + * Free an inode. + * + * @param[in] fs is the file system data. + * @param[in] ino is the ino too free. + * + * @retval 0 Successful operation. + * @retval error_code An error occurred. + */ +int rtems_rfs_inode_free (rtems_rfs_file_system* fs, + rtems_rfs_ino ino); + +/** + * Open the inode handle. This reads the inode into the buffer and sets the + * data pointer. All data is in media byte order and needs to be accessed via + * the supporting calls. + * + * @param[in] fs is the file system. + * @param[in] ino is the inode number. + * @param[in] handle is the handle to the inode we are opening. + * @param[in] load If true load the inode into memory from the media. + * + * @retval 0 Successful operation. + * @retval error_code An error occurred. + */ +int rtems_rfs_inode_open (rtems_rfs_file_system* fs, + rtems_rfs_ino ino, + rtems_rfs_inode_handle* handle, + bool load); + +/** + * The close inode handle. All opened inodes need to be closed. + * + * @param[in] fs is the file system. + * @param[in] handle is the handle to close. + * + * @retval 0 Successful operation. + * @retval error_code An error occurred. + */ +int rtems_rfs_inode_close (rtems_rfs_file_system* fs, + rtems_rfs_inode_handle* handle); + +/** + * Load the inode into memory. + * + * @param[in] fs is the file system. + * @param[in] handle is the inode handle to load. + * + * @retval 0 Successful operation. + * @retval error_code An error occurred. + */ +int rtems_rfs_inode_load (rtems_rfs_file_system* fs, + rtems_rfs_inode_handle* handle); + +/** + * Unload the inode from memory. + * + * @param[in] fs is the file system. + * @param[in] handle is the inode handle to unload. + * @param[in] update_ctime Update the ctime field of the inode. + * + * @retval 0 Successful operation. + * @retval error_code An error occurred. + */ +int rtems_rfs_inode_unload (rtems_rfs_file_system* fs, + rtems_rfs_inode_handle* handle, + bool update_ctime); + +/** + * Create an inode allocating, initialising and adding an entry to the parent + * directory. + * + * @param[in] fs is the file system data. + * @param[in] parent is the parent inode number to add the directory entry to. + * @param[in] name is a pointer to the name of the directory entryinode + * to create. + * + */ +int rtems_rfs_inode_create (rtems_rfs_file_system* fs, + rtems_rfs_ino parent, + const char* name, + size_t length, + uint16_t mode, + uint16_t links, + uid_t uid, + gid_t gid, + rtems_rfs_ino* ino); + +/** + * Delete the inode eraseing it and release the buffer to commit the write. You + * need to load the inode again if you wish to use it again. + * + * @param[in] fs is the file system. + * @param[in] handle is the inode handle to erase. + * + * @retval 0 Successful operation. + * @retval error_code An error occurred. + */ +int rtems_rfs_inode_delete (rtems_rfs_file_system* fs, + rtems_rfs_inode_handle* handle); + +/** + * Initialise a new inode. + * + * @param[in] handle is the inode handle to initialise. + * @param[in] links are the number of links to the inode. + * @param[in] mode is the inode mode. + * @param[in] uid is the user id. + * @param[in] gid is the group id. + * + * @retval 0 Successful operation. + * @retval error_code An error occurred. + */ +int rtems_rfs_inode_initialise (rtems_rfs_inode_handle* handle, + uint16_t links, + uint16_t mode, + uid_t uid, + gid_t gid); + +/** + * Time stamp the inode with the current time. The ctime field is hanlded + * automatically. + * + * @param[in] handle is the inode handle. + * @param[in] atime Update the atime field. + * @param[in] mtime UPdate the mtime field. + * + * @retval 0 Successful operation. + * @retval ENXIO No inode is loaded. + * @retval error_code An error occurred. + */ +int rtems_rfs_inode_time_stamp_now (rtems_rfs_inode_handle* handle, + bool atime, + bool mtime); + +/** + * Calculate the size of data attached to the inode. + * + * @param[in] fs is the file system data. + * @param[in] handle is the inode handle. + * + * @retval size The data size in bytes in the block map attched to the inode. + */ +rtems_rfs_pos rtems_rfs_inode_get_size (rtems_rfs_file_system* fs, + rtems_rfs_inode_handle* handle); + +#endif + |