Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:16

0001 /**
0002  * @file
0003  *
0004  * @brief Constants/Data Structures/Prototypes for Operations on "fat-file"
0005  *
0006  * @ingroup libfs_ff
0007  */
0008 
0009 /*
0010  *
0011  *  Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
0012  *  Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
0013  *
0014  *  The license and distribution terms for this file may be
0015  *  found in the file LICENSE in this distribution or at
0016  *  http://www.rtems.org/license/LICENSE.
0017  */
0018 
0019 #ifndef __DOSFS_FAT_FILE_H__
0020 #define __DOSFS_FAT_FILE_H__
0021 
0022 #include <rtems.h>
0023 #include <rtems/libio_.h>
0024 
0025 #include <time.h>
0026 
0027 #include "fat.h"
0028 
0029 /**
0030  *  @defgroup libfs_ff Fat File
0031  *
0032  *  @ingroup libfs_dosfs
0033  */
0034 /**@{*/
0035 
0036 #ifdef __cplusplus
0037 extern "C" {
0038 #endif
0039 
0040 typedef enum {
0041   FAT_DIRECTORY = 0,
0042   FAT_HARD_LINK = 2, /* pseudo type */
0043   FAT_FILE = 4
0044 } fat_file_type_t;
0045 
0046 /**
0047  * @brief The "fat-file" representation.
0048  *
0049  * the idea is: fat-file is nothing but a cluster chain, any open fat-file is
0050  * represented in system by fat-file descriptor and has well-known
0051  * file interface:
0052  *
0053  * fat_file_open()
0054  * fat_file_close()
0055  * fat_file_read()
0056  * fat_file_write()
0057  *
0058  * Such interface hides the architecture of fat-file and represents it like
0059  * linear file
0060  */
0061 typedef struct fat_file_map_s
0062 {
0063     uint32_t   file_cln;
0064     uint32_t   disk_cln;
0065     uint32_t   last_cln;
0066 } fat_file_map_t;
0067 
0068 /**
0069  * @brief Descriptor of a fat-file.
0070  *
0071  * To each particular clusters chain
0072  */
0073 typedef struct fat_file_fd_s
0074 {
0075     rtems_chain_node link;          /*
0076                                      * fat-file descriptors organized into hash;
0077                                      * collision lists are handled via link
0078                                      * field
0079                                      */
0080     uint32_t         links_num;     /*
0081                                      * the number of fat_file_open call on
0082                                      * this fat-file
0083                                      */
0084     uint32_t         ino;           /* inode, file serial number :)))) */
0085     fat_file_type_t  fat_file_type;
0086     uint32_t         size_limit;
0087     uint32_t         fat_file_size; /* length  */
0088     uint32_t         cln;
0089     fat_dir_pos_t    dir_pos;
0090     uint8_t          flags;
0091     fat_file_map_t   map;
0092     time_t           ctime;
0093     time_t           mtime;
0094 
0095 } fat_file_fd_t;
0096 
0097 #define FAT_FILE_REMOVED 0x01
0098 
0099 #define FAT_FILE_META_DATA_CHANGED 0x02
0100 
0101 static inline bool FAT_FILE_IS_REMOVED(const fat_file_fd_t *fat_fd)
0102 {
0103      return (fat_fd->flags & FAT_FILE_REMOVED) != 0;
0104 }
0105 
0106 static inline bool FAT_FILE_HAS_META_DATA_CHANGED(const fat_file_fd_t *fat_fd)
0107 {
0108      return (fat_fd->flags & FAT_FILE_META_DATA_CHANGED) != 0;
0109 }
0110 
0111 /* ioctl macros */
0112 #define F_CLU_NUM  0x01
0113 
0114 /*
0115  * Each file and directory on a MSDOS volume is unique identified by it
0116  * location, i.e. location of it 32 Bytes Directory Entry Structure. We can
0117  * distinguish them by cluster number it locates on and offset inside this
0118  * cluster. But root directory on any volumes (FAT12/16/32) has no 32 Bytes
0119  * Directory Entry Structure corresponded to it. So we assume 32 Bytes
0120  * Directory Entry Structure of root directory locates at cluster 1 (invalid
0121  * cluaster number) and offset 0
0122  */
0123 #define FAT_ROOTDIR_CLUSTER_NUM 0x01
0124 
0125 #define FAT_FD_OF_ROOT_DIR(fat_fd)  \
0126   ((fat_fd->dir_pos.sname.cln == FAT_ROOTDIR_CLUSTER_NUM) && \
0127   (fat_fd->dir_pos.sname.ofs == 0))
0128 
0129 #define FAT_EOF           0x00
0130 
0131 /* @brief Construct key for hash access.
0132  *
0133  * Construct key for hash access: convert (cluster num, offset) to
0134  * (sector512 num, new offset) and than construct key as
0135  * key = (sector512 num) << 4 | (new offset)
0136  *
0137  * @param[in] cl - cluster number
0138  * @param[in] ofs - offset inside cluster 'cl'
0139  * @param[in] fs_info - FS info
0140  *
0141  * @retval constructed key
0142  */
0143 static inline uint32_t
0144 fat_construct_key(
0145     const fat_fs_info_t                  *fs_info,
0146     fat_pos_t                            *pos)
0147 {
0148     return ( ((fat_cluster_num_to_sector512_num(fs_info, pos->cln) +
0149               (pos->ofs >> FAT_SECTOR512_BITS)) << 4)              +
0150               ((pos->ofs >> 5) & (FAT_DIRENTRIES_PER_SEC512 - 1)) );
0151 }
0152 
0153 static inline void
0154 fat_file_set_first_cluster_num(fat_file_fd_t *fat_fd, uint32_t cln)
0155 {
0156     fat_fd->cln = cln;
0157     fat_fd->flags |= FAT_FILE_META_DATA_CHANGED;
0158 }
0159 
0160 static inline void fat_file_set_file_size(fat_file_fd_t *fat_fd, uint32_t s)
0161 {
0162     fat_fd->fat_file_size = s;
0163     fat_fd->flags |= FAT_FILE_META_DATA_CHANGED;
0164 }
0165 
0166 static inline void fat_file_set_ctime(fat_file_fd_t *fat_fd, time_t t)
0167 {
0168     fat_fd->ctime = t;
0169     fat_fd->flags |= FAT_FILE_META_DATA_CHANGED;
0170 }
0171 
0172 static inline void fat_file_set_mtime(fat_file_fd_t *fat_fd, time_t t)
0173 {
0174     fat_fd->mtime = t;
0175     fat_fd->flags |= FAT_FILE_META_DATA_CHANGED;
0176 }
0177 
0178 static inline void fat_file_set_ctime_mtime(fat_file_fd_t *fat_fd, time_t t)
0179 {
0180     fat_fd->ctime = t;
0181     fat_fd->mtime = t;
0182     fat_fd->flags |= FAT_FILE_META_DATA_CHANGED;
0183 }
0184 
0185 /* Prototypes for "fat-file" operations */
0186 int
0187 fat_file_open(fat_fs_info_t                         *fs_info,
0188               fat_dir_pos_t                         *dir_pos,
0189               fat_file_fd_t                        **fat_fd);
0190 
0191 int
0192 fat_file_reopen(fat_file_fd_t *fat_fd);
0193 
0194 int
0195 fat_file_close(fat_fs_info_t                        *fs_info,
0196                fat_file_fd_t                        *fat_fd);
0197 
0198 ssize_t
0199 fat_file_read(fat_fs_info_t                        *fs_info,
0200               fat_file_fd_t                        *fat_fd,
0201               uint32_t                              start,
0202               uint32_t                              count,
0203               uint8_t                              *buf);
0204 
0205 ssize_t
0206 fat_file_write(fat_fs_info_t                        *fs_info,
0207                fat_file_fd_t                        *fat_fd,
0208                uint32_t                              start,
0209                uint32_t                              count,
0210                const uint8_t                        *buf);
0211 
0212 int
0213 fat_file_extend(fat_fs_info_t                        *fs_info,
0214                 fat_file_fd_t                        *fat_fd,
0215                 bool                                  zero_fill,
0216                 uint32_t                              new_length,
0217                 uint32_t                             *a_length);
0218 
0219 int
0220 fat_file_truncate(fat_fs_info_t                        *fs_info,
0221                   fat_file_fd_t                        *fat_fd,
0222                   uint32_t                              new_length);
0223 
0224 int
0225 fat_file_ioctl(fat_fs_info_t                        *fs_info,
0226                fat_file_fd_t                        *fat_fd,
0227                int                                   cmd,
0228                ...);
0229 
0230 int
0231 fat_file_size(fat_fs_info_t                        *fs_info,
0232               fat_file_fd_t                        *fat_fd);
0233 
0234 void
0235 fat_file_mark_removed(fat_fs_info_t                        *fs_info,
0236                       fat_file_fd_t                        *fat_fd);
0237 
0238 int
0239 fat_file_size(fat_fs_info_t                        *fs_info,
0240               fat_file_fd_t                        *fat_fd);
0241 
0242 int
0243 fat_file_write_first_cluster_num(fat_fs_info_t *fs_info,
0244                                  fat_file_fd_t *fat_fd);
0245 
0246 int
0247 fat_file_write_file_size(fat_fs_info_t *fs_info,
0248                          fat_file_fd_t *fat_fd);
0249 
0250 int
0251 fat_file_write_time_and_date(fat_fs_info_t *fs_info,
0252                              fat_file_fd_t *fat_fd);
0253 
0254 int
0255 fat_file_update(fat_fs_info_t *fs_info,
0256                 fat_file_fd_t *fat_fd);
0257 
0258 int
0259 fat_file_get_new_inode_for(fat_fs_info_t *fs_info,
0260                            fat_dir_pos_t *new_dir_pos,
0261                            fat_file_fd_t *fat_fd);
0262 
0263 #ifdef __cplusplus
0264 }
0265 #endif
0266 /**@}*/
0267 #endif /* __DOSFS_FAT_FILE_H__ */