Changeset 5d3d75a5 in mainline
- Timestamp:
- 2012-07-08T21:50:26Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 9aa82e6
- Parents:
- cc51c27
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ext4/libext4_extent.c
rcc51c27 r5d3d75a5 739 739 */ 740 740 static int ext4_extent_append_extent(ext4_inode_ref_t *inode_ref, 741 ext4_extent_path_t *path, ext4_extent_path_t **last_path_item, 742 uint32_t iblock) 741 ext4_extent_path_t *path, uint32_t iblock) 743 742 { 744 743 745 744 int rc; 746 745 747 ext4_extent_path_t *path_ptr = *last_path_item;746 ext4_extent_path_t *path_ptr = path + path->depth; 748 747 749 748 uint16_t entries = ext4_extent_header_get_entries_count(path_ptr->header); 750 749 uint16_t limit = ext4_extent_header_get_max_entries_count(path_ptr->header); 751 750 752 /* Trivial way - no splitting */753 // if ((entries < limit) && (path == path_ptr)) {754 //755 // ext4_extent_header_set_entries_count(path_ptr->header, entries + 1);756 // path_ptr->extent = EXT4_EXTENT_FIRST(path_ptr->header) + entries;757 // path_ptr->block->dirty = true;758 //759 // return EOK;760 // }761 762 751 uint32_t block_size = 763 752 ext4_superblock_get_block_size(inode_ref->fs->superblock); 764 753 765 // /* Trivial tree - grow (extents were in root node) */766 // if ((path_ptr == path) && ((entries == limit))){767 //768 // EXT4FS_DBG("splitting root with extents");769 //770 // uint32_t new_fblock;771 // rc = ext4_balloc_alloc_block(inode_ref, &new_fblock);772 // if (rc != EOK) {773 // EXT4FS_DBG("error in block allocation");774 // return rc;775 // }776 //777 //// EXT4FS_DBG("alllocated block \%u for new leaf", new_fblock);778 //779 // block_t *block;780 // rc = block_get(&block, inode_ref->fs->device,781 // new_fblock, BLOCK_FLAGS_NOREAD);782 // if (rc != EOK) {783 // EXT4FS_DBG("error in block_get");784 // return rc;785 // }786 //787 // memset(block->data, 0, block_size);788 //789 // /* Move data from root to the new block */790 // memcpy(block->data, inode_ref->inode->blocks,791 // EXT4_INODE_BLOCKS * sizeof(uint32_t));792 //793 // path_ptr++;794 // path_ptr->block = block;795 // path_ptr->header = (ext4_extent_header_t *)block->data;796 // path_ptr->depth = 0;797 // path_ptr->index = NULL;798 //799 // uint16_t entries = ext4_extent_header_get_entries_count(path_ptr->header);800 // path_ptr->extent = EXT4_EXTENT_FIRST(path_ptr->header) + entries;801 // ext4_extent_header_set_entries_count(path_ptr->header, entries + 1);802 // uint16_t limit = (block_size - sizeof(ext4_extent_header_t)) /803 // sizeof(ext4_extent_t);804 // ext4_extent_header_set_max_entries_count(path_ptr->header, limit);805 //806 // /* Modify root (in inode) */807 // path->depth = 1;808 // path->extent = NULL;809 // path->index = EXT4_EXTENT_FIRST_INDEX(path->header);810 //811 // ext4_extent_header_set_depth(path->header, 1);812 // ext4_extent_header_set_entries_count(path->header, 1);813 //814 // ext4_extent_index_set_first_block(path->index, 0);815 // ext4_extent_index_set_leaf(path->index, new_fblock);816 //817 // path_ptr->block->dirty = true;818 // path->block->dirty = true;819 //820 // *last_path_item = path_ptr;821 //822 //// ext4_extent_header_t *tmp_root = path->header;823 //// EXT4FS_DBG("new root: items = \%u, maximum = \%u, depth = \%u", ext4_extent_header_get_entries_count(tmp_root),824 //// ext4_extent_header_get_max_entries_count(tmp_root), ext4_extent_header_get_depth(tmp_root));825 ////826 //// ext4_extent_index_t *root_idx = EXT4_EXTENT_FIRST_INDEX(path->header);827 //// EXT4FS_DBG("first iblock = \%u, fblock = \%u", ext4_extent_index_get_first_block(root_idx),828 //// (uint32_t)ext4_extent_index_get_leaf(root_idx));829 ////830 //// ext4_extent_header_t *new_leaf = path_ptr->header;831 //// EXT4FS_DBG("new leaf: items = \%u, maximum = \%u, depth = \%u", ext4_extent_header_get_entries_count(new_leaf),832 //// ext4_extent_header_get_max_entries_count(new_leaf), ext4_extent_header_get_depth(new_leaf));833 ////834 //// for (uint32_t j = 0; j < ext4_extent_header_get_entries_count(new_leaf); ++j) {835 //// ext4_extent_t *tmp_ext = EXT4_EXTENT_FIRST(path_ptr->header) + j;836 ////837 //// EXT4FS_DBG("item \%u, first iblock = \%u", j, ext4_extent_get_first_block(tmp_ext));838 //// }839 //840 // EXT4FS_DBG("Root block containing extents was split");841 // return EOK;842 // }843 844 // TODO !!!845 // assert(false);846 847 // EXT4FS_DBG("More complex splitting");848 849 754 /* Start splitting */ 850 755 while (path_ptr > path) { 851 uint32_t fblock;852 756 853 757 entries = ext4_extent_header_get_entries_count(path_ptr->header); … … 858 762 EXT4FS_DBG("Full non-root node (\%s)", path_ptr->depth ? "index" : "extent"); 859 763 860 /* Full node */ 764 /* Full node - allocate block for new one */ 765 uint32_t fblock; 861 766 rc = ext4_balloc_alloc_block(inode_ref, &fblock); 862 767 if (rc != EOK) { … … 871 776 } 872 777 873 /* Init block */ 778 /* Put back not modified old block */ 779 block_put(path_ptr->block); 780 781 /* Initialize newly allocated block and remember it */ 874 782 memset(block->data, 0, block_size); 875 876 /* Not modified old block */877 block_put(path_ptr->block);878 783 path_ptr->block = block; 784 785 /* Update pointers in extent path structure */ 879 786 path_ptr->header = block->data; 880 881 787 if (path_ptr->depth) { 882 788 path_ptr->index = EXT4_EXTENT_FIRST_INDEX(path_ptr->header); … … 897 803 path_ptr->block->dirty = true; 898 804 805 /* Jump to the preceeding item */ 899 806 path_ptr--; 900 807 … … 915 822 ext4_extent_header_set_entries_count(path_ptr->header, entries + 1); 916 823 path_ptr->block->dirty = true; 917 *last_path_item = path_ptr; 918 824 825 /* No more splitting needed */ 919 826 return EOK; 920 827 } 921 828 922 829 } 830 831 assert(path_ptr == path); 832 // TODO condition is redundant here 923 833 924 834 /* Should be the root split too? */ … … 947 857 } 948 858 859 /* Initialize newly allocated block */ 949 860 memset(block->data, 0, block_size); 950 861 … … 953 864 EXT4_INODE_BLOCKS * sizeof(uint32_t)); 954 865 955 EXT4FS_DBG("New block prepared"); 866 ext4_extent_header_t *dbg_header = block->data; 867 EXT4FS_DBG("old root: items = \%u, depth = \%u", ext4_extent_header_get_entries_count(dbg_header), ext4_extent_header_get_depth(dbg_header)); 868 869 if (ext4_extent_header_get_depth(dbg_header)) { 870 for (uint16_t x = 0; x < ext4_extent_header_get_entries_count(dbg_header); ++x) { 871 ext4_extent_index_t *iii = EXT4_EXTENT_FIRST_INDEX(dbg_header) + x; 872 EXT4FS_DBG("root item \%u, iblock = \%u, leaf = \%u", x, ext4_extent_index_get_first_block(iii), (uint32_t)ext4_extent_index_get_leaf(iii)); 873 } 874 } else { 875 for (uint16_t x = 0; x < ext4_extent_header_get_entries_count(dbg_header); ++x) { 876 ext4_extent_t *iii = EXT4_EXTENT_FIRST(dbg_header) + x; 877 EXT4FS_DBG("root item \%u, iblock = \%u, leaf = \%u, count = \%u", x, ext4_extent_get_first_block(iii), (uint32_t)ext4_extent_get_start(iii), ext4_extent_get_block_count(iii)); 878 } 879 } 956 880 957 881 /* Make space for tree growing */ 958 memmove(path + 1, path, path->depth + 1);959 960 EXT4FS_DBG("Place for new root ready");961 962 882 path_ptr = path + 1; 883 size_t bytes = (path->depth + 1) * sizeof(ext4_extent_path_t); 884 memmove(path_ptr, path, bytes); 885 886 /* Initialize new root metadata */ 887 path->block = path_ptr->block; 888 path->header = path_ptr->header; 889 path->depth = path_ptr->depth + 1; 890 path->extent = NULL; 891 path->index = EXT4_EXTENT_FIRST_INDEX(path->header); 892 893 ext4_extent_header_set_entries_count(path->header, 1); 894 ext4_extent_header_set_depth(path->header, path->depth); 895 ext4_extent_index_set_first_block(path->index, 0); 896 ext4_extent_index_set_leaf(path->index, new_fblock); 897 898 path->block->dirty = true; 899 900 901 /* Switch storage for "old root" */ 963 902 path_ptr->block = block; 964 903 path_ptr->header = (ext4_extent_header_t *)block->data; 965 904 905 /* Add new entry to the "old root" */ 966 906 if (path_ptr->depth) { 967 907 limit = (block_size - sizeof(ext4_extent_header_t)) / … … 978 918 path_ptr->index = NULL; 979 919 } 980 981 920 ext4_extent_header_set_entries_count(path_ptr->header, entries + 1); 982 921 ext4_extent_header_set_max_entries_count(path_ptr->header, limit); … … 984 923 path_ptr->block->dirty = true; 985 924 986 path->block = inode_ref->block; 987 path->depth = path_ptr->depth + 1; 988 path->header = (ext4_extent_header_t *)inode_ref->inode->blocks; 989 path->extent = NULL; 990 path->index = EXT4_EXTENT_FIRST_INDEX(path->header); 991 992 993 ext4_extent_header_set_entries_count(path->header, 1); 994 ext4_extent_header_set_depth(path->header, path->depth); 995 996 ext4_extent_index_set_first_block(path->index, 0); 997 ext4_extent_index_set_leaf(path->index, new_fblock); 998 999 path->block->dirty = true; 1000 1001 *last_path_item = *last_path_item + 1; 1002 1003 EXT4FS_DBG("Leaving split root"); 925 926 EXT4FS_DBG("new root: items = \%u, depth = \%u, tmp depth = \%u", ext4_extent_header_get_entries_count(path->header), ext4_extent_header_get_depth(path->header), path->depth); 927 928 for (uint16_t x = 0; x < ext4_extent_header_get_entries_count(path->header); ++x) { 929 ext4_extent_index_t *iii = EXT4_EXTENT_FIRST_INDEX(path->header) + x; 930 EXT4FS_DBG("root item \%u, iblock = \%u, leaf = \%u", x, ext4_extent_index_get_first_block(iii), (uint32_t)ext4_extent_index_get_leaf(iii)); 931 } 1004 932 1005 933 } else { … … 1007 935 EXT4FS_DBG("Adding entry to root node"); 1008 936 1009 if (path _ptr->depth) {1010 path _ptr->index = EXT4_EXTENT_FIRST_INDEX(path_ptr->header) + entries;1011 ext4_extent_index_set_first_block(path _ptr->index, iblock);1012 ext4_extent_index_set_leaf(path _ptr->index, (path_ptr+ 1)->block->lba);937 if (path->depth) { 938 path->index = EXT4_EXTENT_FIRST_INDEX(path->header) + entries; 939 ext4_extent_index_set_first_block(path->index, iblock); 940 ext4_extent_index_set_leaf(path->index, (path + 1)->block->lba); 1013 941 } else { 1014 path _ptr->extent = EXT4_EXTENT_FIRST(path_ptr->header) + entries;1015 ext4_extent_set_first_block(path _ptr->extent, iblock);1016 } 1017 1018 ext4_extent_header_set_entries_count(path _ptr->header, entries + 1);942 path->extent = EXT4_EXTENT_FIRST(path->header) + entries; 943 ext4_extent_set_first_block(path->extent, iblock); 944 } 945 946 ext4_extent_header_set_entries_count(path->header, entries + 1); 1019 947 path->block->dirty = true; 1020 948 } … … 1030 958 * to some existing extent or creates new extents. 1031 959 * It includes possible extent tree modifications (splitting). 1032 * 960 *< 1033 961 * @param inode_ref i-node to append block to 1034 962 * @param iblock output logical number of newly allocated block … … 1151 1079 1152 1080 /* Append extent for new block (includes tree splitting if needed) */ 1153 rc = ext4_extent_append_extent(inode_ref, path, &path_ptr,new_block_idx);1081 rc = ext4_extent_append_extent(inode_ref, path, new_block_idx); 1154 1082 if (rc != EOK) { 1155 1083 ext4_balloc_free_block(inode_ref, phys_block); 1156 1084 goto finish; 1157 1085 } 1086 1087 uint32_t tree_depth = ext4_extent_header_get_depth(path->header); 1088 path_ptr = path + tree_depth; 1089 1090 assert(tree_depth == path->depth); 1158 1091 1159 1092 /* Initialize newly created extent */
Note:
See TracChangeset
for help on using the changeset viewer.