Changeset aaedaba in mainline
- Timestamp:
- 2011-10-25T17:10:35Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- ab77928
- Parents:
- e3ca824
- Location:
- uspace/lib/ext4
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/ext4/libext4_directory.c
re3ca824 raaedaba 301 301 } 302 302 303 static int ext4_directory_dx_get_leaf _block(ext4_hash_info_t *hinfo,304 ext4_filesystem_t *fs, ext4_inode_t *inode, uint32_t *leaf_block_idx,305 block_t *root_block)303 static int ext4_directory_dx_get_leaf(ext4_hash_info_t *hinfo, 304 ext4_filesystem_t *fs, ext4_inode_t *inode, block_t *root_block, 305 ext4_directory_dx_handle_t **handle, ext4_directory_dx_handle_t *handles) 306 306 { 307 307 int rc; … … 311 311 ext4_directory_dx_entry_t *p, *q, *m, *at; 312 312 ext4_directory_dx_entry_t *entries; 313 block_t *tmp_block = NULL;313 block_t *tmp_block = root_block; 314 314 uint32_t fblock, next_block; 315 ext4_directory_dx_handle_t *tmp_handle = handles; 315 316 316 317 root = (ext4_directory_dx_root_t *)root_block->data; … … 327 328 } 328 329 330 for (p = entries; p < entries + count; ++p) { 331 EXT4FS_DBG("hash = \%u && block = \%u", ext4_directory_dx_entry_get_hash(p), ext4_directory_dx_entry_get_block(p)); 332 } 333 329 334 p = entries + 1; 330 335 q = entries + count - 1; 331 336 337 EXT4FS_DBG("hash = \%u", hinfo->hash); 338 332 339 while (p <= q) { 333 340 m = p + (q - p) / 2; 341 EXT4FS_DBG("p = \%x, q = \%x, m = \%x", (uint32_t)p, (uint32_t)q, (uint32_t)m); 342 EXT4FS_DBG("node hash = \%u", ext4_directory_dx_entry_get_hash(m)); 334 343 if (ext4_directory_dx_entry_get_hash(m) > hinfo->hash) { 335 344 q = m - 1; … … 341 350 at = p - 1; 342 351 352 tmp_handle->block = tmp_block; 353 tmp_handle->entries = entries; 354 tmp_handle->position = at; 355 356 if (indirect_level == 0) { 357 *handle = tmp_handle; 358 return EOK; 359 } 360 343 361 next_block = ext4_directory_dx_entry_get_block(at); 344 345 if (tmp_block) {346 block_put(tmp_block);347 }348 349 if (indirect_level == 0) {350 return ext4_filesystem_get_inode_data_block_index(fs, inode, next_block, leaf_block_idx);351 }352 362 353 363 indirect_level--; … … 374 384 return EXT4_ERR_BAD_DX_DIR; 375 385 } 386 387 ++tmp_handle; 376 388 } 377 389 … … 401 413 if (name_len == ext4_directory_entry_ll_get_name_length(sb, dentry)) { 402 414 403 if (bcmp((uint8_t *)name, dentry->name, name_len) ) {415 if (bcmp((uint8_t *)name, dentry->name, name_len) == 0) { 404 416 // TODO check entry ?? 417 EXT4FS_DBG("found entry name = \%s", dentry->name); 405 418 *block_offset = offset; 406 419 *res_entry = dentry; 407 return EOK;420 return 1; 408 421 } 409 422 } … … 411 424 // Goto next entry 412 425 dentry_len = ext4_directory_entry_ll_get_entry_length(dentry); 413 if (dentry_len <= 0) { 414 // TODO 426 427 uint16_t nl = ext4_directory_entry_ll_get_name_length(sb, dentry); 428 dentry->name[nl] = 0; 429 430 // EXT4FS_DBG("dentry_len = \%u",(uint32_t)dentry_len); 431 EXT4FS_DBG("dentry_name = \%s", dentry->name); 432 433 if (dentry_len == 0) { 434 // TODO error 415 435 return -1; 416 436 } … … 420 440 } 421 441 422 return ENOENT; 423 } 424 442 return 0; 443 } 444 445 static int ext4_directory_dx_next_block(ext4_filesystem_t *fs, ext4_inode_t *inode, uint32_t hash, 446 ext4_directory_dx_handle_t *handle, ext4_directory_dx_handle_t *handles) 447 { 448 ext4_directory_dx_handle_t *p; 449 uint16_t count; 450 uint32_t num_handles; 451 uint32_t current_hash; 452 block_t *block; 453 uint32_t block_addr, block_idx; 454 int rc; 455 456 num_handles = 0; 457 p = handle; 458 459 while (1) { 460 461 p->position++; 462 count = ext4_directory_dx_countlimit_get_count((ext4_directory_dx_countlimit_t *)p->entries); 463 464 if (p->position < p->entries + count) { 465 break; 466 } 467 468 if (p == handles) { 469 return 0; 470 } 471 472 num_handles++; 473 p--; 474 } 475 476 current_hash = ext4_directory_dx_entry_get_hash(p->position); 477 478 EXT4FS_DBG("hash = \%u, curr = \%u", hash, current_hash); 479 480 if ((hash & 1) == 0) { 481 if ((current_hash & ~1) != hash) { 482 return 0; 483 } 484 } 485 486 while (num_handles--) { 487 488 block_idx = ext4_directory_dx_entry_get_block(p->position); 489 rc = ext4_filesystem_get_inode_data_block_index(fs, inode, block_idx, &block_addr); 490 if (rc != EOK) { 491 return rc; 492 } 493 494 rc = block_get(&block, fs->device, block_addr, BLOCK_FLAGS_NONE); 495 if (rc != EOK) { 496 return rc; 497 } 498 499 p++; 500 501 block_put(p->block); 502 p->block = block; 503 p->entries = ((ext4_directory_dx_node_t *) block->data)->entries; 504 p->position = p->entries; 505 } 506 507 return 1; 508 509 } 425 510 426 511 int ext4_directory_dx_find_entry(ext4_directory_iterator_t *it, … … 428 513 { 429 514 int rc; 430 uint32_t root_block_addr, leaf_block_addr ;515 uint32_t root_block_addr, leaf_block_addr, leaf_block_idx; 431 516 aoff64_t block_offset; 432 517 block_t *root_block, *leaf_block; 433 518 ext4_hash_info_t hinfo; 434 519 ext4_directory_entry_ll_t *res_dentry; 520 // TODO better names 521 ext4_directory_dx_handle_t handles[2], *handle; 522 435 523 436 524 // get direct block 0 (index root) … … 452 540 } 453 541 454 rc = ext4_directory_dx_get_leaf _block(&hinfo, fs, inode_ref->inode, &leaf_block_addr, root_block);542 rc = ext4_directory_dx_get_leaf(&hinfo, fs, inode_ref->inode, root_block, &handle, handles); 455 543 if (rc != EOK) { 544 block_put(root_block); 456 545 return EXT4_ERR_BAD_DX_DIR; 457 546 } 458 547 459 rc = block_get(&leaf_block, fs->device, leaf_block_addr, BLOCK_FLAGS_NONE); 460 if (rc != EOK) { 461 return EXT4_ERR_BAD_DX_DIR; 462 } 463 464 rc = ext4_dirextory_dx_find_dir_entry(leaf_block, fs->superblock, len, name, 465 &res_dentry, &block_offset); 466 467 // Found = return it 468 if (rc == EOK) { 469 it->fs = fs; 470 it->inode_ref = inode_ref; 471 it->current_block = leaf_block; 472 it->current_offset = block_offset; 473 it->current = res_dentry; 474 return EOK; 475 } 476 477 // TODO delete it !!! 478 // TODO block put 548 do { 549 550 EXT4FS_DBG("pos = \%u", (uint32_t)handle->position); 551 552 leaf_block_idx = ext4_directory_dx_entry_get_block(handle->position); 553 554 rc = ext4_filesystem_get_inode_data_block_index(fs, inode_ref->inode, leaf_block_idx, &leaf_block_addr); 555 if (rc != EOK) { 556 return EXT4_ERR_BAD_DX_DIR; 557 } 558 559 EXT4FS_DBG("bloxk = \%u", leaf_block_idx); 560 561 rc = block_get(&leaf_block, fs->device, leaf_block_addr, BLOCK_FLAGS_NONE); 562 if (rc != EOK) { 563 return EXT4_ERR_BAD_DX_DIR; 564 } 565 566 rc = ext4_dirextory_dx_find_dir_entry(leaf_block, fs->superblock, len, name, 567 &res_dentry, &block_offset); 568 569 EXT4FS_DBG("entry \%s", rc == 1 ? "found" : "not found"); 570 571 // Found => return it 572 if (rc == 1) { 573 it->fs = fs; 574 it->inode_ref = inode_ref; 575 it->current_block = leaf_block; 576 it->current_offset = block_offset; 577 it->current = res_dentry; 578 return EOK; 579 } 580 581 block_put(leaf_block); 582 583 // ERROR - corrupted index 584 if (rc == -1) { 585 // TODO cleanup 586 return EXT4_ERR_BAD_DX_DIR; 587 } 588 589 rc = ext4_directory_dx_next_block(fs, inode_ref->inode, hinfo.hash, handle, &handles[0]); 590 if (rc < 0) { 591 // TODO cleanup 592 return EXT4_ERR_BAD_DX_DIR; 593 } 594 595 EXT4FS_DBG("can\%s continue", rc == 1 ? "" : "not"); 596 597 } while (rc == 1); 598 599 // TODO return ENOENT; 479 600 return EXT4_ERR_BAD_DX_DIR; 480 481 if ((it->current == NULL) || (it->current->inode == 0)) {482 return ENOENT;483 }484 485 return EOK;486 601 } 487 602 -
uspace/lib/ext4/libext4_directory.h
re3ca824 raaedaba 107 107 108 108 109 typedef struct ext4_directory_dx_handle { 110 block_t *block; 111 ext4_directory_dx_entry_t *entries; 112 ext4_directory_dx_entry_t *position; 113 } ext4_directory_dx_handle_t; 114 115 116 109 117 #define EXT4_ERR_BAD_DX_DIR (-75000) 110 118 #define EXT4_DIRECTORY_HTREE_EOF (uint32_t)0x7fffffff
Note:
See TracChangeset
for help on using the changeset viewer.