Changeset 1e65444 in mainline for uspace/lib/ext4/libext4_filesystem.c
- Timestamp:
- 2011-11-09T17:52:33Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2b9e142
- Parents:
- 35f48f2
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ext4/libext4_filesystem.c
r35f48f2 r1e65444 364 364 365 365 int ext4_filesystem_set_inode_data_block_index(ext4_filesystem_t *fs, 366 ext4_inode_t *inode, aoff64_t iblock, uint32_t fblock) 367 { 368 369 // int rc; 370 // uint32_t offset_in_block; 371 // uint32_t current_block; 372 // aoff64_t block_offset_in_level; 373 // int i; 374 // int level; 375 // block_t *block; 366 ext4_inode_ref_t *inode_ref, aoff64_t iblock, uint32_t fblock) 367 { 368 369 int rc; 370 uint32_t offset_in_block; 371 uint32_t current_block, new_block_addr; 372 uint32_t block_size; 373 aoff64_t block_offset_in_level; 374 int i; 375 int level; 376 block_t *block, *new_block; 376 377 377 378 /* Handle inode using extents */ 378 379 if (ext4_superblock_has_feature_compatible(fs->superblock, EXT4_FEATURE_INCOMPAT_EXTENTS) && 379 ext4_inode_has_flag(inode , EXT4_INODE_FLAG_EXTENTS)) {380 ext4_inode_has_flag(inode_ref->inode, EXT4_INODE_FLAG_EXTENTS)) { 380 381 // TODO 381 382 return ENOTSUP; … … 385 386 /* Handle simple case when we are dealing with direct reference */ 386 387 if (iblock < EXT4_INODE_DIRECT_BLOCK_COUNT) { 387 ext4_inode_set_direct_block(inode, (uint32_t)iblock, fblock); 388 ext4_inode_set_direct_block(inode_ref->inode, (uint32_t)iblock, fblock); 389 inode_ref->dirty = true; 388 390 return EOK; 389 391 } 390 392 391 // /* Determine the indirection level needed to get the desired block */ 392 // level = -1; 393 // for (i = 1; i < 4; i++) { 394 // if (iblock < fs->inode_block_limits[i]) { 395 // level = i; 396 // break; 397 // } 398 // } 399 // 400 // if (level == -1) { 401 // return EIO; 402 // } 403 // 404 // /* Compute offsets for the topmost level */ 405 // block_offset_in_level = iblock - fs->inode_block_limits[level-1]; 406 // current_block = ext4_inode_get_indirect_block(inode, level-1); 407 // offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1]; 408 // 409 // /* Navigate through other levels, until we find the block number 410 // * or find null reference meaning we are dealing with sparse file 411 // */ 412 // while (level > 0) { 413 // rc = block_get(&block, fs->device, current_block, 0); 414 // if (rc != EOK) { 415 // return rc; 416 // } 417 // 418 // current_block = uint32_t_le2host(((uint32_t*)block->data)[offset_in_block]); 419 // 420 // rc = block_put(block); 421 // if (rc != EOK) { 422 // return rc; 423 // } 424 // 425 // if (current_block == 0) { 426 // /* This is a sparse file */ 427 // *fblock = 0; 428 // return EOK; 429 // } 430 // 431 // level -= 1; 432 // 433 // /* If we are on the last level, break here as 434 // * there is no next level to visit 435 // */ 436 // if (level == 0) { 437 // break; 438 // } 439 // 440 // /* Visit the next level */ 441 // block_offset_in_level %= fs->inode_blocks_per_level[level]; 442 // offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1]; 443 // } 444 // 445 // *fblock = current_block; 446 // 447 // return EOK; 448 // 449 // 393 /* Determine the indirection level needed to get the desired block */ 394 level = -1; 395 for (i = 1; i < 4; i++) { 396 if (iblock < fs->inode_block_limits[i]) { 397 level = i; 398 break; 399 } 400 } 401 402 if (level == -1) { 403 return EIO; 404 } 405 406 block_size = ext4_superblock_get_block_size(fs->superblock); 407 408 /* Compute offsets for the topmost level */ 409 block_offset_in_level = iblock - fs->inode_block_limits[level-1]; 410 current_block = ext4_inode_get_indirect_block(inode_ref->inode, level-1); 411 offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1]; 412 413 if (current_block == 0) { 414 rc = ext4_bitmap_alloc_block(fs, inode_ref, &new_block_addr); 415 if (rc != EOK) { 416 // TODO error 417 } 418 EXT4FS_DBG("AAA: new addr \%u, level = \%u", new_block_addr, level); 419 420 ext4_inode_set_indirect_block(inode_ref->inode, level - 1, new_block_addr); 421 422 inode_ref->dirty = true; 423 424 rc = block_get(&new_block, fs->device, new_block_addr, BLOCK_FLAGS_NOREAD); 425 if (rc != EOK) { 426 EXT4FS_DBG("block load error"); 427 // TODO error 428 } 429 430 memset(new_block->data, 0, block_size); 431 new_block->dirty = true; 432 433 rc = block_put(new_block); 434 if (rc != EOK) { 435 EXT4FS_DBG("block put error"); 436 } 437 438 current_block = new_block_addr; 439 } 440 441 /* Navigate through other levels, until we find the block number 442 * or find null reference meaning we are dealing with sparse file 443 */ 444 while (level > 0) { 445 446 rc = block_get(&block, fs->device, current_block, 0); 447 if (rc != EOK) { 448 return rc; 449 } 450 451 current_block = uint32_t_le2host(((uint32_t*)block->data)[offset_in_block]); 452 453 if (current_block == 0) { 454 if (level > 1) { 455 456 rc = ext4_bitmap_alloc_block(fs, inode_ref, &new_block_addr); 457 if (rc != EOK) { 458 // TODO error 459 } 460 461 rc = block_get(&new_block, fs->device, new_block_addr, BLOCK_FLAGS_NOREAD); 462 if (rc != EOK) { 463 // TODO error 464 } 465 memset(new_block->data, 0, block_size); 466 new_block->dirty = true; 467 468 block_put(new_block); 469 470 ((uint32_t*)block->data)[offset_in_block] = host2uint32_t_le(new_block_addr); 471 block->dirty = true; 472 current_block = new_block_addr; 473 } else { 474 ((uint32_t*)block->data)[offset_in_block] = host2uint32_t_le(fblock); 475 block->dirty = true; 476 } 477 } 478 479 rc = block_put(block); 480 if (rc != EOK) { 481 return rc; 482 } 483 484 level -= 1; 485 486 /* If we are on the last level, break here as 487 * there is no next level to visit 488 */ 489 if (level == 0) { 490 break; 491 } 492 493 /* Visit the next level */ 494 block_offset_in_level %= fs->inode_blocks_per_level[level]; 495 offset_in_block = block_offset_in_level / fs->inode_blocks_per_level[level-1]; 496 } 450 497 451 498 return EOK;
Note:
See TracChangeset
for help on using the changeset viewer.