Changeset 06d85e5 in mainline for uspace/lib/ext4/libext4_directory.c
- Timestamp:
- 2012-06-18T11:09:34Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2616a75b
- Parents:
- 9a487cc
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ext4/libext4_directory.c
r9a487cc r06d85e5 159 159 } 160 160 161 / / else do nothing161 /* else do nothing */ 162 162 163 163 } … … 237 237 } 238 238 239 / / Compute next block address239 /* Compute next block address */ 240 240 uint32_t block_size = ext4_superblock_get_block_size( 241 241 it->inode_ref->fs->superblock); … … 313 313 } 314 314 315 / / Everything OK - "publish" the entry315 /* Everything OK - "publish" the entry */ 316 316 it->current = entry; 317 317 return EOK; … … 357 357 { 358 358 359 / / Check maximum entry length359 /* Check maximum entry length */ 360 360 uint32_t block_size = ext4_superblock_get_block_size(sb); 361 361 assert(entry_len <= block_size); 362 362 363 / / Set basic attributes363 /* Set basic attributes */ 364 364 ext4_directory_entry_ll_set_inode(entry, child->index); 365 365 ext4_directory_entry_ll_set_entry_length(entry, entry_len); 366 366 ext4_directory_entry_ll_set_name_length(sb, entry, name_len); 367 367 368 / / Write name368 /* Write name */ 369 369 memcpy(entry->name, name, name_len); 370 370 371 / / Set type of entry371 /* Set type of entry */ 372 372 if (ext4_inode_is_type(sb, child->inode, EXT4_INODE_MODE_DIRECTORY)) { 373 373 ext4_directory_entry_ll_set_inode_type( … … 394 394 ext4_filesystem_t *fs = parent->fs; 395 395 396 / / Index adding (if allowed)396 /* Index adding (if allowed) */ 397 397 if (ext4_superblock_has_feature_compatible(fs->superblock, EXT4_FEATURE_COMPAT_DIR_INDEX) && 398 398 ext4_inode_has_flag(parent->inode, EXT4_INODE_FLAG_INDEX)) { … … 400 400 rc = ext4_directory_dx_add_entry(parent, child, name); 401 401 402 / / Check if index is not corrupted402 /* Check if index is not corrupted */ 403 403 if (rc != EXT4_ERR_BAD_DX_DIR) { 404 404 … … 410 410 } 411 411 412 / / Needed to clear dir index flag if corrupted412 /* Needed to clear dir index flag if corrupted */ 413 413 ext4_inode_clear_flag(parent->inode, EXT4_INODE_FLAG_INDEX); 414 414 parent->dirty = true; … … 417 417 } 418 418 419 / / Linear algorithm419 /* Linear algorithm */ 420 420 421 421 uint32_t iblock = 0, fblock = 0; … … 426 426 uint32_t name_len = strlen(name); 427 427 428 / / Find block, where is space for new entry and try to add428 /* Find block, where is space for new entry and try to add */ 429 429 bool success = false; 430 430 for (iblock = 0; iblock < total_blocks; ++iblock) { … … 441 441 } 442 442 443 / / If adding is successful, function can finish443 /* If adding is successful, function can finish */ 444 444 rc = ext4_directory_try_insert_entry(fs->superblock, block, child, name, name_len); 445 445 if (rc == EOK) { … … 457 457 } 458 458 459 / / No free block found - needed to allocate next data block459 /* No free block found - needed to allocate next data block */ 460 460 461 461 iblock = 0; … … 466 466 } 467 467 468 / / Load new block468 /* Load new block */ 469 469 block_t *new_block; 470 470 rc = block_get(&new_block, fs->device, fblock, BLOCK_FLAGS_NOREAD); … … 473 473 } 474 474 475 / / Fill block with zeroes475 /* Fill block with zeroes */ 476 476 memset(new_block->data, 0, block_size); 477 477 ext4_directory_entry_ll_t *block_entry = new_block->data; 478 478 ext4_directory_write_entry(fs->superblock, block_entry, block_size, child, name, name_len); 479 479 480 / / Save new block480 /* Save new block */ 481 481 new_block->dirty = true; 482 482 rc = block_put(new_block); … … 503 503 ext4_superblock_t *sb = parent->fs->superblock; 504 504 505 / / Index search505 /* Index search */ 506 506 if (ext4_superblock_has_feature_compatible(sb, EXT4_FEATURE_COMPAT_DIR_INDEX) && 507 507 ext4_inode_has_flag(parent->inode, EXT4_INODE_FLAG_INDEX)) { … … 509 509 rc = ext4_directory_dx_find_entry(result, parent, name_len, name); 510 510 511 / / Check if index is not corrupted511 /* Check if index is not corrupted */ 512 512 if (rc != EXT4_ERR_BAD_DX_DIR) { 513 513 … … 518 518 } 519 519 520 / / Needed to clear dir index flag if corrupted520 /* Needed to clear dir index flag if corrupted */ 521 521 ext4_inode_clear_flag(parent->inode, EXT4_INODE_FLAG_INDEX); 522 522 parent->dirty = true; … … 525 525 } 526 526 527 / / Linear algorithm527 /* Linear algorithm */ 528 528 529 529 uint32_t iblock, fblock; … … 532 532 uint32_t total_blocks = inode_size / block_size; 533 533 534 / / Walk through all data blocks534 /* Walk through all data blocks */ 535 535 for (iblock = 0; iblock < total_blocks; ++iblock) { 536 536 537 / / Load block address537 /* Load block address */ 538 538 rc = ext4_filesystem_get_inode_data_block_index(parent, iblock, &fblock); 539 539 if (rc != EOK) { … … 541 541 } 542 542 543 / / Load data block543 /* Load data block */ 544 544 block_t *block; 545 545 rc = block_get(&block, parent->fs->device, fblock, BLOCK_FLAGS_NONE); … … 548 548 } 549 549 550 / / Try to find entry in block550 /* Try to find entry in block */ 551 551 ext4_directory_entry_ll_t *res_entry; 552 552 rc = ext4_directory_find_in_block(block, sb, name_len, name, &res_entry); … … 557 557 } 558 558 559 / / Entry not found - put block and continue to the next block559 /* Entry not found - put block and continue to the next block */ 560 560 561 561 rc = block_put(block); … … 565 565 } 566 566 567 / / Entry was not found567 /* Entry was not found */ 568 568 569 569 result->block = NULL; … … 584 584 int rc; 585 585 586 / / Check if removing from directory586 /* Check if removing from directory */ 587 587 if (!ext4_inode_is_type(parent->fs->superblock, parent->inode, 588 588 EXT4_INODE_MODE_DIRECTORY)) { … … 590 590 } 591 591 592 / / Try to find entry592 /* Try to find entry */ 593 593 ext4_directory_search_result_t result; 594 594 rc = ext4_directory_find_entry(&result, parent, name); … … 597 597 } 598 598 599 / / Invalidate entry599 /* Invalidate entry */ 600 600 ext4_directory_entry_ll_set_inode(result.dentry, 0); 601 601 602 / / Store entry position in block602 /* Store entry position in block */ 603 603 uint32_t pos = (void *)result.dentry - result.block->data; 604 604 605 // If entry is not the first in block, it must be merged 606 // with previous entry 605 /* If entry is not the first in block, it must be merged 606 * with previous entry 607 */ 607 608 if (pos != 0) { 608 609 609 610 uint32_t offset = 0; 610 611 611 / / Start from the first entry in block612 /* Start from the first entry in block */ 612 613 ext4_directory_entry_ll_t *tmp_dentry = result.block->data; 613 614 uint16_t tmp_dentry_length = 614 615 ext4_directory_entry_ll_get_entry_length(tmp_dentry); 615 616 616 / / Find direct predecessor of removed entry617 /* Find direct predecessor of removed entry */ 617 618 while ((offset + tmp_dentry_length) < pos) { 618 619 offset += ext4_directory_entry_ll_get_entry_length(tmp_dentry); … … 624 625 assert(tmp_dentry_length + offset == pos); 625 626 626 / / Add to removed entry length to predecessor's length627 /* Add to removed entry length to predecessor's length */ 627 628 uint16_t del_entry_length = 628 629 ext4_directory_entry_ll_get_entry_length(result.dentry); … … 650 651 const char *name, uint32_t name_len) 651 652 { 652 / / Compute required length entry and align it to 4 bytes653 /* Compute required length entry and align it to 4 bytes */ 653 654 uint32_t block_size = ext4_superblock_get_block_size(sb); 654 655 uint16_t required_len = sizeof(ext4_fake_directory_entry_t) + name_len; … … 657 658 } 658 659 659 / / Initialize pointers, stop means to upper bound660 /* Initialize pointers, stop means to upper bound */ 660 661 ext4_directory_entry_ll_t *dentry = target_block->data; 661 662 ext4_directory_entry_ll_t *stop = target_block->data + block_size; 662 663 663 // Walk through the block and check for invalid entries 664 // or entries with free space for new entry 664 /* Walk through the block and check for invalid entries 665 * or entries with free space for new entry 666 */ 665 667 while (dentry < stop) { 666 668 … … 668 670 uint16_t rec_len = ext4_directory_entry_ll_get_entry_length(dentry); 669 671 670 / / If invalid and large enough entry, use it672 /* If invalid and large enough entry, use it */ 671 673 if ((inode == 0) && (rec_len >= required_len)) { 672 674 ext4_directory_write_entry(sb, dentry, rec_len, child, name, name_len); … … 675 677 } 676 678 677 / / Valid entry, try to split it679 /* Valid entry, try to split it */ 678 680 if (inode != 0) { 679 681 uint16_t used_name_len = … … 687 689 uint16_t free_space = rec_len - used_space; 688 690 689 / / There is free space for new entry691 /* There is free space for new entry */ 690 692 if (free_space >= required_len) { 691 693 692 / / Cut tail of current entry694 /* Cut tail of current entry */ 693 695 ext4_directory_entry_ll_set_entry_length(dentry, used_space); 694 696 ext4_directory_entry_ll_t *new_entry = … … 702 704 } 703 705 704 / / Jump to the next entry706 /* Jump to the next entry */ 705 707 dentry = (void *)dentry + rec_len; 706 708 } 707 709 708 / / No free space found for new entry710 /* No free space found for new entry */ 709 711 710 712 return ENOSPC; … … 724 726 ext4_directory_entry_ll_t **res_entry) 725 727 { 726 / / Start from the first entry in block728 /* Start from the first entry in block */ 727 729 ext4_directory_entry_ll_t *dentry = (ext4_directory_entry_ll_t *)block->data; 728 / /Set upper bound for cycling730 /*Set upper bound for cycling */ 729 731 uint8_t *addr_limit = block->data + ext4_superblock_get_block_size(sb); 730 732 731 / / Walk through the block and check entries733 /* Walk through the block and check entries */ 732 734 while ((uint8_t *)dentry < addr_limit) { 733 735 734 / / Termination condition736 /* Termination condition */ 735 737 if ((uint8_t*) dentry + name_len > addr_limit) { 736 738 break; 737 739 } 738 740 739 / / Valid entry - check it741 /* Valid entry - check it */ 740 742 if (dentry->inode != 0) { 741 743 742 / / For more effectivity compare firstly only lengths744 /* For more effectivity compare firstly only lengths */ 743 745 if (name_len == ext4_directory_entry_ll_get_name_length(sb, dentry)) { 744 / / Compare names746 /* Compare names */ 745 747 if (bcmp((uint8_t *)name, dentry->name, name_len) == 0) { 746 748 *res_entry = dentry; … … 752 754 uint16_t dentry_len = ext4_directory_entry_ll_get_entry_length(dentry); 753 755 754 / / Corrupted entry756 /* Corrupted entry */ 755 757 if (dentry_len == 0) { 756 758 return EINVAL; 757 759 } 758 760 759 / / Jump to next entry761 /* Jump to next entry */ 760 762 dentry = (ext4_directory_entry_ll_t *)((uint8_t *)dentry + dentry_len); 761 763 } 762 764 763 / / Entry not found765 /* Entry not found */ 764 766 return ENOENT; 765 767 }
Note:
See TracChangeset
for help on using the changeset viewer.