Changeset 3d4fd2c in mainline for uspace/lib/ext4
- Timestamp:
- 2011-11-22T16:56:09Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 82d7816
- Parents:
- bf66ef4
- Location:
- uspace/lib/ext4
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ext4/libext4.h
rbf66ef4 r3d4fd2c 42 42 #include "libext4_filesystem.h" 43 43 #include "libext4_hash.h" 44 #include "libext4_ialloc.h" 44 45 #include "libext4_inode.h" 45 46 #include "libext4_superblock.h" -
uspace/lib/ext4/libext4_filesystem.c
rbf66ef4 r3d4fd2c 283 283 } 284 284 285 int ext4_filesystem_free_inode(ext4_filesystem_t *fs, ext4_inode_ref_t *inode_ref) 286 { 287 int rc; 288 // release all indirect blocks 289 290 uint32_t fblock; 291 292 // 1) Single indirect 293 fblock = ext4_inode_get_indirect_block(inode_ref->inode, 0); 294 if (fblock != 0) { 295 rc = ext4_balloc_free_block(fs, inode_ref, fblock); 296 if (rc != EOK) { 297 // TODO error 298 } 299 300 ext4_inode_set_indirect_block(inode_ref->inode, 0, 0); 301 } 302 303 block_t *block; 304 uint32_t block_size = ext4_superblock_get_block_size(fs->superblock); 305 uint32_t count = block_size / sizeof(uint32_t); 306 307 // 2) Double indirect 308 fblock = ext4_inode_get_indirect_block(inode_ref->inode, 1); 309 if (fblock != 0) { 310 rc = block_get(&block, fs->device, fblock, BLOCK_FLAGS_NONE); 311 if (rc != EOK) { 312 // TODO error 313 } 314 315 uint32_t ind_block; 316 for (uint32_t offset = 0; offset < count; ++offset) { 317 ind_block = uint32_t_le2host(((uint32_t*)block->data)[offset]); 318 319 if (ind_block != 0) { 320 rc = ext4_balloc_free_block(fs, inode_ref, ind_block); 321 if (rc != EOK) { 322 // TODO error 323 } 324 } 325 } 326 327 block_put(block); 328 rc = ext4_balloc_free_block(fs, inode_ref, fblock); 329 if (rc != EOK) { 330 // TODO error 331 } 332 333 ext4_inode_set_indirect_block(inode_ref->inode, 1, 0); 334 } 335 336 337 // 3) Tripple indirect 338 block_t *subblock; 339 fblock = ext4_inode_get_indirect_block(inode_ref->inode, 2); 340 if (fblock != 0) { 341 rc = block_get(&block, fs->device, fblock, BLOCK_FLAGS_NONE); 342 if (rc != EOK) { 343 // TODO error 344 } 345 346 uint32_t ind_block; 347 for (uint32_t offset = 0; offset < count; ++offset) { 348 ind_block = uint32_t_le2host(((uint32_t*)block->data)[offset]); 349 350 if (ind_block != 0) { 351 rc = block_get(&subblock, fs->device, ind_block, BLOCK_FLAGS_NONE); 352 if (rc != EOK) { 353 // TODO error 354 } 355 356 uint32_t ind_subblock; 357 for (uint32_t suboffset = 0; suboffset < count; ++suboffset) { 358 ind_subblock = uint32_t_le2host(((uint32_t*)subblock->data)[suboffset]); 359 360 if (ind_subblock != 0) { 361 rc = ext4_balloc_free_block(fs, inode_ref, ind_subblock); 362 if (rc != EOK) { 363 // TODO error 364 } 365 } 366 367 } 368 block_put(subblock); 369 370 } 371 372 rc = ext4_balloc_free_block(fs, inode_ref, ind_block); 373 if (rc != EOK) { 374 // TODO error 375 } 376 377 378 } 379 380 block_put(block); 381 rc = ext4_balloc_free_block(fs, inode_ref, fblock); 382 if (rc != EOK) { 383 // TODO error 384 } 385 386 ext4_inode_set_indirect_block(inode_ref->inode, 2, 0); 387 } 388 389 // Free inode 390 rc = ext4_ialloc_free_inode(fs, inode_ref); 391 if (rc != EOK) { 392 return rc; 393 } 394 395 return EOK; 396 } 397 398 int ext4_filesystem_truncate_inode(ext4_filesystem_t *fs, 399 ext4_inode_ref_t *inode_ref, aoff64_t new_size) 400 { 401 aoff64_t old_size; 402 aoff64_t size_diff; 403 404 if (! ext4_inode_can_truncate(fs->superblock, inode_ref->inode)) { 405 // Unable to truncate 406 return EINVAL; 407 } 408 409 old_size = ext4_inode_get_size(fs->superblock, inode_ref->inode); 410 411 if (old_size == new_size) { 412 // Nothing to do 413 return EOK; 414 } 415 416 uint32_t block_size; 417 uint32_t blocks_count, total_blocks; 418 uint32_t i; 419 420 block_size = ext4_superblock_get_block_size(fs->superblock); 421 422 if (old_size < new_size) { 423 // Currently not supported to expand the file 424 // TODO 425 EXT4FS_DBG("trying to expand the file"); 426 return EINVAL; 427 } 428 429 size_diff = old_size - new_size; 430 blocks_count = size_diff / block_size; 431 if (size_diff % block_size != 0) { 432 blocks_count++; 433 } 434 435 total_blocks = old_size / block_size; 436 if (old_size % block_size != 0) { 437 total_blocks++; 438 } 439 440 // starting from 1 because of logical blocks are numbered from 0 441 for (i = 1; i <= blocks_count; ++i) { 442 // TODO check retval 443 // TODO decrement inode->blocks_count 444 445 ext4_filesystem_release_inode_block(fs, inode_ref, total_blocks - i); 446 } 447 448 ext4_inode_set_size(inode_ref->inode, new_size); 449 450 inode_ref->dirty = true; 451 452 return EOK; 453 } 454 285 455 int ext4_filesystem_get_inode_data_block_index(ext4_filesystem_t *fs, ext4_inode_t* inode, 286 456 aoff64_t iblock, uint32_t* fblock) -
uspace/lib/ext4/libext4_filesystem.h
rbf66ef4 r3d4fd2c 61 61 ext4_inode_ref_t **); 62 62 extern int ext4_filesystem_put_inode_ref(ext4_inode_ref_t *); 63 extern int ext4_filesystem_free_inode(ext4_filesystem_t *, ext4_inode_ref_t *); 64 extern int ext4_filesystem_truncate_inode(ext4_filesystem_t *, 65 ext4_inode_ref_t *, aoff64_t); 63 66 extern int ext4_filesystem_get_inode_data_block_index(ext4_filesystem_t *, 64 67 ext4_inode_t *, aoff64_t iblock, uint32_t *); -
uspace/lib/ext4/libext4_ialloc.c
rbf66ef4 r3d4fd2c 36 36 */ 37 37 38 #include <errno.h> 38 39 #include "libext4.h" 40 41 static uint32_t ext4_ialloc_inode2index_in_group(ext4_superblock_t *sb, 42 uint32_t inode) 43 { 44 uint32_t inodes_per_group = ext4_superblock_get_inodes_per_group(sb); 45 return (inode - 1) % inodes_per_group; 46 } 47 48 static uint32_t ext4_ialloc_get_bgid_of_inode(ext4_superblock_t *sb, 49 uint32_t inode) 50 { 51 uint32_t inodes_per_group = ext4_superblock_get_inodes_per_group(sb); 52 return (inode - 1) / inodes_per_group; 53 54 } 55 56 57 int ext4_ialloc_free_inode(ext4_filesystem_t *fs, ext4_inode_ref_t *inode_ref) 58 { 59 int rc; 60 uint32_t block_group = ext4_ialloc_get_bgid_of_inode( 61 fs->superblock, inode_ref->index); 62 uint32_t index_in_group = ext4_ialloc_inode2index_in_group( 63 fs->superblock, inode_ref->index); 64 65 ext4_block_group_ref_t *bg_ref; 66 rc = ext4_filesystem_get_block_group_ref(fs, block_group, &bg_ref); 67 if (rc != EOK) { 68 EXT4FS_DBG("error in loading bg_ref \%d", rc); 69 return rc; 70 } 71 72 uint32_t bitmap_block_addr = ext4_block_group_get_inode_bitmap( 73 bg_ref->block_group, fs->superblock); 74 block_t *bitmap_block; 75 rc = block_get(&bitmap_block, fs->device, bitmap_block_addr, 0); 76 if (rc != EOK) { 77 EXT4FS_DBG("error in loading bitmap \%d", rc); 78 return rc; 79 } 80 81 ext4_bitmap_free_bit(bitmap_block->data, index_in_group); 82 bitmap_block->dirty = true; 83 84 rc = block_put(bitmap_block); 85 if (rc != EOK) { 86 // Error in saving bitmap 87 ext4_filesystem_put_block_group_ref(bg_ref); 88 EXT4FS_DBG("error in saving bitmap \%d", rc); 89 return rc; 90 } 91 92 // Update superblock free inodes count 93 uint32_t sb_free_inodes = ext4_superblock_get_free_inodes_count(fs->superblock); 94 sb_free_inodes--; 95 ext4_superblock_set_free_inodes_count(fs->superblock, sb_free_inodes); 96 97 // Update block group free inodes count 98 uint32_t free_inodes = ext4_block_group_get_free_inodes_count( 99 bg_ref->block_group, fs->superblock); 100 free_inodes++; 101 ext4_block_group_set_free_inodes_count(bg_ref->block_group, 102 fs->superblock, free_inodes); 103 bg_ref->dirty = true; 104 105 rc = ext4_filesystem_put_block_group_ref(bg_ref); 106 if (rc != EOK) { 107 EXT4FS_DBG("error in saving bg_ref \%d", rc); 108 // TODO error 109 return rc; 110 } 111 112 return EOK; 113 } 39 114 40 115 -
uspace/lib/ext4/libext4_ialloc.h
rbf66ef4 r3d4fd2c 34 34 #define LIBEXT4_LIBEXT4_IALLOC_H_ 35 35 36 #include "libext4_filesystem.h" 37 #include "libext4_inode.h" 38 39 extern int ext4_ialloc_free_inode(ext4_filesystem_t *, ext4_inode_ref_t *); 36 40 37 41 #endif
Note:
See TracChangeset
for help on using the changeset viewer.