/** * @file * * @brief Constants/Data Structures/Prototypes for Operations on "fat-file" * * @ingroup libfs_ff */ /* * * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia * Author: Eugeny S. Mints * * 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. */ #ifndef __DOSFS_FAT_FILE_H__ #define __DOSFS_FAT_FILE_H__ #include #include #include #include "fat.h" /** * @defgroup libfs_ff Fat File * * @ingroup libfs */ /**@{*/ #ifdef __cplusplus extern "C" { #endif typedef enum { FAT_DIRECTORY = 0, FAT_HARD_LINK = 2, /* pseudo type */ FAT_FILE = 4 } fat_file_type_t; /** * @brief The "fat-file" representation. * * the idea is: fat-file is nothing but a cluster chain, any open fat-file is * represented in system by fat-file descriptor and has well-known * file interface: * * fat_file_open() * fat_file_close() * fat_file_read() * fat_file_write() * * Such interface hides the architecture of fat-file and represents it like * linear file */ typedef struct fat_file_map_s { uint32_t file_cln; uint32_t disk_cln; uint32_t last_cln; } fat_file_map_t; /** * @brief Descriptor of a fat-file. * * To each particular clusters chain */ typedef struct fat_file_fd_s { rtems_chain_node link; /* * fat-file descriptors organized into hash; * collision lists are handled via link * field */ uint32_t links_num; /* * the number of fat_file_open call on * this fat-file */ uint32_t ino; /* inode, file serial number :)))) */ fat_file_type_t fat_file_type; uint32_t size_limit; uint32_t fat_file_size; /* length */ uint32_t cln; fat_dir_pos_t dir_pos; uint8_t flags; fat_file_map_t map; time_t ctime; time_t mtime; } fat_file_fd_t; #define FAT_FILE_REMOVED 0x01 #define FAT_FILE_META_DATA_CHANGED 0x02 static inline bool FAT_FILE_IS_REMOVED(const fat_file_fd_t *fat_fd) { return (fat_fd->flags & FAT_FILE_REMOVED) != 0; } static inline bool FAT_FILE_HAS_META_DATA_CHANGED(const fat_file_fd_t *fat_fd) { return (fat_fd->flags & FAT_FILE_META_DATA_CHANGED) != 0; } /* ioctl macros */ #define F_CLU_NUM 0x01 /* * Each file and directory on a MSDOS volume is unique identified by it * location, i.e. location of it 32 Bytes Directory Entry Structure. We can * distinguish them by cluster number it locates on and offset inside this * cluster. But root directory on any volumes (FAT12/16/32) has no 32 Bytes * Directory Entry Structure corresponded to it. So we assume 32 Bytes * Directory Entry Structure of root directory locates at cluster 1 (invalid * cluaster number) and offset 0 */ #define FAT_ROOTDIR_CLUSTER_NUM 0x01 #define FAT_FD_OF_ROOT_DIR(fat_fd) \ ((fat_fd->dir_pos.sname.cln == FAT_ROOTDIR_CLUSTER_NUM) && \ (fat_fd->dir_pos.sname.ofs == 0)) #define FAT_EOF 0x00 /* @brief Construct key for hash access. * * Construct key for hash access: convert (cluster num, offset) to * (sector512 num, new offset) and than construct key as * key = (sector512 num) << 4 | (new offset) * * @param[in] cl - cluster number * @param[in] ofs - offset inside cluster 'cl' * @param[in] fs_info - FS info * * @retval constructed key */ static inline uint32_t fat_construct_key( const fat_fs_info_t *fs_info, fat_pos_t *pos) { return ( ((fat_cluster_num_to_sector512_num(fs_info, pos->cln) + (pos->ofs >> FAT_SECTOR512_BITS)) << 4) + ((pos->ofs >> 5) & (FAT_DIRENTRIES_PER_SEC512 - 1)) ); } static inline void fat_file_set_first_cluster_num(fat_file_fd_t *fat_fd, uint32_t cln) { fat_fd->cln = cln; fat_fd->flags |= FAT_FILE_META_DATA_CHANGED; } static inline void fat_file_set_file_size(fat_file_fd_t *fat_fd, uint32_t s) { fat_fd->fat_file_size = s; fat_fd->flags |= FAT_FILE_META_DATA_CHANGED; } static inline void fat_file_set_ctime(fat_file_fd_t *fat_fd, time_t t) { fat_fd->ctime = t; fat_fd->flags |= FAT_FILE_META_DATA_CHANGED; } static inline void fat_file_set_mtime(fat_file_fd_t *fat_fd, time_t t) { fat_fd->mtime = t; fat_fd->flags |= FAT_FILE_META_DATA_CHANGED; } static inline void fat_file_set_ctime_mtime(fat_file_fd_t *fat_fd, time_t t) { fat_fd->ctime = t; fat_fd->mtime = t; fat_fd->flags |= FAT_FILE_META_DATA_CHANGED; } /* Prototypes for "fat-file" operations */ int fat_file_open(fat_fs_info_t *fs_info, fat_dir_pos_t *dir_pos, fat_file_fd_t **fat_fd); int fat_file_reopen(fat_file_fd_t *fat_fd); int fat_file_close(fat_fs_info_t *fs_info, fat_file_fd_t *fat_fd); ssize_t fat_file_read(fat_fs_info_t *fs_info, fat_file_fd_t *fat_fd, uint32_t start, uint32_t count, uint8_t *buf); ssize_t fat_file_write(fat_fs_info_t *fs_info, fat_file_fd_t *fat_fd, uint32_t start, uint32_t count, const uint8_t *buf); int fat_file_extend(fat_fs_info_t *fs_info, fat_file_fd_t *fat_fd, bool zero_fill, uint32_t new_length, uint32_t *a_length); int fat_file_truncate(fat_fs_info_t *fs_info, fat_file_fd_t *fat_fd, uint32_t new_length); int fat_file_ioctl(fat_fs_info_t *fs_info, fat_file_fd_t *fat_fd, int cmd, ...); int fat_file_size(fat_fs_info_t *fs_info, fat_file_fd_t *fat_fd); void fat_file_mark_removed(fat_fs_info_t *fs_info, fat_file_fd_t *fat_fd); int fat_file_size(fat_fs_info_t *fs_info, fat_file_fd_t *fat_fd); int fat_file_write_first_cluster_num(fat_fs_info_t *fs_info, fat_file_fd_t *fat_fd); int fat_file_write_file_size(fat_fs_info_t *fs_info, fat_file_fd_t *fat_fd); int fat_file_write_time_and_date(fat_fs_info_t *fs_info, fat_file_fd_t *fat_fd); int fat_file_update(fat_fs_info_t *fs_info, fat_file_fd_t *fat_fd); #ifdef __cplusplus } #endif /**@}*/ #endif /* __DOSFS_FAT_FILE_H__ */