source: mainline/uspace/srv/fs/fat/fat.h@ 47b2d7e3

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 47b2d7e3 was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 8 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 7.9 KB
Line 
1/*
2 * Copyright (c) 2008 Jakub Jermar
3 * Copyright (c) 2011 Oleg Romanenko
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup fs
31 * @{
32 */
33
34#ifndef FAT_FAT_H_
35#define FAT_FAT_H_
36
37#include "fat_fat.h"
38#include <fibril_synch.h>
39#include <libfs.h>
40#include <atomic.h>
41#include <stdint.h>
42#include <stdbool.h>
43#include <macros.h>
44#include "../../vfs/vfs.h"
45
46#ifndef dprintf
47#define dprintf(...) printf(__VA_ARGS__)
48#endif
49
50/*
51 * Convenience macros for accessing some frequently used boot sector members.
52 */
53#define BPS(bs) uint16_t_le2host((bs)->bps)
54#define SPC(bs) (bs)->spc
55#define RSCNT(bs) uint16_t_le2host((bs)->rscnt)
56#define FATCNT(bs) (bs)->fatcnt
57
58#define SF(bs) (uint16_t_le2host((bs)->sec_per_fat) ? \
59 uint16_t_le2host((bs)->sec_per_fat) : \
60 uint32_t_le2host(bs->fat32.sectors_per_fat))
61
62#define RDE(bs) uint16_t_le2host((bs)->root_ent_max)
63
64#define TS(bs) (uint16_t_le2host((bs)->totsec16) ? \
65 uint16_t_le2host((bs)->totsec16) : \
66 uint32_t_le2host(bs->totsec32))
67
68#define BS_BLOCK 0
69#define BS_SIZE 512
70
71typedef struct fat_bs {
72 uint8_t ji[3]; /**< Jump instruction. */
73 uint8_t oem_name[8];
74 /* BIOS Parameter Block */
75 uint16_t bps; /**< Bytes per sector. */
76 uint8_t spc; /**< Sectors per cluster. */
77 uint16_t rscnt; /**< Reserved sector count. */
78 uint8_t fatcnt; /**< Number of FATs. */
79 uint16_t root_ent_max; /**< Maximum number of root directory
80 entries. */
81 uint16_t totsec16; /**< Total sectors. 16-bit version. */
82 uint8_t mdesc; /**< Media descriptor. */
83 uint16_t sec_per_fat; /**< Sectors per FAT12/FAT16. */
84 uint16_t sec_per_track; /**< Sectors per track. */
85 uint16_t headcnt; /**< Number of heads. */
86 uint32_t hidden_sec; /**< Hidden sectors. */
87 uint32_t totsec32; /**< Total sectors. 32-bit version. */
88
89 union {
90 struct {
91 /* FAT12/FAT16 only: Extended BIOS Parameter Block */
92 /** Physical drive number. */
93 uint8_t pdn;
94 uint8_t reserved;
95 /** Extended boot signature. */
96 uint8_t ebs;
97 /** Serial number. */
98 uint32_t id;
99 /** Volume label. */
100 uint8_t label[11];
101 /** FAT type. */
102 uint8_t type[8];
103 /** Boot code. */
104 uint8_t boot_code[448];
105 /** Boot sector signature. */
106 uint16_t signature;
107 } __attribute__ ((packed));
108 struct {
109 /* FAT32 only */
110 /** Sectors per FAT. */
111 uint32_t sectors_per_fat;
112 /** FAT flags. */
113 uint16_t flags;
114 /** Version. */
115 uint16_t version;
116 /** Cluster number of root directory. */
117 uint32_t root_cluster;
118 /** Sector number of file system information sector. */
119 uint16_t fsinfo_sec;
120 /** Sector number of boot sector copy. */
121 uint16_t bscopy_sec;
122 uint8_t reserved1[12];
123 /** Physical drive number. */
124 uint8_t pdn;
125 uint8_t reserved2;
126 /** Extended boot signature. */
127 uint8_t ebs;
128 /** Serial number. */
129 uint32_t id;
130 /** Volume label. */
131 uint8_t label[11];
132 /** FAT type. */
133 uint8_t type[8];
134 /** Boot code. */
135 uint8_t boot_code[420];
136 /** Signature. */
137 uint16_t signature;
138 } __attribute__ ((packed)) fat32;
139 };
140} __attribute__ ((packed)) fat_bs_t;
141
142#define FAT32_FSINFO_SIG1 "RRaA"
143#define FAT32_FSINFO_SIG2 "rrAa"
144#define FAT32_FSINFO_SIG3 "\x00\x00\x55\xaa"
145
146typedef struct {
147 uint8_t sig1[4];
148 uint8_t res1[480];
149 uint8_t sig2[4];
150 uint32_t free_clusters;
151 uint32_t last_allocated_cluster;
152 uint8_t res2[12];
153 uint8_t sig3[4];
154} __attribute__ ((packed)) fat32_fsinfo_t;
155
156typedef enum {
157 FAT_INVALID,
158 FAT_DIRECTORY,
159 FAT_FILE
160} fat_node_type_t;
161
162struct fat_node;
163
164/** FAT index structure.
165 *
166 * This structure exists to help us to overcome certain limitations of the FAT
167 * file system design. The problem with FAT is that it is hard to find
168 * an entity which could represent a VFS index. There are two candidates:
169 *
170 * a) number of the node's first cluster
171 * b) the pair of the parent directory's first cluster and the dentry index
172 * within the parent directory
173 *
174 * We need VFS indices to be:
175 * A) unique
176 * B) stable in time, at least until the next mount
177 *
178 * Unfortunately a) does not meet the A) criterion because zero-length files
179 * will have the first cluster field cleared. And b) does not meet the B)
180 * criterion because unlink() and rename() will both free up the original
181 * dentry, which contains all the essential info about the file.
182 *
183 * Therefore, a completely opaque indices are used and the FAT server maintains
184 * a mapping between them and otherwise nice b) variant. On rename(), the VFS
185 * index stays unaltered, while the internal FAT "physical tree address"
186 * changes. The unlink case is also handled this way thanks to an in-core node
187 * pointer embedded in the index structure.
188 */
189typedef struct {
190 /** Used indices (position) hash table link. */
191 ht_link_t uph_link;
192 /** Used indices (index) hash table link. */
193 ht_link_t uih_link;
194
195 fibril_mutex_t lock;
196 service_id_t service_id;
197 fs_index_t index;
198 /**
199 * Parent node's first cluster.
200 * Zero is used if this node is not linked, in which case nodep must
201 * contain a pointer to the in-core node structure.
202 * One is used when the parent is the root directory.
203 */
204 fat_cluster_t pfc;
205 /** Directory entry index within the parent node. */
206 unsigned pdi;
207 /** Pointer to in-core node instance. */
208 struct fat_node *nodep;
209} fat_idx_t;
210
211/** FAT in-core node. */
212typedef struct fat_node {
213 /** Back pointer to the FS node. */
214 fs_node_t *bp;
215
216 fibril_mutex_t lock;
217 fat_node_type_t type;
218 fat_idx_t *idx;
219 /**
220 * Node's first cluster.
221 * Zero is used for zero-length nodes.
222 * One is used to mark root directory.
223 */
224 fat_cluster_t firstc;
225 /** FAT in-core node free list link. */
226 link_t ffn_link;
227 aoff64_t size;
228 unsigned lnkcnt;
229 unsigned refcnt;
230 bool dirty;
231
232 /*
233 * Cache of the node's last and "current" cluster to avoid some
234 * unnecessary FAT walks.
235 */
236 /* Node's last cluster in FAT. */
237 bool lastc_cached_valid;
238 fat_cluster_t lastc_cached_value;
239 /* Node's "current" cluster, i.e. where the last I/O took place. */
240 bool currc_cached_valid;
241 aoff64_t currc_cached_bn;
242 fat_cluster_t currc_cached_value;
243} fat_node_t;
244
245typedef struct {
246 bool lfn_enabled;
247} fat_instance_t;
248
249extern vfs_out_ops_t fat_ops;
250extern libfs_ops_t fat_libfs_ops;
251
252extern errno_t fat_idx_get_new(fat_idx_t **, service_id_t);
253extern fat_idx_t *fat_idx_get_by_pos(service_id_t, fat_cluster_t, unsigned);
254extern fat_idx_t *fat_idx_get_by_index(service_id_t, fs_index_t);
255extern void fat_idx_destroy(fat_idx_t *);
256extern void fat_idx_hashin(fat_idx_t *);
257extern void fat_idx_hashout(fat_idx_t *);
258
259extern errno_t fat_idx_init(void);
260extern void fat_idx_fini(void);
261extern errno_t fat_idx_init_by_service_id(service_id_t);
262extern void fat_idx_fini_by_service_id(service_id_t);
263
264#endif
265
266/**
267 * @}
268 */
Note: See TracBrowser for help on using the repository browser.