Changeset 3d4fd2c in mainline
- Timestamp:
- 2011-11-22T16:56:09Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 82d7816
- Parents:
- bf66ef4
- Location:
- uspace
- Files:
-
- 6 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 -
uspace/srv/fs/ext4fs/ext4fs_ops.c
rbf66ef4 r3d4fd2c 382 382 int ext4fs_destroy_node(fs_node_t *fn) 383 383 { 384 int rc; 385 386 bool has_children; 387 rc = ext4fs_has_children(&has_children, fn); 388 if (rc != EOK) { 389 ext4fs_node_put(fn); 390 return rc; 391 } 392 393 if (has_children) { 394 EXT4FS_DBG("destroying non-empty node"); 395 ext4fs_node_put(fn); 396 return EINVAL; 397 } 398 399 ext4fs_node_t *enode = EXT4FS_NODE(fn); 400 ext4_filesystem_t *fs = enode->instance->filesystem; 401 ext4_inode_ref_t *inode_ref = enode->inode_ref; 402 403 EXT4FS_DBG("destroying \%u", inode_ref->index); 404 405 rc = ext4_filesystem_truncate_inode(fs, inode_ref, 0); 406 if (rc != EOK) { 407 ext4fs_node_put(fn); 408 return rc; 409 } 410 411 rc = ext4_filesystem_free_inode(fs, inode_ref); 412 if (rc != EOK) { 413 ext4fs_node_put(fn); 414 return rc; 415 } 416 417 ext4fs_node_put(fn); 418 return EOK; 419 420 // EXT4FS_DBG("not supported"); 421 // 422 // // TODO 423 // return ENOTSUP; 424 } 425 426 427 int ext4fs_link(fs_node_t *pfn, fs_node_t *cfn, const char *name) 428 { 384 429 EXT4FS_DBG("not supported"); 385 430 … … 389 434 390 435 391 int ext4fs_link(fs_node_t *pfn, fs_node_t *cfn, const char *name)392 {393 EXT4FS_DBG("not supported");394 395 // TODO396 return ENOTSUP;397 }398 399 400 436 int ext4fs_unlink(fs_node_t *pfn, fs_node_t *cfn, const char *name) 401 437 { 438 EXT4FS_DBG("unlinking \%s", name); 439 402 440 int rc; 403 441 … … 430 468 child_inode_ref->dirty = true; 431 469 470 // EXT4FS_DBG("links count = \%u", lnk_count); 471 432 472 // If directory - handle links from parent 433 473 if (lnk_count <= 1 && ext4fs_is_directory(cfn)) { 434 474 435 ext4_inode_ref_t *parent_inode_ref = EXT4FS_NODE(pfn)->inode_ref; 436 uint32_t parent_lnk_count = ext4_inode_get_links_count( 437 parent_inode_ref->inode); 438 parent_lnk_count--; 439 ext4_inode_set_links_count(parent_inode_ref->inode, parent_lnk_count); 440 441 parent_inode_ref->dirty = true; 475 // EXT4FS_DBG("directory will be removed, lnlk_count = \%u", lnk_count); 476 477 if (lnk_count) { 478 lnk_count = ext4_inode_get_links_count(child_inode_ref->inode); 479 lnk_count--; 480 ext4_inode_set_links_count(child_inode_ref->inode, lnk_count); 481 } 482 483 // ext4_inode_ref_t *parent_inode_ref = EXT4FS_NODE(pfn)->inode_ref; 484 // uint32_t parent_lnk_count = ext4_inode_get_links_count( 485 // parent_inode_ref->inode); 486 // 487 // EXT4FS_DBG("directory will be removed, parent link count = \%u", parent_lnk_count); 488 // 489 // parent_lnk_count--; 490 // ext4_inode_set_links_count(parent_inode_ref->inode, parent_lnk_count); 491 // 492 // parent_inode_ref->dirty = true; 442 493 } 443 494 … … 1021 1072 ext4fs_truncate(service_id_t service_id, fs_index_t index, aoff64_t new_size) 1022 1073 { 1074 int rc; 1023 1075 fs_node_t *fn; 1024 ext4fs_node_t *enode; 1025 ext4_inode_ref_t *inode_ref; 1026 ext4_filesystem_t* fs; 1027 aoff64_t old_size; 1028 aoff64_t size_diff; 1029 int rc; 1076 // aoff64_t old_size; 1077 // aoff64_t size_diff; 1030 1078 1031 1079 rc = ext4fs_node_get(&fn, service_id, index); … … 1034 1082 } 1035 1083 1036 enode = EXT4FS_NODE(fn); 1037 inode_ref = enode->inode_ref; 1038 fs = enode->instance->filesystem; 1039 1040 1041 if (! ext4_inode_can_truncate(fs->superblock, inode_ref->inode)) { 1042 // Unable to truncate 1043 ext4fs_node_put(fn); 1044 return EINVAL; 1045 } 1046 1047 old_size = ext4_inode_get_size(fs->superblock, inode_ref->inode); 1048 1049 if (old_size == new_size) { 1050 ext4fs_node_put(fn); 1051 return EOK; 1052 } else { 1053 1054 uint32_t block_size; 1055 uint32_t blocks_count, total_blocks; 1056 uint32_t i; 1057 1058 block_size = ext4_superblock_get_block_size(fs->superblock); 1059 1060 if (old_size < new_size) { 1061 // Currently not supported to expand the file 1062 // TODO 1063 EXT4FS_DBG("trying to expand the file"); 1064 return EINVAL; 1065 } 1066 1067 size_diff = old_size - new_size; 1068 blocks_count = size_diff / block_size; 1069 if (size_diff % block_size != 0) { 1070 blocks_count++; 1071 } 1072 1073 total_blocks = old_size / block_size; 1074 if (old_size % block_size != 0) { 1075 total_blocks++; 1076 } 1077 1078 inode_ref->dirty = true; 1079 1080 // starting from 1 because of logical blocks are numbered from 0 1081 for (i = 1; i <= blocks_count; ++i) { 1082 // TODO check retval 1083 // TODO decrement inode->blocks_count 1084 1085 ext4_filesystem_release_inode_block(fs, inode_ref, total_blocks - i); 1086 } 1087 1088 ext4_inode_set_size(inode_ref->inode, new_size); 1089 1090 } 1091 1084 ext4fs_node_t *enode = EXT4FS_NODE(fn); 1085 ext4_inode_ref_t *inode_ref = enode->inode_ref; 1086 ext4_filesystem_t *fs = enode->instance->filesystem; 1087 1088 rc = ext4_filesystem_truncate_inode(fs, inode_ref, new_size); 1092 1089 ext4fs_node_put(fn); 1093 1090 1094 return EOK; 1091 return rc; 1092 1093 // if (! ext4_inode_can_truncate(fs->superblock, inode_ref->inode)) { 1094 // // Unable to truncate 1095 // ext4fs_node_put(fn); 1096 // return EINVAL; 1097 // } 1098 // 1099 // old_size = ext4_inode_get_size(fs->superblock, inode_ref->inode); 1100 // 1101 // if (old_size == new_size) { 1102 // ext4fs_node_put(fn); 1103 // return EOK; 1104 // } else { 1105 // 1106 // uint32_t block_size; 1107 // uint32_t blocks_count, total_blocks; 1108 // uint32_t i; 1109 // 1110 // block_size = ext4_superblock_get_block_size(fs->superblock); 1111 // 1112 // if (old_size < new_size) { 1113 // // Currently not supported to expand the file 1114 // // TODO 1115 // EXT4FS_DBG("trying to expand the file"); 1116 // ext4fs_node_put(fn); 1117 // return EINVAL; 1118 // } 1119 // 1120 // size_diff = old_size - new_size; 1121 // blocks_count = size_diff / block_size; 1122 // if (size_diff % block_size != 0) { 1123 // blocks_count++; 1124 // } 1125 // 1126 // total_blocks = old_size / block_size; 1127 // if (old_size % block_size != 0) { 1128 // total_blocks++; 1129 // } 1130 // 1131 // // starting from 1 because of logical blocks are numbered from 0 1132 // for (i = 1; i <= blocks_count; ++i) { 1133 // // TODO check retval 1134 // // TODO decrement inode->blocks_count 1135 // 1136 // ext4_filesystem_release_inode_block(fs, inode_ref, total_blocks - i); 1137 // } 1138 // 1139 // ext4_inode_set_size(inode_ref->inode, new_size); 1140 // 1141 // inode_ref->dirty = true; 1142 // 1143 // } 1144 // 1145 // ext4fs_node_put(fn); 1146 // 1147 // return EOK; 1095 1148 } 1096 1149
Note:
See TracChangeset
for help on using the changeset viewer.