summaryrefslogtreecommitdiffstats
path: root/cpukit/libfs/src/dosfs/fat_file.h
blob: b16b9b370f7fb660e5f61fbdda7af0f5ecc1a8a7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
/*
 *  fat_file.h
 *
 *  Constants/data structures/prototypes for operations on "fat-file"
 *
 *  Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
 *  Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.rtems.com/license/LICENSE.
 *
 *  @(#) $Id$
 */
#ifndef __DOSFS_FAT_FILE_H__
#define __DOSFS_FAT_FILE_H__

#ifdef __cplusplus
extern "C" {
#endif

#include <rtems.h>
#include <rtems/libio_.h>

#include <time.h>

/* "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 rtems_filesystem_node_types_t fat_file_type_t;

#define FAT_DIRECTORY     RTEMS_FILESYSTEM_DIRECTORY
#define FAT_FILE          RTEMS_FILESYSTEM_MEMORY_FILE

typedef struct fat_file_map_s
{
    uint32_t   file_cln;
    uint32_t   disk_cln;
    uint32_t   last_cln;
} fat_file_map_t;
/* 
 * descriptor of a fat-file 
 *
 * To each particular clusters chain 
 */
typedef struct fat_file_fd_s
{
    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        info_cln;
    uint32_t        cln;
    uint16_t        info_ofs;     
    unsigned char   first_char;
    uint8_t         flags;
    fat_file_map_t  map;
    time_t          mtime;
    
} fat_file_fd_t;


#define FAT_FILE_REMOVED  0x01

#define FAT_FILE_IS_REMOVED(p)\
    (((p)->flags & FAT_FILE_REMOVED) ? 1 : 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->info_cln == FAT_ROOTDIR_CLUSTER_NUM ) && \
  (fat_fd->info_ofs == 0))

#define FAT_EOF           0x00

/* fat_construct_key --
 *     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)
 *
 * PARAMETERS:
 *     cl       - cluster number
 *     ofs      - offset inside cluster 'cl'
 *     mt_entry - mount table entry
 *
 * RETURNS:
 *     constructed key
 */
static inline uint32_t   
fat_construct_key(
    rtems_filesystem_mount_table_entry_t *mt_entry,
    uint32_t                              cl, 
    uint32_t                              ofs)
{
    return ( ((fat_cluster_num_to_sector512_num(mt_entry, cl) + 
              (ofs >> FAT_SECTOR512_BITS)) << 4)              + 
              ((ofs >> 5) & (FAT_DIRENTRIES_PER_SEC512 - 1)) );
}

/* Prototypes for "fat-file" operations */
int 
fat_file_open(rtems_filesystem_mount_table_entry_t  *mt_entry,
              uint32_t                               cln, 
              uint32_t                               ofs,
              fat_file_fd_t                        **fat_fd);

int
fat_file_reopen(fat_file_fd_t *fat_fd);

int 
fat_file_close(rtems_filesystem_mount_table_entry_t *mt_entry,
               fat_file_fd_t                        *fat_fd);

ssize_t
fat_file_read(rtems_filesystem_mount_table_entry_t *mt_entry,
              fat_file_fd_t                        *fat_fd,
              uint32_t                              start,
              uint32_t                              count,
              char                                 *buf);

ssize_t
fat_file_write(rtems_filesystem_mount_table_entry_t *mt_entry,
               fat_file_fd_t                        *fat_fd,
               uint32_t                              start,
               uint32_t                              count,
               const char                            *buf);

int
fat_file_extend(rtems_filesystem_mount_table_entry_t *mt_entry,
                fat_file_fd_t                        *fat_fd,
                uint32_t                              new_length,
                uint32_t                             *a_length);

int
fat_file_truncate(rtems_filesystem_mount_table_entry_t *mt_entry,
                  fat_file_fd_t                        *fat_fd,
                  uint32_t                              new_length);
                  
int
fat_file_datasync(rtems_filesystem_mount_table_entry_t *mt_entry,
                  fat_file_fd_t                        *fat_fd);
                  

int
fat_file_ioctl(rtems_filesystem_mount_table_entry_t *mt_entry,
               fat_file_fd_t                        *fat_fd,
               int                                   cmd,
               ...);

int
fat_file_size(rtems_filesystem_mount_table_entry_t *mt_entry,
              fat_file_fd_t                        *fat_fd);

void
fat_file_mark_removed(rtems_filesystem_mount_table_entry_t *mt_entry,
                      fat_file_fd_t                        *fat_fd);

#ifdef __cplusplus
}
#endif

#endif /* __DOSFS_FAT_FILE_H__ */