Changeset 728d771 in mainline
- Timestamp:
- 2012-04-22T13:11:29Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 6773ff3
- Parents:
- cb7056a
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ext4/libext4_extent.c
rcb7056a r728d771 41 41 #include "libext4.h" 42 42 43 /** Get logical number of the block covered extent.43 /** Get logical number of the block covered by extent. 44 44 * 45 45 * @param extent extent to load number from … … 53 53 /** Set logical number of the first block covered by extent. 54 54 * 55 * @param extent extent to load number from55 * @param extent extent to set number to 56 56 * @param iblock logical number of the first block covered by extent 57 57 */ … … 103 103 } 104 104 105 // TODO start comments here 106 105 /** Get logical number of the block covered by extent index. 106 * 107 * @param index extent index to load number from 108 * @return logical number of the first block covered by extent index 109 */ 107 110 uint32_t ext4_extent_index_get_first_block(ext4_extent_index_t *index) 108 111 { … … 110 113 } 111 114 115 /** Set logical number of the block covered by extent index. 116 * 117 * @param index extent index to set number to 118 * @param iblock logical number of the first block covered by extent index 119 */ 112 120 void ext4_extent_index_set_first_block(ext4_extent_index_t *index, 113 uint32_t first) 114 { 115 index->first_block = host2uint32_t_le(first); 116 } 117 121 uint32_t iblock) 122 { 123 index->first_block = host2uint32_t_le(iblock); 124 } 125 126 /** Get physical number of block where the child node is located. 127 * 128 * @param index extent index to load number from 129 * @return physical number of the block with child node 130 */ 118 131 uint64_t ext4_extent_index_get_leaf(ext4_extent_index_t *index) 119 132 { … … 122 135 } 123 136 124 void ext4_extent_index_set_leaf(ext4_extent_index_t *index, uint64_t leaf) 125 { 126 index->leaf_lo = host2uint32_t_le((leaf << 32) >> 32); 127 index->leaf_hi = host2uint16_t_le((uint16_t)(leaf >> 32)); 128 } 129 137 /** Set physical number of block where the child node is located. 138 * 139 * @param index extent index to set number to 140 * @param fblock physical number of the block with child node 141 */ 142 void ext4_extent_index_set_leaf(ext4_extent_index_t *index, uint64_t fblock) 143 { 144 index->leaf_lo = host2uint32_t_le((fblock << 32) >> 32); 145 index->leaf_hi = host2uint16_t_le((uint16_t)(fblock >> 32)); 146 } 147 148 /** Get magic value from extent header. 149 * 150 * @param header extent header to load value from 151 * @return magic value of extent header 152 */ 130 153 uint16_t ext4_extent_header_get_magic(ext4_extent_header_t *header) 131 154 { … … 133 156 } 134 157 158 /** Set magic value to extent header. 159 * 160 * @param header extent header to set value to 161 * @param magic magic value of extent header 162 */ 135 163 void ext4_extent_header_set_magic(ext4_extent_header_t *header, uint16_t magic) 136 164 { … … 138 166 } 139 167 168 /** Get number of entries from extent header 169 * 170 * @param header extent header to get value from 171 * @return number of entries covered by extent header 172 */ 140 173 uint16_t ext4_extent_header_get_entries_count(ext4_extent_header_t *header) 141 174 { … … 143 176 } 144 177 178 /** Set number of entries to extent header 179 * 180 * @param header extent header to set value to 181 * @param count number of entries covered by extent header 182 */ 145 183 void ext4_extent_header_set_entries_count(ext4_extent_header_t *header, 146 184 uint16_t count) … … 149 187 } 150 188 189 /** Get maximum number of entries from extent header 190 * 191 * @param header extent header to get value from 192 * @return maximum number of entries covered by extent header 193 */ 151 194 uint16_t ext4_extent_header_get_max_entries_count(ext4_extent_header_t *header) 152 195 { … … 154 197 } 155 198 199 /** Set maximum number of entries to extent header 200 * 201 * @param header extent header to set value to 202 * @param max_count maximum number of entries covered by extent header 203 */ 156 204 void ext4_extent_header_set_max_entries_count(ext4_extent_header_t *header, 157 205 uint16_t max_count) … … 160 208 } 161 209 210 /** Get depth of extent subtree. 211 * 212 * @param header extent header to get value from 213 * @return depth of extent subtree 214 */ 162 215 uint16_t ext4_extent_header_get_depth(ext4_extent_header_t *header) 163 216 { … … 165 218 } 166 219 220 /** Set depth of extent subtree. 221 * 222 * @param header extent header to set value to 223 * @param depth depth of extent subtree 224 */ 167 225 void ext4_extent_header_set_depth(ext4_extent_header_t *header, uint16_t depth) 168 226 { … … 170 228 } 171 229 230 /** Get generation from extent header 231 * 232 * @param header extent header to get value from 233 * @return generation 234 */ 172 235 uint32_t ext4_extent_header_get_generation(ext4_extent_header_t *header) 173 236 { … … 175 238 } 176 239 240 /** Set generation to extent header 241 * 242 * @param header extent header to set value to 243 * @param generation generation 244 */ 177 245 void ext4_extent_header_set_generation(ext4_extent_header_t *header, 178 246 uint32_t generation) … … 181 249 } 182 250 183 /** 184 * Binary search in extent index node 251 /** Binary search in extent index node. 252 * 253 * @param header extent header of index node 254 * @param index output value - found index will be set here 255 * @param iblock logical block number to find in index node 185 256 */ 186 257 static void ext4_extent_binsearch_idx(ext4_extent_header_t *header, … … 191 262 uint16_t entries_count = ext4_extent_header_get_entries_count(header); 192 263 264 // Check trivial situation 193 265 if (entries_count == 1) { 194 266 *index = EXT4_EXTENT_FIRST_INDEX(header); … … 196 268 } 197 269 270 // Initialize bounds 198 271 l = EXT4_EXTENT_FIRST_INDEX(header) + 1; 199 272 r = l + entries_count - 1; 200 273 274 // Do binary search 201 275 while (l <= r) { 202 276 m = l + (r - l) / 2; … … 209 283 } 210 284 285 // Set output value 211 286 *index = l - 1; 212 287 } 213 288 214 /** 215 * Binary search in extent leaf node 289 /** Binary search in extent leaf node. 290 * @param header extent header of leaf node 291 * @param extent output value - found extent will be set here, 292 * or NULL if node is empty 293 * @param iblock logical block number to find in leaf node 294 * 216 295 */ 217 296 static void ext4_extent_binsearch(ext4_extent_header_t *header, … … 224 303 if (entries_count == 0) { 225 304 // this leaf is empty 226 // EXT4FS_DBG("EMPTY LEAF");227 305 *extent = NULL; 228 306 return; 229 307 } 230 308 309 // Check trivial situation 231 310 if (entries_count == 1) { 232 311 *extent = EXT4_EXTENT_FIRST(header); … … 234 313 } 235 314 315 // Initialize bounds 236 316 l = EXT4_EXTENT_FIRST(header) + 1; 237 317 r = l + entries_count - 1; 238 318 319 // Do binary search 239 320 while (l < r) { 240 321 m = l + (r - l) / 2; … … 247 328 } 248 329 330 // Set output value 249 331 *extent = l - 1; 250 332 } 251 333 252 // Reading routine without saving blocks to path - for saving memory during finding block 253 int ext4_extent_find_block(ext4_inode_ref_t *inode_ref, uint32_t iblock, uint32_t *fblock) 334 /** Find physical block in the extent tree by logical block number. 335 * 336 * There is no need to save path in the tree during this algorithm. 337 * 338 * @param inode_ref i-node to load block from 339 * @param iblock logical block number to find 340 * @param fblock output value for physical block number 341 * @return error code 342 */ 343 int ext4_extent_find_block(ext4_inode_ref_t *inode_ref, 344 uint32_t iblock, uint32_t *fblock) 254 345 { 255 346 int rc; 256 347 348 // Compute bound defined by i-node size 257 349 uint64_t inode_size = ext4_inode_get_size( 258 350 inode_ref->fs->superblock, inode_ref->inode); … … 263 355 uint32_t last_idx = (inode_size - 1) / block_size; 264 356 357 // Check if requested iblock is not over size of i-node 265 358 if (iblock > last_idx) { 266 359 *fblock = 0; … … 270 363 block_t* block = NULL; 271 364 365 // Walk through extent tree 272 366 ext4_extent_header_t *header = ext4_inode_get_extent_header(inode_ref->inode); 273 367 while (ext4_extent_header_get_depth(header) != 0) { 274 368 369 // Search index in node 275 370 ext4_extent_index_t *index; 276 371 ext4_extent_binsearch_idx(header, &index, iblock); 277 372 373 // Load child node and set values for the next iteration 278 374 uint64_t child = ext4_extent_index_get_leaf(index); 279 375 … … 290 386 } 291 387 292 388 // Search extent in the leaf block 293 389 ext4_extent_t* extent = NULL; 294 390 ext4_extent_binsearch(header, &extent, iblock); 295 391 392 // Prevent empty leaf 296 393 if (extent == NULL) { 297 394 *fblock = 0; 298 395 } else { 396 397 // Compute requested physical block address 299 398 uint32_t phys_block; 300 399 phys_block = ext4_extent_get_start(extent) + iblock; … … 304 403 } 305 404 405 // Cleanup 306 406 if (block != NULL) { 307 407 block_put(block); … … 311 411 } 312 412 413 414 /** Find extent for specified iblock. 415 * 416 * This function is used for finding block in the extent tree with 417 * saving the path through the tree for possible future modifications. 418 * 419 * @param inode_ref i-node to read extent tree from 420 * @param iblock iblock to find extent for 421 * @param ret_path output value for loaded path from extent tree 422 * @return error code 423 */ 313 424 static int ext4_extent_find_extent(ext4_inode_ref_t *inode_ref, 314 425 uint32_t iblock, ext4_extent_path_t **ret_path) … … 329 440 } 330 441 442 // Initialize structure for algorithm start 331 443 tmp_path[0].block = inode_ref->block; 332 444 tmp_path[0].header = eh; 333 445 446 // Walk through the extent tree 334 447 uint16_t pos = 0; 335 448 while (ext4_extent_header_get_depth(eh) != 0) { 336 449 450 // Search index in index node by iblock 337 451 ext4_extent_binsearch_idx(tmp_path[pos].header, &tmp_path[pos].index, iblock); 338 452 … … 342 456 assert(tmp_path[pos].index != NULL); 343 457 458 // Load information for the next iteration 344 459 uint64_t fblock = ext4_extent_index_get_leaf(tmp_path[pos].index); 345 460 … … 362 477 tmp_path[pos].index = NULL; 363 478 364 / * find extent */479 // Find extent in the leaf node 365 480 ext4_extent_binsearch(tmp_path[pos].header, &tmp_path[pos].extent, iblock); 366 481 … … 382 497 383 498 return rc; 384 385 } 386 387 static int ext4_extent_release(ext4_inode_ref_t *inode_ref, ext4_extent_t* extent) 499 } 500 501 /** Release extent and all data blocks covered by the extent. 502 * 503 * @param inode_ref i-node to release extent and block from 504 * @param extent extent to release 505 * @return error code 506 */ 507 static int ext4_extent_release( 508 ext4_inode_ref_t *inode_ref, ext4_extent_t *extent) 388 509 { 389 510 int rc; 390 511 512 // Compute number of the first physical block to release 391 513 uint64_t start = ext4_extent_get_start(extent); 392 514 uint16_t block_count = ext4_extent_get_block_count(extent); … … 394 516 rc = ext4_balloc_free_blocks(inode_ref, start, block_count); 395 517 if (rc != EOK) { 396 EXT4FS_DBG("E RROR");518 EXT4FS_DBG("Error in releasing data blocks"); 397 519 return rc; 398 520 } … … 400 522 return EOK; 401 523 } 524 525 // TODO comments 402 526 403 527 // Recursive release
Note:
See TracChangeset
for help on using the changeset viewer.