Rev 2891 | Rev 2910 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2891 | Rev 2893 | ||
---|---|---|---|
Line 48... | Line 48... | ||
48 | #include <assert.h> |
48 | #include <assert.h> |
49 | #include <futex.h> |
49 | #include <futex.h> |
50 | 50 | ||
51 | #define BS_BLOCK 0 |
51 | #define BS_BLOCK 0 |
52 | 52 | ||
53 | #define FIN_KEY_DEV_HANDLE 0 |
- | |
54 | #define FIN_KEY_INDEX 1 |
- | |
55 | - | ||
56 | /** Hash table of FAT in-core nodes. */ |
- | |
57 | hash_table_t fin_hash; |
- | |
58 | - | ||
59 | /** List of free FAT in-core nodes. */ |
53 | /** List of free FAT nodes that still contain valid data. */ |
60 | link_t ffn_head; |
54 | LIST_INITIALIZE(ffn_head); |
61 | 55 | ||
62 | #define FAT_NAME_LEN 8 |
56 | #define FAT_NAME_LEN 8 |
63 | #define FAT_EXT_LEN 3 |
57 | #define FAT_EXT_LEN 3 |
64 | 58 | ||
65 | #define FAT_PAD ' ' |
59 | #define FAT_PAD ' ' |
Line 123... | Line 117... | ||
123 | 117 | ||
124 | #define fat_block_get(np, off) \ |
118 | #define fat_block_get(np, off) \ |
125 | _fat_block_get((np)->idx->dev_handle, (np)->firstc, (off)) |
119 | _fat_block_get((np)->idx->dev_handle, (np)->firstc, (off)) |
126 | 120 | ||
127 | static block_t * |
121 | static block_t * |
128 | _fat_block_get(dev_handle_t dev_handle, fat_cluster_t fc, off_t offset) |
122 | _fat_block_get(dev_handle_t dev_handle, fat_cluster_t firstc, off_t offset) |
129 | { |
123 | { |
130 | block_t *bb; |
124 | block_t *bb; |
131 | block_t *b; |
125 | block_t *b; |
132 | unsigned bps; |
126 | unsigned bps; |
133 | unsigned spc; |
127 | unsigned spc; |
Line 136... | Line 130... | ||
136 | unsigned rde; |
130 | unsigned rde; |
137 | unsigned rds; /* root directory size */ |
131 | unsigned rds; /* root directory size */ |
138 | unsigned sf; |
132 | unsigned sf; |
139 | unsigned ssa; /* size of the system area */ |
133 | unsigned ssa; /* size of the system area */ |
140 | unsigned clusters; |
134 | unsigned clusters; |
141 | fat_cluster_t clst = fc; |
135 | fat_cluster_t clst = firstc; |
142 | unsigned i; |
136 | unsigned i; |
143 | 137 | ||
144 | bb = block_get(dev_handle, BS_BLOCK); |
138 | bb = block_get(dev_handle, BS_BLOCK); |
145 | bps = uint16_t_le2host(FAT_BS(bb)->bps); |
139 | bps = uint16_t_le2host(FAT_BS(bb)->bps); |
146 | spc = FAT_BS(bb)->spc; |
140 | spc = FAT_BS(bb)->spc; |
Line 152... | Line 146... | ||
152 | 146 | ||
153 | rds = (sizeof(fat_dentry_t) * rde) / bps; |
147 | rds = (sizeof(fat_dentry_t) * rde) / bps; |
154 | rds += ((sizeof(fat_dentry_t) * rde) % bps != 0); |
148 | rds += ((sizeof(fat_dentry_t) * rde) % bps != 0); |
155 | ssa = rscnt + fatcnt * sf + rds; |
149 | ssa = rscnt + fatcnt * sf + rds; |
156 | 150 | ||
157 | if (fc == FAT_CLST_RES1) { |
151 | if (firstc == FAT_CLST_RES1) { |
158 | /* root directory special case */ |
152 | /* root directory special case */ |
159 | assert(offset < rds); |
153 | assert(offset < rds); |
160 | b = block_get(dev_handle, rscnt + fatcnt * sf + offset); |
154 | b = block_get(dev_handle, rscnt + fatcnt * sf + offset); |
161 | return b; |
155 | return b; |
162 | } |
156 | } |
Line 185... | Line 179... | ||
185 | 179 | ||
186 | static void fat_node_initialize(fat_node_t *node) |
180 | static void fat_node_initialize(fat_node_t *node) |
187 | { |
181 | { |
188 | node->idx = NULL; |
182 | node->idx = NULL; |
189 | node->type = 0; |
183 | node->type = 0; |
190 | link_initialize(&node->fin_link); |
- | |
191 | link_initialize(&node->ffn_link); |
184 | link_initialize(&node->ffn_link); |
192 | node->size = 0; |
185 | node->size = 0; |
193 | node->lnkcnt = 0; |
186 | node->lnkcnt = 0; |
194 | node->refcnt = 0; |
187 | node->refcnt = 0; |
195 | node->dirty = false; |
188 | node->dirty = false; |
Line 236... | Line 229... | ||
236 | return FAT_DENTRY_SKIP; |
229 | return FAT_DENTRY_SKIP; |
237 | } |
230 | } |
238 | return FAT_DENTRY_VALID; |
231 | return FAT_DENTRY_VALID; |
239 | } |
232 | } |
240 | 233 | ||
241 | static void fat_sync_node(fat_node_t *node) |
234 | static void fat_node_sync(fat_node_t *node) |
242 | { |
235 | { |
243 | /* TODO */ |
236 | /* TODO */ |
244 | } |
237 | } |
245 | 238 | ||
246 | /** Instantiate a FAT in-core node. */ |
239 | /** Instantiate a FAT in-core node. */ |
Line 270... | Line 263... | ||
270 | * We must instantiate the node from the file system. |
263 | * We must instantiate the node from the file system. |
271 | */ |
264 | */ |
272 | 265 | ||
273 | assert(idx->pfc); |
266 | assert(idx->pfc); |
274 | 267 | ||
- | 268 | if (!list_empty(&ffn_head)) { |
|
- | 269 | /* Try to use a cached unused node structure. */ |
|
- | 270 | nodep = list_get_instance(ffn_head.next, fat_node_t, ffn_link); |
|
- | 271 | if (nodep->dirty) |
|
- | 272 | fat_node_sync(nodep); |
|
- | 273 | list_remove(&nodep->ffn_link); |
|
- | 274 | nodep->idx->nodep = NULL; |
|
- | 275 | } else { |
|
- | 276 | /* Try to allocate a new node structure. */ |
|
275 | nodep = (fat_node_t *)malloc(sizeof(fat_node_t)); |
277 | nodep = (fat_node_t *)malloc(sizeof(fat_node_t)); |
276 | if (!nodep) |
278 | if (!nodep) |
277 | return NULL; |
279 | return NULL; |
- | 280 | } |
|
278 | fat_node_initialize(nodep); |
281 | fat_node_initialize(nodep); |
279 | 282 | ||
280 | bps = fat_bps_get(dev_handle); |
283 | bps = fat_bps_get(dev_handle); |
281 | dps = bps / sizeof(fat_dentry_t); |
284 | dps = bps / sizeof(fat_dentry_t); |
282 | 285 | ||
- | 286 | /* Read the block that contains the dentry of interest. */ |
|
283 | b = _fat_block_get(dev_handle, idx->pfc, |
287 | b = _fat_block_get(dev_handle, idx->pfc, |
284 | (idx->pdi * sizeof(fat_dentry_t)) / bps); |
288 | (idx->pdi * sizeof(fat_dentry_t)) / bps); |
285 | - | ||
286 | assert(b); |
289 | assert(b); |
287 | 290 | ||
288 | d = ((fat_dentry_t *)b->data) + (idx->pdi % dps); |
291 | d = ((fat_dentry_t *)b->data) + (idx->pdi % dps); |
- | 292 | if (d->attr & FAT_ATTR_SUBDIR) { |
|
- | 293 | /* |
|
- | 294 | * The only directory which does not have this bit set is the |
|
- | 295 | * root directory itself. The root directory node is handled |
|
- | 296 | * and initialized elsewhere. |
|
289 | /* XXX */ |
297 | */ |
- | 298 | nodep->type = FAT_DIRECTORY; |
|
- | 299 | } else { |
|
- | 300 | nodep->type = FAT_FILE; |
|
- | 301 | } |
|
- | 302 | nodep->firstc = uint16_t_le2host(d->firstc); |
|
- | 303 | nodep->size = uint32_t_le2host(d->size); |
|
- | 304 | nodep->lnkcnt = 1; |
|
- | 305 | nodep->refcnt = 1; |
|
- | 306 | ||
- | 307 | block_put(b); |
|
- | 308 | ||
- | 309 | /* Link the idx structure with the node structure. */ |
|
- | 310 | nodep->idx = idx; |
|
- | 311 | idx->nodep = nodep; |
|
- | 312 | ||
- | 313 | return nodep; |
|
290 | } |
314 | } |
291 | 315 | ||
292 | static void fat_node_put(void *node) |
316 | static void fat_node_put(void *node) |
293 | { |
317 | { |
294 | /* TODO */ |
318 | /* TODO */ |
Line 438... | Line 462... | ||
438 | return false; |
462 | return false; |
439 | } |
463 | } |
440 | 464 | ||
441 | static void *fat_root_get(dev_handle_t dev_handle) |
465 | static void *fat_root_get(dev_handle_t dev_handle) |
442 | { |
466 | { |
443 | return fat_node_get(dev_handle, 0); /* TODO */ |
467 | return NULL; /* TODO */ |
444 | } |
468 | } |
445 | 469 | ||
446 | static char fat_plb_get_char(unsigned pos) |
470 | static char fat_plb_get_char(unsigned pos) |
447 | { |
471 | { |
448 | return fat_reg.plb_ro[pos % PLB_SIZE]; |
472 | return fat_reg.plb_ro[pos % PLB_SIZE]; |