Rev 2863 | Rev 2876 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2863 | Rev 2864 | ||
---|---|---|---|
Line 51... | Line 51... | ||
51 | #define BS_BLOCK 0 |
51 | #define BS_BLOCK 0 |
52 | 52 | ||
53 | #define FIN_KEY_DEV_HANDLE 0 |
53 | #define FIN_KEY_DEV_HANDLE 0 |
54 | #define FIN_KEY_INDEX 1 |
54 | #define FIN_KEY_INDEX 1 |
55 | 55 | ||
56 | /** Futex protecting both fin_hash and ffn_head. */ |
- | |
57 | futex_t fin_futex = FUTEX_INITIALIZER; |
- | |
58 | - | ||
59 | /** Hash table of FAT in-core nodes. */ |
56 | /** Hash table of FAT in-core nodes. */ |
60 | hash_table_t fin_hash; |
57 | hash_table_t fin_hash; |
61 | 58 | ||
62 | /** List of free FAT in-core nodes. */ |
59 | /** List of free FAT in-core nodes. */ |
63 | link_t ffn_head; |
60 | link_t ffn_head; |
Line 113... | Line 110... | ||
113 | static void block_put(block_t *block) |
110 | static void block_put(block_t *block) |
114 | { |
111 | { |
115 | /* TODO */ |
112 | /* TODO */ |
116 | } |
113 | } |
117 | 114 | ||
- | 115 | static fat_idx_t *fat_idx_map(fat_cluster_t pfc, unsigned pdi) |
|
- | 116 | { |
|
- | 117 | return NULL; /* TODO */ |
|
- | 118 | } |
|
118 | 119 | ||
119 | #define FAT_BS(b) ((fat_bs_t *)((b)->data)) |
120 | #define FAT_BS(b) ((fat_bs_t *)((b)->data)) |
120 | 121 | ||
- | 122 | #define FAT_CLST_RES0 0x0000 |
|
- | 123 | #define FAT_CLST_RES1 0x0001 /* internally used to mark root directory */ |
|
121 | #define FAT_CLST_FIRST 0x0002 |
124 | #define FAT_CLST_FIRST 0x0002 |
122 | #define FAT_CLST_BAD 0xfff7 |
125 | #define FAT_CLST_BAD 0xfff7 |
123 | #define FAT_CLST_LAST1 0xfff8 |
126 | #define FAT_CLST_LAST1 0xfff8 |
124 | #define FAT_CLST_LAST8 0xffff |
127 | #define FAT_CLST_LAST8 0xffff |
125 | 128 | ||
126 | /** Convert cluster number to an index within a FAT. |
- | |
127 | * |
- | |
128 | * Format Identifier and cluster numbering is considered. |
- | |
129 | */ |
- | |
130 | #define C2FAT_IDX(c) (1 + (c) - FAT_CLST_FIRST) |
- | |
131 | - | ||
132 | static block_t *fat_block_get(dev_handle_t dev_handle, fs_index_t index, |
129 | static block_t *fat_block_get(fat_node_t *nodep, off_t offset) |
133 | off_t offset) |
- | |
134 | { |
130 | { |
135 | block_t *bb; |
131 | block_t *bb; |
136 | block_t *b; |
132 | block_t *b; |
137 | unsigned bps; |
133 | unsigned bps; |
138 | unsigned spc; |
134 | unsigned spc; |
Line 141... | Line 137... | ||
141 | unsigned rde; |
137 | unsigned rde; |
142 | unsigned rds; /* root directory size */ |
138 | unsigned rds; /* root directory size */ |
143 | unsigned sf; |
139 | unsigned sf; |
144 | unsigned ssa; /* size of the system area */ |
140 | unsigned ssa; /* size of the system area */ |
145 | unsigned clusters; |
141 | unsigned clusters; |
146 | unsigned clst = index; |
142 | fat_cluster_t clst = nodep->firstc; |
147 | unsigned i; |
143 | unsigned i; |
148 | 144 | ||
149 | bb = block_get(dev_handle, BS_BLOCK); |
145 | bb = block_get(nodep->idx->dev_handle, BS_BLOCK); |
150 | bps = uint16_t_le2host(FAT_BS(bb)->bps); |
146 | bps = uint16_t_le2host(FAT_BS(bb)->bps); |
151 | spc = FAT_BS(bb)->spc; |
147 | spc = FAT_BS(bb)->spc; |
152 | rscnt = uint16_t_le2host(FAT_BS(bb)->rscnt); |
148 | rscnt = uint16_t_le2host(FAT_BS(bb)->rscnt); |
153 | fatcnt = FAT_BS(bb)->fatcnt; |
149 | fatcnt = FAT_BS(bb)->fatcnt; |
154 | rde = uint16_t_le2host(FAT_BS(bb)->root_ent_max); |
150 | rde = uint16_t_le2host(FAT_BS(bb)->root_ent_max); |
Line 157... | Line 153... | ||
157 | 153 | ||
158 | rds = (sizeof(fat_dentry_t) * rde) / bps; |
154 | rds = (sizeof(fat_dentry_t) * rde) / bps; |
159 | rds += ((sizeof(fat_dentry_t) * rde) % bps != 0); |
155 | rds += ((sizeof(fat_dentry_t) * rde) % bps != 0); |
160 | ssa = rscnt + fatcnt * sf + rds; |
156 | ssa = rscnt + fatcnt * sf + rds; |
161 | 157 | ||
162 | if (!index) { |
158 | if (nodep->idx->index == FAT_CLST_RES1) { |
163 | /* root directory special case */ |
159 | /* root directory special case */ |
164 | assert(offset < rds); |
160 | assert(offset < rds); |
- | 161 | b = block_get(nodep->idx->dev_handle, |
|
165 | b = block_get(dev_handle, rscnt + fatcnt * sf + offset); |
162 | rscnt + fatcnt * sf + offset); |
166 | return b; |
163 | return b; |
167 | } |
164 | } |
168 | 165 | ||
169 | clusters = offset / spc; |
166 | clusters = offset / spc; |
170 | for (i = 0; i < clusters; i++) { |
167 | for (i = 0; i < clusters; i++) { |
171 | unsigned fsec; /* sector offset relative to FAT1 */ |
168 | unsigned fsec; /* sector offset relative to FAT1 */ |
172 | unsigned fidx; /* FAT1 entry index */ |
169 | unsigned fidx; /* FAT1 entry index */ |
173 | 170 | ||
174 | assert(clst >= FAT_CLST_FIRST && clst < FAT_CLST_BAD); |
171 | assert(clst >= FAT_CLST_FIRST && clst < FAT_CLST_BAD); |
175 | fsec = (C2FAT_IDX(clst) * sizeof(uint16_t)) / bps; |
172 | fsec = (clst * sizeof(fat_cluster_t)) / bps; |
176 | fidx = C2FAT_IDX(clst) % (bps / sizeof(uint16_t)); |
173 | fidx = clst % (bps / sizeof(fat_cluster_t)); |
177 | /* read FAT1 */ |
174 | /* read FAT1 */ |
178 | b = block_get(dev_handle, rscnt + fsec); |
175 | b = block_get(nodep->idx->dev_handle, rscnt + fsec); |
179 | clst = uint16_t_le2host(((uint16_t *)b->data)[fidx]); |
176 | clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]); |
180 | assert(clst != FAT_CLST_BAD); |
177 | assert(clst != FAT_CLST_BAD); |
181 | assert(clst < FAT_CLST_LAST1); |
178 | assert(clst < FAT_CLST_LAST1); |
182 | block_put(b); |
179 | block_put(b); |
183 | } |
180 | } |
184 | 181 | ||
185 | b = block_get(dev_handle, ssa + (clst - FAT_CLST_FIRST) * spc + |
182 | b = block_get(nodep->idx->dev_handle, ssa + |
186 | offset % spc); |
183 | (clst - FAT_CLST_FIRST) * spc + offset % spc); |
187 | 184 | ||
188 | return b; |
185 | return b; |
189 | } |
186 | } |
190 | 187 | ||
191 | static void fat_node_initialize(fat_node_t *node) |
188 | static void fat_node_initialize(fat_node_t *node) |
192 | { |
189 | { |
193 | futex_initialize(&node->lock, 1); |
190 | node->idx = NULL; |
194 | node->type = 0; |
191 | node->type = 0; |
195 | node->index = 0; |
- | |
196 | node->pindex = 0; |
- | |
197 | node->dev_handle = 0; |
- | |
198 | link_initialize(&node->fin_link); |
192 | link_initialize(&node->fin_link); |
199 | link_initialize(&node->ffn_link); |
193 | link_initialize(&node->ffn_link); |
200 | node->size = 0; |
194 | node->size = 0; |
201 | node->lnkcnt = 0; |
195 | node->lnkcnt = 0; |
202 | node->refcnt = 0; |
196 | node->refcnt = 0; |
Line 292... | Line 286... | ||
292 | unsigned dps; /* dentries per sector */ |
286 | unsigned dps; /* dentries per sector */ |
293 | unsigned blocks; |
287 | unsigned blocks; |
294 | fat_dentry_t *d; |
288 | fat_dentry_t *d; |
295 | block_t *b; |
289 | block_t *b; |
296 | 290 | ||
297 | bps = fat_bps_get(parentp->dev_handle); |
291 | bps = fat_bps_get(parentp->idx->dev_handle); |
298 | dps = bps / sizeof(fat_dentry_t); |
292 | dps = bps / sizeof(fat_dentry_t); |
299 | blocks = parentp->size / bps + (parentp->size % bps != 0); |
293 | blocks = parentp->size / bps + (parentp->size % bps != 0); |
300 | for (i = 0; i < blocks; i++) { |
294 | for (i = 0; i < blocks; i++) { |
301 | unsigned dentries; |
295 | unsigned dentries; |
302 | 296 | ||
303 | b = fat_block_get(parentp->dev_handle, parentp->index, i); |
297 | b = fat_block_get(parentp, i); |
304 | dentries = (i == blocks - 1) ? |
298 | dentries = (i == blocks - 1) ? |
305 | parentp->size % sizeof(fat_dentry_t) : |
299 | parentp->size % sizeof(fat_dentry_t) : |
306 | dps; |
300 | dps; |
307 | for (j = 0; j < dentries; j++) { |
301 | for (j = 0; j < dentries; j++) { |
308 | d = ((fat_dentry_t *)b->data) + j; |
302 | d = ((fat_dentry_t *)b->data) + j; |
Line 317... | Line 311... | ||
317 | dentry_name_canonify(d, name); |
311 | dentry_name_canonify(d, name); |
318 | break; |
312 | break; |
319 | } |
313 | } |
320 | if (strcmp(name, component) == 0) { |
314 | if (strcmp(name, component) == 0) { |
321 | /* hit */ |
315 | /* hit */ |
- | 316 | fat_idx_t *idx = fat_idx_map(parentp->firstc, |
|
- | 317 | i * dps + j); |
|
322 | void *node = fat_node_get(parentp->dev_handle, |
318 | void *node = fat_node_get(idx->dev_handle, |
323 | (fs_index_t)uint16_t_le2host(d->firstc)); |
319 | idx->index); |
324 | block_put(b); |
320 | block_put(b); |
325 | return node; |
321 | return node; |
326 | } |
322 | } |
327 | } |
323 | } |
328 | block_put(b); |
324 | block_put(b); |
Line 334... | Line 330... | ||
334 | static fs_index_t fat_index_get(void *node) |
330 | static fs_index_t fat_index_get(void *node) |
335 | { |
331 | { |
336 | fat_node_t *fnodep = (fat_node_t *)node; |
332 | fat_node_t *fnodep = (fat_node_t *)node; |
337 | if (!fnodep) |
333 | if (!fnodep) |
338 | return 0; |
334 | return 0; |
339 | return fnodep->index; |
335 | return fnodep->idx->index; |
340 | } |
336 | } |
341 | 337 | ||
342 | static size_t fat_size_get(void *node) |
338 | static size_t fat_size_get(void *node) |
343 | { |
339 | { |
344 | return ((fat_node_t *)node)->size; |
340 | return ((fat_node_t *)node)->size; |
Line 359... | Line 355... | ||
359 | unsigned i, j; |
355 | unsigned i, j; |
360 | 356 | ||
361 | if (nodep->type != FAT_DIRECTORY) |
357 | if (nodep->type != FAT_DIRECTORY) |
362 | return false; |
358 | return false; |
363 | 359 | ||
364 | bps = fat_bps_get(nodep->dev_handle); |
360 | bps = fat_bps_get(nodep->idx->dev_handle); |
365 | dps = bps / sizeof(fat_dentry_t); |
361 | dps = bps / sizeof(fat_dentry_t); |
366 | 362 | ||
367 | blocks = nodep->size / bps + (nodep->size % bps != 0); |
363 | blocks = nodep->size / bps + (nodep->size % bps != 0); |
368 | 364 | ||
369 | for (i = 0; i < blocks; i++) { |
365 | for (i = 0; i < blocks; i++) { |
370 | unsigned dentries; |
366 | unsigned dentries; |
371 | fat_dentry_t *d; |
367 | fat_dentry_t *d; |
372 | 368 | ||
373 | b = fat_block_get(nodep->dev_handle, nodep->index, i); |
369 | b = fat_block_get(nodep, i); |
374 | dentries = (i == blocks - 1) ? |
370 | dentries = (i == blocks - 1) ? |
375 | nodep->size % sizeof(fat_dentry_t) : |
371 | nodep->size % sizeof(fat_dentry_t) : |
376 | dps; |
372 | dps; |
377 | for (j = 0; j < dentries; j++) { |
373 | for (j = 0; j < dentries; j++) { |
378 | d = ((fat_dentry_t *)b->data) + j; |
374 | d = ((fat_dentry_t *)b->data) + j; |
Line 396... | Line 392... | ||
396 | return false; |
392 | return false; |
397 | } |
393 | } |
398 | 394 | ||
399 | static void *fat_root_get(dev_handle_t dev_handle) |
395 | static void *fat_root_get(dev_handle_t dev_handle) |
400 | { |
396 | { |
401 | return fat_node_get(dev_handle, 0); |
397 | return fat_node_get(dev_handle, FAT_CLST_RES1); |
402 | } |
398 | } |
403 | 399 | ||
404 | static char fat_plb_get_char(unsigned pos) |
400 | static char fat_plb_get_char(unsigned pos) |
405 | { |
401 | { |
406 | return fat_reg.plb_ro[pos % PLB_SIZE]; |
402 | return fat_reg.plb_ro[pos % PLB_SIZE]; |