Changeset 1e65444 in mainline
- Timestamp:
- 2011-11-09T17:52:33Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2b9e142
- Parents:
- 35f48f2
- Location:
- uspace
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ext4/libext4_bitmap.c
r35f48f2 r1e65444 43 43 static void ext4_bitmap_free_bit(uint8_t *bitmap, uint32_t index) 44 44 { 45 // Block numbers are 1-based 45 46 uint32_t byte_index = index / 8; 46 47 uint32_t bit_index = index % 8; 48 49 // EXT4FS_DBG("freeing block \%u, byte \%u and bit \%u", index, byte_index, bit_index); 47 50 48 51 uint8_t *target = bitmap + byte_index; … … 59 62 int i; 60 63 uint32_t idx = 0; 64 uint8_t value, new_value; 61 65 62 66 while (pos < bitmap + size) { … … 72 76 if (pos < bitmap + size) { 73 77 78 // EXT4FS_DBG("byte found \%u", (uint32_t)(pos - bitmap)); 79 74 80 for(i = 0; i < 8; ++i) { 75 if ((*pos & (1 << i)) == 0) { 81 value = *pos; 82 83 if ((value & (1 << i)) == 0) { 76 84 // free bit found 77 *pos |= (1 << i); 78 *index = idx; 85 // EXT4FS_DBG("bit found \%u", i); 86 new_value = value | (1 << i); 87 *pos = new_value; 88 *index = idx + i; 79 89 return EOK; 80 90 } 81 82 idx++;83 91 } 84 92 } … … 98 106 99 107 blocks_per_group = ext4_superblock_get_blocks_per_group(fs->superblock); 100 block_group = block_index / blocks_per_group;101 index_in_group = block_index% blocks_per_group;108 block_group = ((block_index - 1) / blocks_per_group); 109 index_in_group = (block_index - 1) % blocks_per_group; 102 110 103 111 rc = ext4_filesystem_get_block_group_ref(fs, block_group, &bg_ref); … … 133 141 return rc; 134 142 } 143 144 EXT4FS_DBG("block \%u released", block_index); 135 145 136 146 return EOK; … … 148 158 149 159 inodes_per_group = ext4_superblock_get_inodes_per_group(fs->superblock); 150 block_group = inode_ref->index/ inodes_per_group;160 block_group = (inode_ref->index - 1) / inodes_per_group; 151 161 152 162 block_size = ext4_superblock_get_block_size(fs->superblock); … … 166 176 167 177 rc = ext4_bitmap_find_free_bit_and_set(block->data, &rel_block_idx, block_size); 168 169 170 178 if (rc != EOK) { 171 179 EXT4FS_DBG("no block found"); 172 180 // TODO if ENOSPC - try next block group - try next block groups 173 181 } 182 183 block->dirty = true; 184 185 // TODO check retval 186 block_put(block); 174 187 175 188 // TODO decrement superblock free blocks count … … 179 192 180 193 uint32_t bg_free_blocks = ext4_block_group_get_free_blocks_count(bg_ref->block_group); 181 bg_free_blocks ++;194 bg_free_blocks--; 182 195 ext4_block_group_set_free_blocks_count(bg_ref->block_group, bg_free_blocks); 183 196 bg_ref->dirty = true; 184 197 185 // return 198 ext4_filesystem_put_block_group_ref(bg_ref); 199 186 200 blocks_per_group = ext4_superblock_get_blocks_per_group(fs->superblock); 187 *fblock = blocks_per_group * block_group + rel_block_idx; 201 202 EXT4FS_DBG("block \%u allocated", blocks_per_group * block_group + rel_block_idx + 1); 203 204 *fblock = blocks_per_group * block_group + rel_block_idx + 1; 188 205 return EOK; 189 206 -
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; -
uspace/lib/ext4/libext4_filesystem.h
r35f48f2 r1e65444 63 63 ext4_inode_t *, aoff64_t iblock, uint32_t *); 64 64 extern int ext4_filesystem_set_inode_data_block_index(ext4_filesystem_t *, 65 ext4_inode_ t *, aoff64_t, uint32_t);65 ext4_inode_ref_t *, aoff64_t, uint32_t); 66 66 extern int ext4_filesystem_release_inode_block(ext4_filesystem_t *, 67 67 ext4_inode_ref_t *, uint32_t); -
uspace/lib/ext4/libext4_inode.c
r35f48f2 r1e65444 97 97 } 98 98 99 uint32_t ext4_inode_get_direct_block(ext4_inode_t *inode, uint 8_t idx)99 uint32_t ext4_inode_get_direct_block(ext4_inode_t *inode, uint32_t idx) 100 100 { 101 101 assert(idx < EXT4_INODE_DIRECT_BLOCK_COUNT); … … 103 103 } 104 104 105 void ext4_inode_set_direct_block(ext4_inode_t *inode, uint 8_t idx, uint32_t fblock)105 void ext4_inode_set_direct_block(ext4_inode_t *inode, uint32_t idx, uint32_t fblock) 106 106 { 107 107 assert(idx < EXT4_INODE_DIRECT_BLOCK_COUNT); … … 109 109 } 110 110 111 uint32_t ext4_inode_get_indirect_block(ext4_inode_t *inode, uint8_t idx) 112 { 113 assert(idx < EXT4_INODE_INDIRECT_BLOCK_COUNT); 111 uint32_t ext4_inode_get_indirect_block(ext4_inode_t *inode, uint32_t idx) 112 { 114 113 return uint32_t_le2host(inode->blocks[idx + EXT4_INODE_INDIRECT_BLOCK]); 115 114 } 115 116 void ext4_inode_set_indirect_block(ext4_inode_t *inode, uint32_t idx, uint32_t fblock) 117 { 118 inode->blocks[idx + EXT4_INODE_INDIRECT_BLOCK] = host2uint32_t_le(fblock); 119 } 120 116 121 117 122 uint32_t ext4_inode_get_extent_block(ext4_inode_t *inode, uint64_t idx, service_id_t service_id) -
uspace/lib/ext4/libext4_inode.h
r35f48f2 r1e65444 168 168 extern uint32_t ext4_inode_get_flags(ext4_inode_t *); 169 169 170 extern uint32_t ext4_inode_get_direct_block(ext4_inode_t *, uint8_t); 171 extern void ext4_inode_set_direct_block(ext4_inode_t *, uint8_t, uint32_t); 172 extern uint32_t ext4_inode_get_indirect_block(ext4_inode_t *, uint8_t); 170 extern uint32_t ext4_inode_get_direct_block(ext4_inode_t *, uint32_t); 171 extern void ext4_inode_set_direct_block(ext4_inode_t *, uint32_t, uint32_t); 172 extern uint32_t ext4_inode_get_indirect_block(ext4_inode_t *, uint32_t); 173 extern void ext4_inode_set_indirect_block(ext4_inode_t *, uint32_t, uint32_t); 173 174 extern uint32_t ext4_inode_get_extent_block(ext4_inode_t *, uint64_t, service_id_t); 174 175 /* -
uspace/srv/fs/ext4fs/ext4fs_ops.c
r35f48f2 r1e65444 926 926 size_t *wbytes, aoff64_t *nsize) 927 927 { 928 EXT4FS_DBG("");929 930 928 int rc; 931 929 int flags = BLOCK_FLAGS_NONE; … … 966 964 } 967 965 968 EXT4FS_DBG("bytes == \%u", bytes);966 // EXT4FS_DBG("bytes == \%u", bytes); 969 967 970 968 iblock = pos / block_size; … … 973 971 974 972 if (fblock == 0) { 975 EXT4FS_DBG("Allocate block !!!");973 // EXT4FS_DBG("Allocate block !!!"); 976 974 rc = ext4_bitmap_alloc_block(fs, inode_ref, &fblock); 977 975 if (rc != EOK) { … … 981 979 } 982 980 983 ext4_filesystem_set_inode_data_block_index(fs, inode_ref ->inode, iblock, fblock);981 ext4_filesystem_set_inode_data_block_index(fs, inode_ref, iblock, fblock); 984 982 inode_ref->dirty = true; 985 983 986 984 flags = BLOCK_FLAGS_NOREAD; 987 985 988 EXT4FS_DBG("block \%u allocated", fblock);986 // EXT4FS_DBG("block \%u allocated", fblock); 989 987 } 990 988 … … 996 994 } 997 995 998 EXT4FS_DBG("block loaded");999 1000 996 if (flags == BLOCK_FLAGS_NOREAD) { 1001 EXT4FS_DBG("fill block with zeros");997 // EXT4FS_DBG("fill block with zeros"); 1002 998 memset(write_block->data, 0, block_size); 1003 999 } … … 1005 1001 rc = async_data_write_finalize(callid, write_block->data + (pos % block_size), bytes); 1006 1002 if (rc != EOK) { 1003 // TODO error 1007 1004 EXT4FS_DBG("error in write finalize \%d", rc); 1008 1005 } 1009 1006 1010 char *data = write_block->data + (pos % block_size);1011 for (uint32_t x = 0; x < bytes; ++x) {1012 printf("%c", data[x]);1013 }1014 printf("\n");1015 1016 1007 write_block->dirty = true; 1017 1008 … … 1022 1013 } 1023 1014 1024 EXT4FS_DBG("writing finished");1015 // EXT4FS_DBG("writing finished"); 1025 1016 1026 1017 old_inode_size = ext4_inode_get_size(fs->superblock, inode_ref->inode);
Note:
See TracChangeset
for help on using the changeset viewer.