Changeset ee3b6150 in mainline for uspace/lib/ext4/libext4_ialloc.c
- Timestamp:
- 2012-04-23T16:01:14Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- bc03679
- Parents:
- 6773ff3
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ext4/libext4_ialloc.c
r6773ff3 ree3b6150 40 40 #include "libext4.h" 41 41 42 43 /** Convert i-node number to relative index in block group. 44 * 45 * @param sb superblock 46 * @param inode i-node number to be converted 47 * @return index of the i-node in the block group 48 */ 42 49 static uint32_t ext4_ialloc_inode2index_in_group(ext4_superblock_t *sb, 43 50 uint32_t inode) … … 47 54 } 48 55 56 /** Convert relative index of i-node to absolute i-node number. 57 * 58 * @param sb superblock 59 * @param inode index to be converted 60 * @return absolute number of the i-node 61 */ 49 62 static uint32_t ext4_ialloc_index_in_group2inode(ext4_superblock_t *sb, 50 63 uint32_t index, uint32_t bgid) … … 54 67 } 55 68 69 /** Compute block group number from the i-node number. 70 * 71 * @param sb superblock 72 * @param inode i-node number to be found the block group for 73 * @return block group number computed from i-node number 74 */ 56 75 static uint32_t ext4_ialloc_get_bgid_of_inode(ext4_superblock_t *sb, 57 76 uint32_t inode) … … 63 82 64 83 84 /** Free i-node number and modify filesystem data structers. 85 * 86 * @param fs filesystem, where the i-node is located 87 * @param index index of i-node to be release 88 * @param is_dir flag us for information whether i-node is directory or not 89 */ 65 90 int ext4_ialloc_free_inode(ext4_filesystem_t *fs, uint32_t index, bool is_dir) 66 91 { … … 69 94 ext4_superblock_t *sb = fs->superblock; 70 95 96 // Compute index of block group and load it 71 97 uint32_t block_group = ext4_ialloc_get_bgid_of_inode(sb, index); 72 98 … … 77 103 } 78 104 105 // Load i-node bitmap 79 106 uint32_t bitmap_block_addr = ext4_block_group_get_inode_bitmap( 80 107 bg_ref->block_group, sb); … … 85 112 } 86 113 114 // Free i-node in the bitmap 87 115 uint32_t index_in_group = ext4_ialloc_inode2index_in_group(sb, index); 88 116 ext4_bitmap_free_bit(bitmap_block->data, index_in_group); 89 117 bitmap_block->dirty = true; 90 118 119 // Put back the block with bitmap 91 120 rc = block_put(bitmap_block); 92 121 if (rc != EOK) { … … 96 125 } 97 126 98 // if inode isdirectory, decrement used directories count127 // If released i-node is a directory, decrement used directories count 99 128 if (is_dir) { 100 129 uint32_t bg_used_dirs = ext4_block_group_get_used_dirs_count( … … 112 141 sb, free_inodes); 113 142 143 // Set unused i-nodes count if supported 114 144 if (ext4_block_group_has_flag(bg_ref->block_group, EXT4_BLOCK_GROUP_INODE_UNINIT)) { 115 145 uint32_t unused_inodes = ext4_block_group_get_itable_unused( … … 121 151 bg_ref->dirty = true; 122 152 153 // Put back the modified block group 123 154 rc = ext4_filesystem_put_block_group_ref(bg_ref); 124 155 if (rc != EOK) { … … 134 165 } 135 166 167 /** I-node allocation algorithm. 168 * 169 * This is more simple algorithm, than Orlov allocator used in the Linux kernel 170 * 171 * @param fs filesystem to allocate i-node on 172 * @param index output value - allocated i-node number 173 * @param is_dir flag if allocated i-node will be file or directory 174 * @return error code 175 */ 136 176 int ext4_ialloc_alloc_inode(ext4_filesystem_t *fs, uint32_t *index, bool is_dir) 137 177 { … … 145 185 uint32_t avg_free_inodes = sb_free_inodes / bg_count; 146 186 187 // Try to find free i-node in all block groups 147 188 while (bgid < bg_count) { 148 189 190 // Load block group to check 149 191 ext4_block_group_ref_t *bg_ref; 150 192 rc = ext4_filesystem_get_block_group_ref(fs, bgid, &bg_ref); … … 152 194 return rc; 153 195 } 196 154 197 ext4_block_group_t *bg = bg_ref->block_group; 155 198 199 // Read necessary values for algorithm 156 200 uint32_t free_blocks = ext4_block_group_get_free_blocks_count(bg, sb); 157 201 uint32_t free_inodes = ext4_block_group_get_free_inodes_count(bg, sb); 158 202 uint32_t used_dirs = ext4_block_group_get_used_dirs_count(bg, sb); 159 203 204 // Check if this block group is good candidate for allocation 160 205 if ((free_inodes >= avg_free_inodes) && (free_blocks > 0)) { 161 206 207 // Load block with bitmap 162 208 uint32_t bitmap_block_addr = ext4_block_group_get_inode_bitmap( 163 209 bg_ref->block_group, sb); … … 170 216 } 171 217 172 // Alloc bit218 // Try to allocate i-node in the bitmap 173 219 uint32_t inodes_in_group = ext4_superblock_get_inodes_in_group(sb, bgid); 174 220 uint32_t index_in_group; … … 176 222 bitmap_block->data, 0, &index_in_group, inodes_in_group); 177 223 178 // Block group is full (inodes)224 // Block group has not any free i-node 179 225 if (rc == ENOSPC) { 180 226 block_put(bitmap_block); … … 183 229 } 184 230 231 // Free i-node found, save the bitmap 185 232 bitmap_block->dirty = true; 186 233 … … 194 241 ext4_block_group_set_free_inodes_count(bg, sb, free_inodes); 195 242 243 // Decrement unused i-nodes counter if supported 196 244 if (ext4_block_group_has_flag(bg, EXT4_BLOCK_GROUP_INODE_UNINIT)) { 197 245 uint16_t unused_inodes = ext4_block_group_get_itable_unused(bg, sb); … … 200 248 } 201 249 250 // Increment used directories counter 202 251 if (is_dir) { 203 252 used_dirs++; … … 205 254 } 206 255 256 // Save modified block group 207 257 bg_ref->dirty = true; 208 258 … … 213 263 } 214 264 265 // Update superblock 215 266 sb_free_inodes--; 216 267 ext4_superblock_set_free_inodes_count(sb, sb_free_inodes); 217 268 269 // Compute the absolute i-nodex number 218 270 *index = ext4_ialloc_index_in_group2inode(sb, index_in_group, bgid); 219 271 … … 222 274 } 223 275 224 // Not modified276 // Block group not modified, put it and jump to the next block group 225 277 ext4_filesystem_put_block_group_ref(bg_ref); 226 278 ++bgid;
Note:
See TracChangeset
for help on using the changeset viewer.