Changeset d0d7afb in mainline
- Timestamp:
- 2012-03-01T19:56:31Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c30a015
- Parents:
- d8269dc
- Location:
- uspace/lib/ext4
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ext4/libext4_directory.c
rd8269dc rd0d7afb 314 314 315 315 int ext4_directory_add_entry(ext4_filesystem_t *fs, ext4_inode_ref_t * parent, 316 const char * entry_name, ext4_inode_ref_t *child)316 const char *name, ext4_inode_ref_t *child) 317 317 { 318 318 int rc; 319 319 320 EXT4FS_DBG("adding entry to directory \%u [ino = \%u, name = \%s]", parent->index, child->index, entry_name); 321 322 uint16_t name_len = strlen(entry_name); 320 EXT4FS_DBG("adding entry to directory \%u [ino = \%u, name = \%s]", parent->index, child->index, name); 323 321 324 322 // Index adding (if allowed) … … 326 324 ext4_inode_has_flag(parent->inode, EXT4_INODE_FLAG_INDEX)) { 327 325 328 rc = ext4_directory_dx_add_entry(fs, parent, child, name _len, entry_name);326 rc = ext4_directory_dx_add_entry(fs, parent, child, name); 329 327 330 328 // Check if index is not corrupted … … 347 345 // Linear algorithm 348 346 349 ext4_directory_iterator_t it; 350 rc = ext4_directory_iterator_init(&it, fs, parent, 0); 351 if (rc != EOK) { 352 return rc; 353 } 354 347 EXT4FS_DBG("Linear algorithm"); 348 349 uint32_t iblock, fblock; 355 350 uint32_t block_size = ext4_superblock_get_block_size(fs->superblock); 356 uint16_t required_len = 8 + name_len + (4 - name_len % 4); 357 358 while (it.current != NULL) { 359 uint32_t entry_inode = ext4_directory_entry_ll_get_inode(it.current); 360 uint16_t rec_len = ext4_directory_entry_ll_get_entry_length(it.current); 361 362 if ((entry_inode == 0) && (rec_len >= required_len)) { 363 364 ext4_directory_write_entry(fs->superblock, it.current, rec_len, 365 child, entry_name, name_len); 366 it.current_block->dirty = true; 367 return ext4_directory_iterator_fini(&it); 368 } 369 370 if (entry_inode != 0) { 371 uint16_t used_name_len = ext4_directory_entry_ll_get_name_length( 372 fs->superblock, it.current); 373 374 uint16_t used_space = 8 + used_name_len; 375 if ((used_name_len % 4) != 0) { 376 used_space += 4 - (used_name_len % 4); 377 } 378 uint16_t free_space = rec_len - used_space; 379 380 EXT4FS_DBG("rec_len = \%u, used_space = \%u, free space = \%u", rec_len, used_space, free_space); 381 382 if (free_space >= required_len) { 383 384 // Cut tail of current entry 385 ext4_directory_entry_ll_set_entry_length(it.current, used_space); 386 387 // SEEK manually 388 uint32_t local_offset = (it.current_offset % block_size); 389 local_offset += used_space; 390 ext4_directory_entry_ll_t *new_entry = it.current_block->data + local_offset; 391 392 // We are sure, that both entries are in the same data block 393 // dirtyness will be set now 394 395 ext4_directory_write_entry(fs->superblock, new_entry, 396 free_space, child, entry_name, name_len); 397 it.current_block->dirty = true; 398 return ext4_directory_iterator_fini(&it); 399 } 400 401 } 402 403 rc = ext4_directory_iterator_next(&it); 404 if (rc != EOK) { 405 return rc; 406 } 407 } 408 409 // Destroy iterator 410 ext4_directory_iterator_fini(&it); 351 uint32_t inode_size = ext4_inode_get_size(fs->superblock, parent->inode); 352 uint32_t total_blocks = inode_size / block_size; 353 354 uint32_t name_len = strlen(name); 355 356 bool success = false; 357 for (iblock = 0; iblock < total_blocks; ++iblock) { 358 359 rc = ext4_filesystem_get_inode_data_block_index(fs, parent->inode, iblock, &fblock); 360 if (rc != EOK) { 361 return rc; 362 } 363 364 block_t *block; 365 rc = block_get(&block, fs->device, fblock, BLOCK_FLAGS_NONE); 366 if (rc != EOK) { 367 return rc; 368 } 369 370 rc = ext4_directory_try_insert_entry(fs->superblock, block, child, name, name_len); 371 if (rc == EOK) { 372 success = true; 373 } 374 375 rc = block_put(block); 376 if (rc != EOK) { 377 return rc; 378 } 379 380 if (success) { 381 return EOK; 382 } 383 } 384 411 385 412 386 EXT4FS_DBG("NO FREE SPACE - needed to allocate block"); 413 387 414 uint32_t fblock;415 uint32_t iblock;416 388 rc = ext4_directory_append_block(fs, parent, &fblock, &iblock); 417 389 if (rc != EOK) { … … 428 400 // Fill block with zeroes 429 401 memset(new_block->data, 0, block_size); 430 431 402 ext4_directory_entry_ll_t *block_entry = new_block->data; 432 433 ext4_directory_write_entry(fs->superblock, block_entry, block_size, 434 child, entry_name, name_len); 403 ext4_directory_write_entry(fs->superblock, block_entry, block_size, child, name, name_len); 435 404 436 405 new_block->dirty = true; … … 556 525 } 557 526 527 int ext4_directory_try_insert_entry(ext4_superblock_t *sb, 528 block_t *target_block, ext4_inode_ref_t *child, 529 const char *name, uint32_t name_len) 530 { 531 uint32_t block_size = ext4_superblock_get_block_size(sb); 532 uint16_t required_len = sizeof(ext4_fake_directory_entry_t) + name_len; 533 if ((required_len % 4) != 0) { 534 required_len += 4 - (required_len % 4); 535 } 536 537 ext4_directory_entry_ll_t *dentry = target_block->data; 538 ext4_directory_entry_ll_t *stop = target_block->data + block_size; 539 540 while (dentry < stop) { 541 542 uint32_t inode = ext4_directory_entry_ll_get_inode(dentry); 543 uint16_t rec_len = ext4_directory_entry_ll_get_entry_length(dentry); 544 545 if ((inode == 0) && (rec_len >= required_len)) { 546 ext4_directory_write_entry(sb, dentry, rec_len, child, name, name_len); 547 target_block->dirty = true; 548 return EOK; 549 } 550 551 if (inode != 0) { 552 uint16_t used_name_len = 553 ext4_directory_entry_ll_get_name_length(sb, dentry); 554 555 uint16_t used_space = 556 sizeof(ext4_fake_directory_entry_t) + used_name_len; 557 if ((used_name_len % 4) != 0) { 558 used_space += 4 - (used_name_len % 4); 559 } 560 uint16_t free_space = rec_len - used_space; 561 562 if (free_space >= required_len) { 563 564 // Cut tail of current entry 565 ext4_directory_entry_ll_set_entry_length(dentry, used_space); 566 ext4_directory_entry_ll_t *new_entry = 567 (void *)dentry + used_space; 568 ext4_directory_write_entry(sb, new_entry, 569 free_space, child, name, name_len); 570 571 target_block->dirty = true; 572 return EOK; 573 } 574 } 575 576 dentry = (void *)dentry + rec_len; 577 } 578 579 return ENOSPC; 580 } 581 558 582 559 583 /** -
uspace/lib/ext4/libext4_directory.h
rd8269dc rd0d7afb 106 106 ext4_inode_ref_t *, const char *); 107 107 108 extern int ext4_directory_try_insert_entry(ext4_superblock_t *, 109 block_t *, ext4_inode_ref_t *, const char *, uint32_t); 108 110 #endif 109 111 -
uspace/lib/ext4/libext4_directory_index.c
rd8269dc rd0d7afb 503 503 block_t *old_data_block, ext4_directory_dx_block_t *index_block, block_t **new_data_block) 504 504 { 505 int rc ;505 int rc = EOK; 506 506 507 507 uint32_t block_size = ext4_superblock_get_block_size(fs->superblock); … … 652 652 653 653 int ext4_directory_dx_add_entry(ext4_filesystem_t *fs, 654 ext4_inode_ref_t *parent, ext4_inode_ref_t *child, 655 size_t name_size, const char *name) 656 { 657 int rc ;654 ext4_inode_ref_t *parent, ext4_inode_ref_t *child, const char *name) 655 { 656 int rc = EOK; 657 int rc2; 658 658 659 659 // get direct block 0 (index root) … … 670 670 } 671 671 672 uint32_t name_len = strlen(name); 672 673 ext4_hash_info_t hinfo; 673 rc = ext4_directory_hinfo_init(&hinfo, root_block, fs->superblock, name_ size, name);674 rc = ext4_directory_hinfo_init(&hinfo, root_block, fs->superblock, name_len, name); 674 675 if (rc != EOK) { 675 676 block_put(root_block); … … 702 703 } 703 704 704 uint32_t block_size = ext4_superblock_get_block_size(fs->superblock); 705 uint16_t required_len = 8 + name_size + (4 - name_size % 4); 706 707 ext4_directory_entry_ll_t *de = target_block->data; 708 ext4_directory_entry_ll_t *stop = target_block->data + block_size; 709 710 while (de < stop) { 711 712 uint32_t de_inode = ext4_directory_entry_ll_get_inode(de); 713 uint16_t de_rec_len = ext4_directory_entry_ll_get_entry_length(de); 714 715 if ((de_inode == 0) && (de_rec_len >= required_len)) { 716 ext4_directory_write_entry(fs->superblock, de, de_rec_len, 717 child, name, name_size); 718 719 // TODO cleanup 720 target_block->dirty = true; 721 rc = block_put(target_block); 722 if (rc != EOK) { 723 return EXT4_ERR_BAD_DX_DIR; 724 } 725 return EOK; 726 } 727 728 if (de_inode != 0) { 729 uint16_t used_name_len = ext4_directory_entry_ll_get_name_length( 730 fs->superblock, de); 731 732 uint16_t used_space = 8 + used_name_len; 733 if ((used_name_len % 4) != 0) { 734 used_space += 4 - (used_name_len % 4); 735 } 736 uint16_t free_space = de_rec_len - used_space; 737 738 if (free_space >= required_len) { 739 740 // Cut tail of current entry 741 ext4_directory_entry_ll_set_entry_length(de, used_space); 742 ext4_directory_entry_ll_t *new_entry = (void *)de + used_space; 743 ext4_directory_write_entry(fs->superblock, new_entry, 744 free_space, child, name, name_size); 745 746 // TODO cleanup 747 target_block->dirty = true; 748 rc = block_put(target_block); 749 if (rc != EOK) { 750 return EXT4_ERR_BAD_DX_DIR; 751 } 752 return EOK; 753 754 } 755 756 } 757 758 de = (void *)de + de_rec_len; 705 rc = ext4_directory_try_insert_entry(fs->superblock, target_block, child, name, name_len); 706 if (rc == EOK) { 707 goto cleanup; 708 759 709 } 760 710 761 711 EXT4FS_DBG("no free space found"); 712 713 uint32_t block_size = ext4_superblock_get_block_size(fs->superblock); 762 714 763 715 ext4_directory_dx_entry_t *entries = ((ext4_directory_dx_node_t *) dx_block->block->data)->entries; … … 786 738 rc = ext4_directory_append_block(fs, parent, &new_fblock, &new_iblock); 787 739 if (rc != EOK) { 788 // TODO error740 goto cleanup; 789 741 } 790 742 … … 793 745 rc = block_get(&new_block, fs->device, new_fblock, BLOCK_FLAGS_NOREAD); 794 746 if (rc != EOK) { 795 // TODO error747 goto cleanup; 796 748 } 797 749 … … 873 825 } 874 826 875 // TODOWhere to save new entry827 // Where to save new entry 876 828 uint32_t new_block_hash = ext4_directory_dx_entry_get_hash(dx_block->position + 1); 877 829 if (hinfo.hash >= new_block_hash) { 878 de = new_block->data; 879 stop = new_block->data + block_size; 830 rc = ext4_directory_try_insert_entry(fs->superblock, new_block, child, name, name_len); 880 831 } else { 881 de = target_block->data; 882 stop = target_block->data + block_size; 883 } 884 885 while (de < stop) { 886 887 uint32_t de_inode = ext4_directory_entry_ll_get_inode(de); 888 uint16_t de_rec_len = ext4_directory_entry_ll_get_entry_length(de); 889 890 if ((de_inode == 0) && (de_rec_len >= required_len)) { 891 ext4_directory_write_entry(fs->superblock, de, de_rec_len, 892 child, name, name_size); 893 goto success; 894 } 895 896 if (de_inode != 0) { 897 uint16_t used_name_len = ext4_directory_entry_ll_get_name_length( 898 fs->superblock, de); 899 900 uint16_t used_space = 8 + used_name_len; 901 if ((used_name_len % 4) != 0) { 902 used_space += 4 - (used_name_len % 4); 903 } 904 uint16_t free_space = de_rec_len - used_space; 905 906 if (free_space >= required_len) { 907 908 // Cut tail of current entry 909 ext4_directory_entry_ll_set_entry_length(de, used_space); 910 ext4_directory_entry_ll_t *new_entry = (void *)de + used_space; 911 ext4_directory_write_entry(fs->superblock, new_entry, 912 free_space, child, name, name_size); 913 914 goto success; 915 } 916 917 } 918 919 de = (void *)de + de_rec_len; 920 } 921 922 success: 832 rc = ext4_directory_try_insert_entry(fs->superblock, target_block, child, name, name_len); 833 } 834 835 if (rc != EOK) { 836 goto terminate; 837 } 838 839 840 terminate: 841 rc = block_put(new_block); 842 if (rc != EOK) { 843 EXT4FS_DBG("error writing new block"); 844 } 845 846 847 cleanup: 848 849 rc2 = rc; 923 850 924 851 rc = block_put(target_block); 925 852 if (rc != EOK) { 926 EXT4FS_DBG("error writing target block"); 927 } 928 rc = block_put(new_block); 929 if (rc != EOK) { 930 EXT4FS_DBG("error writing new block"); 853 return rc; 931 854 } 932 855 … … 936 859 rc = block_put(dx_it->block); 937 860 if (rc != EOK) { 938 EXT4FS_DBG("error writing index block \%u", (uint32_t)dx_it->block->pba);861 return rc; 939 862 } 940 863 dx_it++; 941 864 } 942 865 943 return EOK;866 return rc2; 944 867 } 945 868 -
uspace/lib/ext4/libext4_directory_index.h
rd8269dc rd0d7afb 126 126 ext4_filesystem_t *, ext4_inode_ref_t *, size_t, const char *); 127 127 extern int ext4_directory_dx_add_entry(ext4_filesystem_t *, 128 ext4_inode_ref_t *, ext4_inode_ref_t *, size_t,const char *);128 ext4_inode_ref_t *, ext4_inode_ref_t *, const char *); 129 129 130 130 #endif
Note:
See TracChangeset
for help on using the changeset viewer.