Changeset 7689590 in mainline
- Timestamp:
- 2012-03-03T17:44:38Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- e63ce679
- Parents:
- c30a015
- Location:
- uspace
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ext4/libext4_directory.c
rc30a015 r7689590 345 345 // Linear algorithm 346 346 347 EXT4FS_DBG("Linear algorithm");348 349 347 uint32_t iblock, fblock; 350 348 uint32_t block_size = ext4_superblock_get_block_size(fs->superblock); … … 354 352 uint32_t name_len = strlen(name); 355 353 354 // Find block, where is space for new entry 356 355 bool success = false; 357 356 for (iblock = 0; iblock < total_blocks; ++iblock) { … … 383 382 } 384 383 385 386 EXT4FS_DBG("NO FREE SPACE - needed to allocate block"); 384 // No free block found - needed to allocate next block 387 385 388 386 rc = ext4_directory_append_block(fs, parent, &fblock, &iblock); … … 391 389 } 392 390 393 // Load block391 // Load new block 394 392 block_t *new_block; 395 393 rc = block_get(&new_block, fs->device, fblock, BLOCK_FLAGS_NOREAD); … … 403 401 ext4_directory_write_entry(fs->superblock, block_entry, block_size, child, name, name_len); 404 402 403 // Save new block 405 404 new_block->dirty = true; 406 405 rc = block_put(new_block); … … 412 411 } 413 412 414 int ext4_directory_find_entry(ext4_directory_iterator_t *it, 415 ext4_inode_ref_t *parent, const char *name) 413 int ext4_directory_find_entry(ext4_filesystem_t *fs, 414 ext4_directory_search_result_t *result, ext4_inode_ref_t *parent, 415 const char *name) 416 416 { 417 417 int rc; 418 uint32_t name_ size= strlen(name);418 uint32_t name_len = strlen(name); 419 419 420 420 // Index search 421 if (ext4_superblock_has_feature_compatible( it->fs->superblock, EXT4_FEATURE_COMPAT_DIR_INDEX) &&421 if (ext4_superblock_has_feature_compatible(fs->superblock, EXT4_FEATURE_COMPAT_DIR_INDEX) && 422 422 ext4_inode_has_flag(parent->inode, EXT4_INODE_FLAG_INDEX)) { 423 423 424 rc = ext4_directory_dx_find_entry( it, it->fs, parent, name_size, name);424 rc = ext4_directory_dx_find_entry(result, fs, parent, name_len, name); 425 425 426 426 // Check if index is not corrupted … … 434 434 435 435 EXT4FS_DBG("index is corrupted - doing linear search"); 436 437 } 438 439 bool found = false; 440 // Linear search 441 while (it->current != NULL) { 442 uint32_t inode = ext4_directory_entry_ll_get_inode(it->current); 443 444 /* ignore empty directory entries */ 445 if (inode != 0) { 446 uint16_t entry_name_size = ext4_directory_entry_ll_get_name_length( 447 it->fs->superblock, it->current); 448 449 if (entry_name_size == name_size && bcmp(name, it->current->name, 450 name_size) == 0) { 451 found = true; 452 break; 453 } 454 } 455 456 rc = ext4_directory_iterator_next(it); 457 if (rc != EOK) { 458 return rc; 459 } 460 } 461 462 if (!found) { 463 return ENOENT; 464 } 465 466 return EOK; 436 } 437 438 uint32_t iblock, fblock; 439 uint32_t block_size = ext4_superblock_get_block_size(fs->superblock); 440 uint32_t inode_size = ext4_inode_get_size(fs->superblock, parent->inode); 441 uint32_t total_blocks = inode_size / block_size; 442 443 for (iblock = 0; iblock < total_blocks; ++iblock) { 444 445 rc = ext4_filesystem_get_inode_data_block_index(fs, parent->inode, iblock, &fblock); 446 if (rc != EOK) { 447 return rc; 448 } 449 450 block_t *block; 451 rc = block_get(&block, fs->device, fblock, BLOCK_FLAGS_NONE); 452 if (rc != EOK) { 453 return rc; 454 } 455 456 // find block entry 457 ext4_directory_entry_ll_t *res_entry; 458 rc = ext4_directory_find_in_block(block, fs->superblock, name_len, name, &res_entry); 459 if (rc == EOK) { 460 result->block = block; 461 result->dentry = res_entry; 462 return EOK; 463 } 464 465 rc = block_put(block); 466 if (rc != EOK) { 467 return rc; 468 } 469 } 470 471 result->block = NULL; 472 result->dentry = NULL; 473 474 return ENOENT; 467 475 } 468 476 … … 478 486 } 479 487 480 ext4_directory_ iterator_t it;481 rc = ext4_directory_iterator_init(&it, fs, parent, 0);488 ext4_directory_search_result_t result; 489 rc = ext4_directory_find_entry(fs, &result, parent, name); 482 490 if (rc != EOK) { 483 491 return rc; 484 492 } 485 493 486 rc = ext4_directory_find_entry(&it, parent, name); 487 if (rc != EOK) { 488 ext4_directory_iterator_fini(&it); 489 return rc; 490 } 491 492 uint32_t block_size = ext4_superblock_get_block_size(fs->superblock); 493 uint32_t pos = it.current_offset % block_size; 494 495 ext4_directory_entry_ll_set_inode(it.current, 0); 496 494 ext4_directory_entry_ll_set_inode(result.dentry, 0); 495 496 uint32_t pos = (void *)result.dentry - result.block->data; 497 498 uint32_t offset = 0; 497 499 if (pos != 0) { 498 uint32_t offset = 0; 499 500 ext4_directory_entry_ll_t *tmp_dentry = it.current_block->data; 500 501 ext4_directory_entry_ll_t *tmp_dentry = result.block->data; 501 502 uint16_t tmp_dentry_length = 502 503 ext4_directory_entry_ll_get_entry_length(tmp_dentry); … … 504 505 while ((offset + tmp_dentry_length) < pos) { 505 506 offset += ext4_directory_entry_ll_get_entry_length(tmp_dentry); 506 tmp_dentry = it.current_block->data + offset;507 tmp_dentry = result.block->data + offset; 507 508 tmp_dentry_length = 508 509 ext4_directory_entry_ll_get_entry_length(tmp_dentry); … … 512 513 513 514 uint16_t del_entry_length = 514 ext4_directory_entry_ll_get_entry_length( it.current);515 ext4_directory_entry_ll_get_entry_length(result.dentry); 515 516 ext4_directory_entry_ll_set_entry_length(tmp_dentry, 516 517 tmp_dentry_length + del_entry_length); … … 518 519 } 519 520 520 521 it.current_block->dirty = true; 522 523 ext4_directory_iterator_fini(&it); 524 return EOK; 525 } 521 result.block->dirty = true; 522 523 return ext4_directory_destroy_result(&result); 524 } 525 526 526 527 527 int ext4_directory_try_insert_entry(ext4_superblock_t *sb, … … 580 580 } 581 581 582 int ext4_directory_find_in_block(block_t *block, 583 ext4_superblock_t *sb, size_t name_len, const char *name, 584 ext4_directory_entry_ll_t **res_entry) 585 { 586 587 ext4_directory_entry_ll_t *dentry = (ext4_directory_entry_ll_t *)block->data; 588 uint8_t *addr_limit = block->data + ext4_superblock_get_block_size(sb); 589 590 while ((uint8_t *)dentry < addr_limit) { 591 592 if ((uint8_t*) dentry + name_len > addr_limit) { 593 break; 594 } 595 596 if (dentry->inode != 0) { 597 if (name_len == ext4_directory_entry_ll_get_name_length(sb, dentry)) { 598 // Compare names 599 if (bcmp((uint8_t *)name, dentry->name, name_len) == 0) { 600 *res_entry = dentry; 601 return EOK; 602 } 603 } 604 } 605 606 // Goto next entry 607 uint16_t dentry_len = ext4_directory_entry_ll_get_entry_length(dentry); 608 609 if (dentry_len == 0) { 610 return EINVAL; 611 } 612 613 dentry = (ext4_directory_entry_ll_t *)((uint8_t *)dentry + dentry_len); 614 } 615 616 return ENOENT; 617 } 618 619 int ext4_directory_destroy_result(ext4_directory_search_result_t *result) 620 { 621 if (result->block) { 622 return block_put(result->block); 623 } 624 625 return EOK; 626 } 582 627 583 628 /** 584 629 * @} 585 */ 630 */ -
uspace/lib/ext4/libext4_directory.h
rc30a015 r7689590 70 70 } ext4_directory_iterator_t; 71 71 72 typedef struct ext4_directory_search_result { 73 block_t *block; 74 ext4_directory_entry_ll_t *dentry; 75 } ext4_directory_search_result_t; 72 76 73 77 extern uint32_t ext4_directory_entry_ll_get_inode(ext4_directory_entry_ll_t *); … … 101 105 extern int ext4_directory_add_entry(ext4_filesystem_t *, ext4_inode_ref_t *, 102 106 const char *, ext4_inode_ref_t *); 103 extern int ext4_directory_find_entry(ext4_ directory_iterator_t *,104 ext4_ inode_ref_t *, const char *);107 extern int ext4_directory_find_entry(ext4_filesystem_t *, 108 ext4_directory_search_result_t *, ext4_inode_ref_t *, const char *); 105 109 extern int ext4_directory_remove_entry(ext4_filesystem_t* , 106 110 ext4_inode_ref_t *, const char *); … … 108 112 extern int ext4_directory_try_insert_entry(ext4_superblock_t *, 109 113 block_t *, ext4_inode_ref_t *, const char *, uint32_t); 114 115 extern int ext4_directory_find_in_block(block_t *, 116 ext4_superblock_t *, size_t, const char *, 117 ext4_directory_entry_ll_t **); 118 119 extern int ext4_directory_destroy_result(ext4_directory_search_result_t *); 110 120 #endif 111 121 -
uspace/lib/ext4/libext4_directory_index.c
rc30a015 r7689590 264 264 265 265 266 static int ext4_directory_dx_find_dir_entry(block_t *block,267 ext4_superblock_t *sb, size_t name_len, const char *name,268 ext4_directory_entry_ll_t **res_entry, aoff64_t *block_offset)269 {270 271 aoff64_t offset = 0;272 ext4_directory_entry_ll_t *dentry = (ext4_directory_entry_ll_t *)block->data;273 uint8_t *addr_limit = block->data + ext4_superblock_get_block_size(sb);274 275 while ((uint8_t *)dentry < addr_limit) {276 277 if ((uint8_t*) dentry + name_len > addr_limit) {278 break;279 }280 281 if (dentry->inode != 0) {282 if (name_len == ext4_directory_entry_ll_get_name_length(sb, dentry)) {283 // Compare names284 if (bcmp((uint8_t *)name, dentry->name, name_len) == 0) {285 *block_offset = offset;286 *res_entry = dentry;287 return 1;288 }289 }290 }291 292 293 // Goto next entry294 uint16_t dentry_len = ext4_directory_entry_ll_get_entry_length(dentry);295 296 if (dentry_len == 0) {297 // Error298 return -1;299 }300 301 offset += dentry_len;302 dentry = (ext4_directory_entry_ll_t *)((uint8_t *)dentry + dentry_len);303 }304 305 return 0;306 }307 308 266 static int ext4_directory_dx_next_block(ext4_filesystem_t *fs, ext4_inode_t *inode, uint32_t hash, 309 267 ext4_directory_dx_block_t *handle, ext4_directory_dx_block_t *handles) … … 368 326 } 369 327 370 int ext4_directory_dx_find_entry(ext4_directory_ iterator_t *it,371 ext4_filesystem_t *fs, ext4_inode_ref_t *inode_ref, size_t len, const char *name)328 int ext4_directory_dx_find_entry(ext4_directory_search_result_t *result, 329 ext4_filesystem_t *fs, ext4_inode_ref_t *inode_ref, size_t name_len, const char *name) 372 330 { 373 331 int rc; … … 383 341 rc = block_get(&root_block, fs->device, root_block_addr, BLOCK_FLAGS_NONE); 384 342 if (rc != EOK) { 385 it->current_block = NULL;386 343 return rc; 387 344 } 388 345 389 346 ext4_hash_info_t hinfo; 390 rc = ext4_directory_hinfo_init(&hinfo, root_block, fs->superblock, len, name);347 rc = ext4_directory_hinfo_init(&hinfo, root_block, fs->superblock, name_len, name); 391 348 if (rc != EOK) { 392 349 block_put(root_block); … … 419 376 } 420 377 421 aoff64_t block_offset;422 378 ext4_directory_entry_ll_t *res_dentry; 423 rc = ext4_directory_ dx_find_dir_entry(leaf_block, fs->superblock, len, name,424 &res_dentry, &block_offset); 379 rc = ext4_directory_find_in_block(leaf_block, fs->superblock, name_len, name, &res_dentry); 380 425 381 426 382 // Found => return it 427 if (rc == 1) { 428 it->fs = fs; 429 it->inode_ref = inode_ref; 430 it->current_block = leaf_block; 431 it->current_offset = block_offset; 432 it->current = res_dentry; 383 if (rc == EOK) { 384 result->block = leaf_block; 385 result->dentry = res_dentry; 433 386 return EOK; 434 387 } … … 572 525 } 573 526 574 // EXT4FS_DBG("new block appended (iblock = \%u, fblock = \%u)", new_iblock, new_fblock);575 576 527 // Load new block 577 528 block_t *new_data_block_tmp; … … 584 535 585 536 // Distribute entries to splitted blocks (by size) 586 587 537 uint32_t new_hash = 0; 588 538 uint32_t current_size = 0; -
uspace/lib/ext4/libext4_directory_index.h
rc30a015 r7689590 123 123 /*********************************************************************************/ 124 124 125 extern int ext4_directory_dx_find_entry(ext4_directory_ iterator_t *,125 extern int ext4_directory_dx_find_entry(ext4_directory_search_result_t *, 126 126 ext4_filesystem_t *, ext4_inode_ref_t *, size_t, const char *); 127 127 extern int ext4_directory_dx_add_entry(ext4_filesystem_t *, -
uspace/srv/fs/ext4fs/ext4fs_ops.c
rc30a015 r7689590 210 210 } 211 211 212 213 ext4_directory_iterator_t it; 214 rc = ext4_directory_iterator_init(&it, fs, eparent->inode_ref, 0); 215 if (rc != EOK) { 216 return rc; 217 } 218 219 rc = ext4_directory_find_entry(&it, eparent->inode_ref, component); 220 if (rc != EOK) { 221 ext4_directory_iterator_fini(&it); 212 ext4_directory_search_result_t result; 213 rc = ext4_directory_find_entry(fs, &result, eparent->inode_ref, component); 214 if (rc != EOK) { 222 215 if (rc == ENOENT) { 223 216 *rfn = NULL; … … 227 220 } 228 221 229 uint32_t inode = ext4_directory_entry_ll_get_inode( it.current);222 uint32_t inode = ext4_directory_entry_ll_get_inode(result.dentry); 230 223 231 224 rc = ext4fs_node_get_core(rfn, eparent->instance, inode); 232 225 if (rc != EOK) { 233 ext4_directory_iterator_fini(&it); 234 return rc; 235 } 236 237 ext4_directory_iterator_fini(&it); 226 return rc; 227 } 228 229 rc = ext4_directory_destroy_result(&result); 230 if (rc != EOK) { 231 return rc; 232 } 233 238 234 return EOK; 239 235 }
Note:
See TracChangeset
for help on using the changeset viewer.