source: mainline/uspace/srv/fs/fat/fat.h@ 869e546

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 869e546 was 869e546, checked in by Jakub Jermar <jakub@…>, 18 years ago

Introduce the foundation for unique and stable FAT VFS node indices.

The first two reserved FAT entries are physically present in each FAT, so fix
the code to be aware of this.

  • Property mode set to 100644
File size: 6.4 KB
Line 
1/*
2 * Copyright (c) 2008 Jakub Jermar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup fs
30 * @{
31 */
32
33#ifndef FAT_FAT_H_
34#define FAT_FAT_H_
35
36#include <ipc/ipc.h>
37#include <libfs.h>
38#include <atomic.h>
39#include <sys/types.h>
40#include <bool.h>
41#include "../../vfs/vfs.h"
42
43#define dprintf(...) printf(__VA_ARGS__)
44
45typedef struct {
46 uint8_t ji[3]; /**< Jump instruction. */
47 uint8_t oem_name[8];
48 /* BIOS Parameter Block */
49 uint16_t bps; /**< Bytes per sector. */
50 uint8_t spc; /**< Sectors per cluster. */
51 uint16_t rscnt; /**< Reserved sector count. */
52 uint8_t fatcnt; /**< Number of FATs. */
53 uint16_t root_ent_max; /**< Maximum number of root directory
54 entries. */
55 uint16_t totsec16; /**< Total sectors. 16-bit version. */
56 uint8_t mdesc; /**< Media descriptor. */
57 uint16_t sec_per_fat; /**< Sectors per FAT12/FAT16. */
58 uint16_t sec_per_track; /**< Sectors per track. */
59 uint16_t headcnt; /**< Number of heads. */
60 uint32_t hidden_sec; /**< Hidden sectors. */
61 uint32_t totsec32; /**< Total sectors. 32-bit version. */
62
63 union {
64 struct {
65 /* FAT12/FAT16 only: Extended BIOS Parameter Block */
66 /** Physical drive number. */
67 uint8_t pdn;
68 uint8_t reserved;
69 /** Extended boot signature. */
70 uint8_t ebs;
71 /** Serial number. */
72 uint32_t id;
73 /** Volume label. */
74 uint8_t label[11];
75 /** FAT type. */
76 uint8_t type[8];
77 /** Boot code. */
78 uint8_t boot_code[448];
79 /** Boot sector signature. */
80 uint16_t signature;
81 } __attribute__ ((packed));
82 struct {
83 /* FAT32 only */
84 /** Sectors per FAT. */
85 uint32_t sectors_per_fat;
86 /** FAT flags. */
87 uint16_t flags;
88 /** Version. */
89 uint16_t version;
90 /** Cluster number of root directory. */
91 uint32_t root_cluster;
92 /** Sector number of file system information sector. */
93 uint16_t fsinfo_sec;
94 /** Sector number of boot sector copy. */
95 uint16_t bscopy_sec;
96 uint8_t reserved1[12];
97 /** Physical drive number. */
98 uint8_t pdn;
99 uint8_t reserved2;
100 /** Extended boot signature. */
101 uint8_t ebs;
102 /** Serial number. */
103 uint32_t id;
104 /** Volume label. */
105 uint8_t label[11];
106 /** FAT type. */
107 uint8_t type[8];
108 /** Boot code. */
109 uint8_t boot_code[420];
110 /** Signature. */
111 uint16_t signature;
112 } __attribute__ ((packed));
113 };
114} __attribute__ ((packed)) fat_bs_t;
115
116#define FAT_ATTR_RDONLY (1 << 0)
117#define FAT_ATTR_VOLLABEL (1 << 3)
118#define FAT_ATTR_SUBDIR (1 << 4)
119
120typedef struct {
121 uint8_t name[8];
122 uint8_t ext[3];
123 uint8_t attr;
124 uint8_t reserved;
125 uint8_t ctime_fine;
126 uint16_t ctime;
127 uint16_t cdate;
128 uint16_t adate;
129 union {
130 uint16_t eaidx; /* FAT12/FAT16 */
131 uint16_t firstc_hi; /* FAT32 */
132 };
133 uint16_t mtime;
134 uint16_t mdate;
135 union {
136 uint16_t firstc; /* FAT12/FAT16 */
137 uint16_t firstc_lo; /* FAT32 */
138 };
139 uint32_t size;
140} __attribute__ ((packed)) fat_dentry_t;
141
142typedef uint16_t fat_cluster_t;
143
144typedef enum {
145 FAT_INVALID,
146 FAT_DIRECTORY,
147 FAT_FILE
148} fat_node_type_t;
149
150struct fat_node;
151
152/** FAT index structure.
153 *
154 * This structure exists to help us to overcome certain limitations of the FAT
155 * file system design. The problem with FAT is that it is hard to find
156 * an entity which could represent a VFS index. There are two candidates:
157 *
158 * a) number of the node's first cluster
159 * b) the pair of the parent directory's first cluster and the dentry index
160 * within the parent directory
161 *
162 * We need VFS indices to be:
163 * A) unique
164 * B) stable in time, at least until the next mount
165 *
166 * Unfortunately a) does not meet the A) criterion because zero-length files
167 * will have the first cluster field cleared. And b) does not meet the B)
168 * criterion because unlink() and rename() will both free up the original
169 * dentry, which contains all the essential info about the file.
170 *
171 * Therefore, a completely opaque indices are used and the FAT server maintains
172 * a mapping between them and otherwise nice b) variant. On rename(), the VFS
173 * index stays unaltered, while the internal FAT "physical tree address"
174 * changes. The unlink case is also handled this way thanks to an in-core node
175 * pointer embedded in the index structure.
176 */
177typedef struct {
178 dev_handle_t dev_handle;
179 fs_index_t index;
180 /**
181 * Parent first cluster.
182 * Zero is used if this node is not linked, in which case nodep must
183 * contain a pointer to the in-core node structure.
184 * One is used when the parent is the root directory.
185 */
186 fat_cluster_t pfc;
187 /** Parent directory entry index. */
188 unsigned pdi;
189 /** Pointer to in-core node instance. */
190 struct fat_node *nodep;
191} fat_idx_t;
192
193/** FAT in-core node. */
194typedef struct fat_node {
195 fat_node_type_t type;
196 fat_idx_t *idx;
197 /**
198 * Node's first cluster.
199 * Zero is used for zero-length nodes.
200 * One is used to mark root directory.
201 */
202 fat_cluster_t firstc;
203 /** FAT in-core node hash table link. */
204 link_t fin_link;
205 /** FAT in-core node free list link. */
206 link_t ffn_link;
207 size_t size;
208 unsigned lnkcnt;
209 unsigned refcnt;
210 bool dirty;
211} fat_node_t;
212
213extern fs_reg_t fat_reg;
214
215extern void fat_lookup(ipc_callid_t, ipc_call_t *);
216
217#endif
218
219/**
220 * @}
221 */
Note: See TracBrowser for help on using the repository browser.