Changeset aaedaba in mainline


Ignore:
Timestamp:
2011-10-25T17:10:35Z (12 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ab77928
Parents:
e3ca824
Message:

full directory reading using index - but including many bugs

Location:
uspace/lib/ext4
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/ext4/libext4_directory.c

    re3ca824 raaedaba  
    301301}
    302302
    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)
     303static 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)
    306306{
    307307        int rc;
     
    311311        ext4_directory_dx_entry_t *p, *q, *m, *at;
    312312        ext4_directory_dx_entry_t *entries;
    313         block_t *tmp_block = NULL;
     313        block_t *tmp_block = root_block;
    314314        uint32_t fblock, next_block;
     315        ext4_directory_dx_handle_t *tmp_handle = handles;
    315316
    316317        root = (ext4_directory_dx_root_t *)root_block->data;
     
    327328                }
    328329
     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
    329334                p = entries + 1;
    330335                q = entries + count - 1;
    331336
     337                EXT4FS_DBG("hash = \%u", hinfo->hash);
     338
    332339                while (p <= q) {
    333340                        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));
    334343                        if (ext4_directory_dx_entry_get_hash(m) > hinfo->hash) {
    335344                                q = m - 1;
     
    341350                at = p - 1;
    342351
     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
    343361                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         }
    352362
    353363        indirect_level--;
     
    374384                return EXT4_ERR_BAD_DX_DIR;
    375385                }
     386
     387                ++tmp_handle;
    376388        }
    377389
     
    401413                if (name_len == ext4_directory_entry_ll_get_name_length(sb, dentry)) {
    402414
    403                         if (bcmp((uint8_t *)name, dentry->name, name_len)) {
     415                        if (bcmp((uint8_t *)name, dentry->name, name_len) == 0) {
    404416                                // TODO check entry ??
     417                                EXT4FS_DBG("found entry name = \%s", dentry->name);
    405418                                *block_offset = offset;
    406419                                *res_entry = dentry;
    407                                 return EOK;
     420                                return 1;
    408421                        }
    409422                }
     
    411424                // Goto next entry
    412425                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
    415435                return -1;
    416436        }
     
    420440        }
    421441
    422         return ENOENT;
    423 }
    424 
     442        return 0;
     443}
     444
     445static 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}
    425510
    426511int ext4_directory_dx_find_entry(ext4_directory_iterator_t *it,
     
    428513{
    429514        int rc;
    430         uint32_t root_block_addr, leaf_block_addr;
     515        uint32_t root_block_addr, leaf_block_addr, leaf_block_idx;
    431516        aoff64_t block_offset;
    432517        block_t *root_block, *leaf_block;
    433518        ext4_hash_info_t hinfo;
    434519        ext4_directory_entry_ll_t *res_dentry;
     520        // TODO better names
     521        ext4_directory_dx_handle_t handles[2], *handle;
     522
    435523
    436524        // get direct block 0 (index root)
     
    452540        }
    453541
    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);
    455543        if (rc != EOK) {
     544                block_put(root_block);
    456545                return EXT4_ERR_BAD_DX_DIR;
    457546        }
    458547
    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;
    479600        return EXT4_ERR_BAD_DX_DIR;
    480 
    481         if ((it->current == NULL) || (it->current->inode == 0)) {
    482                         return ENOENT;
    483         }
    484 
    485         return EOK;
    486601}
    487602
  • uspace/lib/ext4/libext4_directory.h

    re3ca824 raaedaba  
    107107
    108108
     109typedef 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
    109117#define EXT4_ERR_BAD_DX_DIR                     (-75000)
    110118#define EXT4_DIRECTORY_HTREE_EOF        (uint32_t)0x7fffffff
Note: See TracChangeset for help on using the changeset viewer.