Changeset 0fdd6bb in mainline for uspace/srv/fs/fat/fat_ops.c
- Timestamp:
- 2008-11-23T16:22:40Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a5da446
- Parents:
- d2093d6
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/fat/fat_ops.c
rd2093d6 r0fdd6bb 344 344 int fat_link(void *prnt, void *chld, const char *name) 345 345 { 346 return ENOTSUP; /* not supported at the moment */ 346 fat_node_t *parentp = (fat_node_t *)prnt; 347 fat_node_t *childp = (fat_node_t *)chld; 348 fat_dentry_t *d; 349 fat_bs_t *bs; 350 block_t *b; 351 int i, j; 352 uint16_t bps; 353 unsigned dps; 354 unsigned blocks; 355 356 futex_down(&childp->lock); 357 if (childp->lnkcnt == 1) { 358 /* 359 * On FAT, we don't support multiple hard links. 360 */ 361 futex_up(&childp->lock); 362 return EMLINK; 363 } 364 assert(childp->lnkcnt == 0); 365 futex_up(&childp->lock); 366 367 if (!fat_dentry_name_verify(name)) { 368 /* 369 * Attempt to create unsupported name. 370 */ 371 return ENOTSUP; 372 } 373 374 /* 375 * Get us an unused parent node's dentry or grow the parent and allocate 376 * a new one. 377 */ 378 379 futex_down(&parentp->idx->lock); 380 bs = block_bb_get(parentp->idx->dev_handle); 381 bps = uint16_t_le2host(bs->bps); 382 dps = bps / sizeof(fat_dentry_t); 383 384 blocks = parentp->size / bps; 385 386 for (i = 0; i < blocks; i++) { 387 b = fat_block_get(bs, parentp, i, BLOCK_FLAGS_NONE); 388 for (j = 0; j < dps; j++) { 389 d = ((fat_dentry_t *)b->data) + j; 390 switch (fat_classify_dentry(d)) { 391 case FAT_DENTRY_SKIP: 392 case FAT_DENTRY_VALID: 393 /* skipping used and meta entries */ 394 continue; 395 case FAT_DENTRY_FREE: 396 case FAT_DENTRY_LAST: 397 /* found an empty slot */ 398 goto hit; 399 } 400 } 401 block_put(b); 402 } 403 404 /* 405 * We need to grow the parent in order to create a new unused dentry. 406 */ 407 futex_up(&parentp->idx->lock); 408 return ENOTSUP; /* XXX */ 409 410 hit: 411 /* 412 * At this point we only establish the link between the parent and the 413 * child. The dentry, except of the name and the extension, will remain 414 * uninitialized until the the corresponding node is synced. Thus the 415 * valid dentry data is kept in the child node structure. 416 */ 417 memset(d, 0, sizeof(fat_dentry_t)); 418 fat_dentry_name_set(d, name); 419 b->dirty = true; /* need to sync block */ 420 block_put(b); 421 futex_up(&parentp->idx->lock); 422 423 futex_down(&childp->idx->lock); 424 childp->idx->pfc = parentp->firstc; 425 childp->idx->pdi = i * dps + j; 426 futex_up(&childp->idx->lock); 427 428 futex_down(&childp->lock); 429 childp->lnkcnt = 1; 430 childp->dirty = true; /* need to sync node */ 431 futex_up(&childp->lock); 432 433 /* 434 * Hash in the index structure into the position hash. 435 */ 436 fat_idx_hashin(childp->idx); 437 438 return EOK; 347 439 } 348 440 … … 375 467 switch (fat_classify_dentry(d)) { 376 468 case FAT_DENTRY_SKIP: 469 case FAT_DENTRY_FREE: 377 470 continue; 378 471 case FAT_DENTRY_LAST: … … 382 475 default: 383 476 case FAT_DENTRY_VALID: 384 dentry_name_canonify(d, name);477 fat_dentry_name_get(d, name); 385 478 break; 386 479 } … … 465 558 switch (fat_classify_dentry(d)) { 466 559 case FAT_DENTRY_SKIP: 560 case FAT_DENTRY_FREE: 467 561 continue; 468 562 case FAT_DENTRY_LAST: … … 699 793 switch (fat_classify_dentry(d)) { 700 794 case FAT_DENTRY_SKIP: 795 case FAT_DENTRY_FREE: 701 796 continue; 702 797 case FAT_DENTRY_LAST: … … 705 800 default: 706 801 case FAT_DENTRY_VALID: 707 dentry_name_canonify(d, name);802 fat_dentry_name_get(d, name); 708 803 block_put(b); 709 804 goto hit;
Note:
See TracChangeset
for help on using the changeset viewer.