Rev 2844 | Rev 2852 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2844 | Rev 2845 | ||
---|---|---|---|
Line 141... | Line 141... | ||
141 | block_put(bb); |
141 | block_put(bb); |
142 | 142 | ||
143 | return bps; |
143 | return bps; |
144 | } |
144 | } |
145 | 145 | ||
- | 146 | typedef enum { |
|
- | 147 | FAT_DENTRY_SKIP, |
|
- | 148 | FAT_DENTRY_LAST, |
|
- | 149 | FAT_DENTRY_VALID |
|
- | 150 | } fat_dentry_clsf_t; |
|
- | 151 | ||
- | 152 | static fat_dentry_clsf_t fat_classify_dentry(fat_dentry_t *d) |
|
- | 153 | { |
|
- | 154 | if (d->attr & FAT_ATTR_VOLLABEL) { |
|
- | 155 | /* volume label entry */ |
|
- | 156 | return FAT_DENTRY_SKIP; |
|
- | 157 | } |
|
- | 158 | if (d->name[0] == FAT_DENTRY_ERASED) { |
|
- | 159 | /* not-currently-used entry */ |
|
- | 160 | return FAT_DENTRY_SKIP; |
|
- | 161 | } |
|
- | 162 | if (d->name[0] == FAT_DENTRY_UNUSED) { |
|
- | 163 | /* never used entry */ |
|
- | 164 | return FAT_DENTRY_LAST; |
|
- | 165 | } |
|
- | 166 | if (d->name[0] == FAT_DENTRY_DOT) { |
|
- | 167 | /* |
|
- | 168 | * Most likely '.' or '..'. |
|
- | 169 | * It cannot occur in a regular file name. |
|
- | 170 | */ |
|
- | 171 | return FAT_DENTRY_SKIP; |
|
- | 172 | } |
|
- | 173 | return FAT_DENTRY_VALID; |
|
- | 174 | } |
|
- | 175 | ||
146 | static void fat_sync_node(fat_node_t *node) |
176 | static void fat_sync_node(fat_node_t *node) |
147 | { |
177 | { |
148 | /* TODO */ |
178 | /* TODO */ |
149 | } |
179 | } |
150 | 180 | ||
Line 219... | Line 249... | ||
219 | * must contain a directory entry for our node of interest. We simply |
249 | * must contain a directory entry for our node of interest. We simply |
220 | * scan the parent until we find it. |
250 | * scan the parent until we find it. |
221 | */ |
251 | */ |
222 | for (i = 0; ; i++) { |
252 | for (i = 0; ; i++) { |
223 | b = fat_block_get(node->dev_handle, node->pindex, i); |
253 | b = fat_block_get(node->dev_handle, node->pindex, i); |
224 | if (!b) { |
- | |
225 | node->refcnt--; |
- | |
226 | list_append(&node->ffn_link, &ffn_head); |
- | |
227 | return NULL; |
- | |
228 | } |
- | |
229 | for (j = 0; j < dps; j++) { |
254 | for (j = 0; j < dps; j++) { |
230 | d = ((fat_dentry_t *)b->data) + j; |
255 | d = ((fat_dentry_t *)b->data) + j; |
231 | if (d->firstc == node->index) |
256 | if (d->firstc == node->index) |
232 | goto found; |
257 | goto found; |
233 | } |
258 | } |
Line 267... | Line 292... | ||
267 | blocks = parentp->size / bps + (parentp->size % bps != 0); |
292 | blocks = parentp->size / bps + (parentp->size % bps != 0); |
268 | for (i = 0; i < blocks; i++) { |
293 | for (i = 0; i < blocks; i++) { |
269 | unsigned dentries; |
294 | unsigned dentries; |
270 | 295 | ||
271 | b = fat_block_get(parentp->dev_handle, parentp->index, i); |
296 | b = fat_block_get(parentp->dev_handle, parentp->index, i); |
272 | if (!b) |
- | |
273 | return NULL; |
- | |
274 | - | ||
275 | dentries = (i == blocks - 1) ? |
297 | dentries = (i == blocks - 1) ? |
276 | parentp->size % sizeof(fat_dentry_t) : |
298 | parentp->size % sizeof(fat_dentry_t) : |
277 | dps; |
299 | dps; |
278 | for (j = 0; j < dentries; j++) { |
300 | for (j = 0; j < dentries; j++) { |
279 | d = ((fat_dentry_t *)b->data) + j; |
301 | d = ((fat_dentry_t *)b->data) + j; |
280 | if (d->attr & FAT_ATTR_VOLLABEL) { |
- | |
281 | /* volume label entry */ |
302 | switch (fat_classify_dentry(d)) { |
282 | continue; |
- | |
283 | } |
- | |
284 | if (d->name[0] == FAT_DENTRY_ERASED) { |
303 | case FAT_DENTRY_SKIP: |
285 | /* not-currently-used entry */ |
- | |
286 | continue; |
304 | continue; |
287 | } |
- | |
288 | if (d->name[0] == FAT_DENTRY_UNUSED) { |
305 | case FAT_DENTRY_LAST: |
289 | /* never used entry */ |
- | |
290 | block_put(b); |
306 | block_put(b); |
291 | return NULL; |
307 | return NULL; |
292 | } |
308 | default: |
293 | if (d->name[0] == FAT_DENTRY_DOT) { |
309 | case FAT_DENTRY_VALID: |
294 | /* |
- | |
295 | * Most likely '.' or '..'. |
- | |
296 | * It cannot occur in a regular file name. |
- | |
297 | */ |
- | |
298 | continue; |
- | |
299 | } |
- | |
300 | - | ||
301 | dentry_name_canonify(d, name); |
310 | dentry_name_canonify(d, name); |
- | 311 | break; |
|
- | 312 | } |
|
302 | if (strcmp(name, component) == 0) { |
313 | if (strcmp(name, component) == 0) { |
303 | /* hit */ |
314 | /* hit */ |
304 | void *node = fat_node_get(parentp->dev_handle, |
315 | void *node = fat_node_get(parentp->dev_handle, |
305 | (fs_index_t)uint16_t_le2host(d->firstc), |
316 | (fs_index_t)uint16_t_le2host(d->firstc), |
306 | parentp->index); |
317 | parentp->index); |
Line 330... | Line 341... | ||
330 | static unsigned fat_lnkcnt_get(void *node) |
341 | static unsigned fat_lnkcnt_get(void *node) |
331 | { |
342 | { |
332 | return ((fat_node_t *)node)->lnkcnt; |
343 | return ((fat_node_t *)node)->lnkcnt; |
333 | } |
344 | } |
334 | 345 | ||
- | 346 | static bool fat_has_children(void *node) |
|
- | 347 | { |
|
- | 348 | fat_node_t *nodep = (fat_node_t *)node; |
|
- | 349 | unsigned bps; |
|
- | 350 | unsigned dps; |
|
- | 351 | unsigned blocks; |
|
- | 352 | block_t *b; |
|
- | 353 | unsigned i, j; |
|
- | 354 | ||
- | 355 | if (nodep->type != FAT_DIRECTORY) |
|
- | 356 | return false; |
|
- | 357 | ||
- | 358 | bps = fat_bps_get(nodep->dev_handle); |
|
- | 359 | dps = bps / sizeof(fat_dentry_t); |
|
- | 360 | ||
- | 361 | blocks = nodep->size / bps + (nodep->size % bps != 0); |
|
- | 362 | ||
- | 363 | for (i = 0; i < blocks; i++) { |
|
- | 364 | unsigned dentries; |
|
- | 365 | fat_dentry_t *d; |
|
- | 366 | ||
- | 367 | b = fat_block_get(nodep->dev_handle, nodep->index, i); |
|
- | 368 | dentries = (i == blocks - 1) ? |
|
- | 369 | nodep->size % sizeof(fat_dentry_t) : |
|
- | 370 | dps; |
|
- | 371 | for (j = 0; j < dentries; j++) { |
|
- | 372 | d = ((fat_dentry_t *)b->data) + j; |
|
- | 373 | switch (fat_classify_dentry(d)) { |
|
- | 374 | case FAT_DENTRY_SKIP: |
|
- | 375 | continue; |
|
- | 376 | case FAT_DENTRY_LAST: |
|
- | 377 | block_put(b); |
|
- | 378 | return false; |
|
- | 379 | default: |
|
- | 380 | case FAT_DENTRY_VALID: |
|
- | 381 | block_put(b); |
|
- | 382 | return true; |
|
- | 383 | } |
|
- | 384 | block_put(b); |
|
- | 385 | return true; |
|
- | 386 | } |
|
- | 387 | block_put(b); |
|
- | 388 | } |
|
- | 389 | ||
- | 390 | return false; |
|
- | 391 | } |
|
- | 392 | ||
335 | static void *fat_root_get(dev_handle_t dev_handle) |
393 | static void *fat_root_get(dev_handle_t dev_handle) |
336 | { |
394 | { |
337 | return fat_node_get(dev_handle, 0, 0); |
395 | return fat_node_get(dev_handle, 0, 0); |
338 | } |
396 | } |
339 | 397 | ||
Line 361... | Line 419... | ||
361 | .link = NULL, |
419 | .link = NULL, |
362 | .unlink = NULL, |
420 | .unlink = NULL, |
363 | .index_get = fat_index_get, |
421 | .index_get = fat_index_get, |
364 | .size_get = fat_size_get, |
422 | .size_get = fat_size_get, |
365 | .lnkcnt_get = fat_lnkcnt_get, |
423 | .lnkcnt_get = fat_lnkcnt_get, |
366 | .has_children = NULL, |
424 | .has_children = fat_has_children, |
367 | .root_get = fat_root_get, |
425 | .root_get = fat_root_get, |
368 | .plb_get_char = fat_plb_get_char, |
426 | .plb_get_char = fat_plb_get_char, |
369 | .is_directory = fat_is_directory, |
427 | .is_directory = fat_is_directory, |
370 | .is_file = fat_is_file |
428 | .is_file = fat_is_file |
371 | }; |
429 | }; |