Rev 2859 | Rev 2864 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2859 | Rev 2863 | ||
---|---|---|---|
Line 249... | Line 249... | ||
249 | static void fat_sync_node(fat_node_t *node) |
249 | static void fat_sync_node(fat_node_t *node) |
250 | { |
250 | { |
251 | /* TODO */ |
251 | /* TODO */ |
252 | } |
252 | } |
253 | 253 | ||
254 | /** Instantiate a FAT in-core node. |
254 | /** Instantiate a FAT in-core node. */ |
255 | * |
- | |
256 | * FAT stores the info necessary for instantiation of a node in the parent of |
- | |
257 | * that node. This design necessitated the addition of the parent node index |
- | |
258 | * parameter to this otherwise generic libfs API. |
- | |
259 | */ |
- | |
260 | static void * |
255 | static void * |
261 | fat_node_get(dev_handle_t dev_handle, fs_index_t index, fs_index_t pindex) |
256 | fat_node_get(dev_handle_t dev_handle, fs_index_t index) |
262 | { |
257 | { |
263 | link_t *lnk; |
- | |
264 | fat_node_t *node = NULL; |
- | |
265 | block_t *b; |
- | |
266 | unsigned bps; |
- | |
267 | unsigned dps; |
- | |
268 | fat_dentry_t *d; |
- | |
269 | unsigned i, j; |
- | |
270 | - | ||
271 | unsigned long key[] = { |
- | |
272 | [FIN_KEY_DEV_HANDLE] = dev_handle, |
- | |
273 | [FIN_KEY_INDEX] = index |
- | |
274 | }; |
- | |
275 | - | ||
276 | futex_down(&fin_futex); |
- | |
277 | lnk = hash_table_find(&fin_hash, key); |
- | |
278 | if (lnk) { |
- | |
279 | /* |
- | |
280 | * The in-core node was found in the hash table. |
- | |
281 | */ |
- | |
282 | node = hash_table_get_instance(lnk, fat_node_t, fin_link); |
- | |
283 | if (!node->refcnt++) |
- | |
284 | list_remove(&node->ffn_link); |
- | |
285 | futex_up(&fin_futex); |
- | |
286 | - | ||
287 | /* Make sure that the node is fully instantiated. */ |
- | |
288 | futex_down(&node->lock); |
- | |
289 | futex_up(&node->lock); |
- | |
290 | - | ||
291 | return (void *) node; |
- | |
292 | } |
- | |
293 | - | ||
294 | bps = fat_bps_get(dev_handle); |
- | |
295 | dps = bps / sizeof(fat_dentry_t); |
- | |
296 | - | ||
297 | if (!list_empty(&ffn_head)) { |
- | |
298 | /* |
- | |
299 | * We are going to reuse a node from the free list. |
- | |
300 | */ |
- | |
301 | lnk = ffn_head.next; |
- | |
302 | list_remove(lnk); |
- | |
303 | node = list_get_instance(lnk, fat_node_t, ffn_link); |
- | |
304 | assert(!node->refcnt); |
- | |
305 | if (node->dirty) |
- | |
306 | fat_sync_node(node); |
- | |
307 | key[FIN_KEY_DEV_HANDLE] = node->dev_handle; |
- | |
308 | key[FIN_KEY_INDEX] = node->index; |
- | |
309 | hash_table_remove(&fin_hash, key, sizeof(key)/sizeof(*key)); |
- | |
310 | } else { |
- | |
311 | /* |
- | |
312 | * We need to allocate a new node. |
- | |
313 | */ |
- | |
314 | node = malloc(sizeof(fat_node_t)); |
- | |
315 | if (!node) |
- | |
316 | return NULL; |
258 | return NULL; /* TODO */ |
317 | } |
- | |
318 | fat_node_initialize(node); |
- | |
319 | node->refcnt++; |
- | |
320 | node->lnkcnt++; |
- | |
321 | node->dev_handle = dev_handle; |
- | |
322 | node->index = index; |
- | |
323 | node->pindex = pindex; |
- | |
324 | key[FIN_KEY_DEV_HANDLE] = node->dev_handle; |
- | |
325 | key[FIN_KEY_INDEX] = node->index; |
- | |
326 | hash_table_insert(&fin_hash, key, &node->fin_link); |
- | |
327 | - | ||
328 | /* |
- | |
329 | * We have already put the node back to fin_hash. |
- | |
330 | * The node is not yet fully instantiated so we lock it prior to |
- | |
331 | * unlocking fin_hash. |
- | |
332 | */ |
- | |
333 | futex_down(&node->lock); |
- | |
334 | futex_up(&fin_futex); |
- | |
335 | - | ||
336 | /* |
- | |
337 | * Because of the design of the FAT file system, we have no clue about |
- | |
338 | * how big (i.e. how many directory entries it contains) is the parent |
- | |
339 | * of the node we are trying to instantiate. However, we know that it |
- | |
340 | * must contain a directory entry for our node of interest. We simply |
- | |
341 | * scan the parent until we find it. |
- | |
342 | */ |
- | |
343 | for (i = 0; ; i++) { |
- | |
344 | b = fat_block_get(node->dev_handle, node->pindex, i); |
- | |
345 | for (j = 0; j < dps; j++) { |
- | |
346 | d = ((fat_dentry_t *)b->data) + j; |
- | |
347 | if (d->firstc == node->index) |
- | |
348 | goto found; |
- | |
349 | } |
- | |
350 | block_put(b); |
- | |
351 | } |
- | |
352 | - | ||
353 | found: |
- | |
354 | if (!(d->attr & (FAT_ATTR_SUBDIR | FAT_ATTR_VOLLABEL))) |
- | |
355 | node->type = FAT_FILE; |
- | |
356 | if ((d->attr & FAT_ATTR_SUBDIR) || !index) |
- | |
357 | node->type = FAT_DIRECTORY; |
- | |
358 | assert((node->type == FAT_FILE) || (node->type == FAT_DIRECTORY)); |
- | |
359 | - | ||
360 | node->size = uint32_t_le2host(d->size); |
- | |
361 | block_put(b); |
- | |
362 | - | ||
363 | futex_up(&node->lock); |
- | |
364 | return node; |
- | |
365 | } |
259 | } |
366 | 260 | ||
367 | static void fat_node_put(void *node) |
261 | static void fat_node_put(void *node) |
368 | { |
262 | { |
369 | fat_node_t *nodep = (fat_node_t *)node; |
- | |
370 | - | ||
371 | futex_down(&fin_futex); |
- | |
372 | if (!--nodep->refcnt) |
263 | /* TODO */ |
373 | list_append(&nodep->ffn_link, &ffn_head); |
- | |
374 | futex_up(&fin_futex); |
- | |
375 | } |
264 | } |
376 | 265 | ||
377 | static void *fat_create(int flags) |
266 | static void *fat_create(int flags) |
378 | { |
267 | { |
379 | return NULL; /* not supported at the moment */ |
268 | return NULL; /* not supported at the moment */ |
Line 429... | Line 318... | ||
429 | break; |
318 | break; |
430 | } |
319 | } |
431 | if (strcmp(name, component) == 0) { |
320 | if (strcmp(name, component) == 0) { |
432 | /* hit */ |
321 | /* hit */ |
433 | void *node = fat_node_get(parentp->dev_handle, |
322 | void *node = fat_node_get(parentp->dev_handle, |
434 | (fs_index_t)uint16_t_le2host(d->firstc), |
323 | (fs_index_t)uint16_t_le2host(d->firstc)); |
435 | parentp->index); |
- | |
436 | block_put(b); |
324 | block_put(b); |
437 | return node; |
325 | return node; |
438 | } |
326 | } |
439 | } |
327 | } |
440 | block_put(b); |
328 | block_put(b); |
Line 508... | Line 396... | ||
508 | return false; |
396 | return false; |
509 | } |
397 | } |
510 | 398 | ||
511 | static void *fat_root_get(dev_handle_t dev_handle) |
399 | static void *fat_root_get(dev_handle_t dev_handle) |
512 | { |
400 | { |
513 | return fat_node_get(dev_handle, 0, 0); |
401 | return fat_node_get(dev_handle, 0); |
514 | } |
402 | } |
515 | 403 | ||
516 | static char fat_plb_get_char(unsigned pos) |
404 | static char fat_plb_get_char(unsigned pos) |
517 | { |
405 | { |
518 | return fat_reg.plb_ro[pos % PLB_SIZE]; |
406 | return fat_reg.plb_ro[pos % PLB_SIZE]; |