Changeset 7689590 in mainline for uspace/lib/ext4/libext4_directory.c


Ignore:
Timestamp:
2012-03-03T17:44:38Z (12 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
e63ce679
Parents:
c30a015
Message:

Code refactoring (for dentry searching)

File:
1 edited

Legend:

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

    rc30a015 r7689590  
    345345        // Linear algorithm
    346346
    347         EXT4FS_DBG("Linear algorithm");
    348 
    349347        uint32_t iblock, fblock;
    350348        uint32_t block_size = ext4_superblock_get_block_size(fs->superblock);
     
    354352        uint32_t name_len = strlen(name);
    355353
     354        // Find block, where is space for new entry
    356355        bool success = false;
    357356        for (iblock = 0; iblock < total_blocks; ++iblock) {
     
    383382        }
    384383
    385 
    386         EXT4FS_DBG("NO FREE SPACE - needed to allocate block");
     384        // No free block found - needed to allocate next block
    387385
    388386        rc = ext4_directory_append_block(fs, parent, &fblock, &iblock);
     
    391389        }
    392390
    393         // Load block
     391        // Load new block
    394392        block_t *new_block;
    395393        rc = block_get(&new_block, fs->device, fblock, BLOCK_FLAGS_NOREAD);
     
    403401        ext4_directory_write_entry(fs->superblock, block_entry, block_size, child, name, name_len);
    404402
     403        // Save new block
    405404        new_block->dirty = true;
    406405        rc = block_put(new_block);
     
    412411}
    413412
    414 int ext4_directory_find_entry(ext4_directory_iterator_t *it,
    415                 ext4_inode_ref_t *parent, const char *name)
     413int ext4_directory_find_entry(ext4_filesystem_t *fs,
     414                ext4_directory_search_result_t *result, ext4_inode_ref_t *parent,
     415                const char *name)
    416416{
    417417        int rc;
    418         uint32_t name_size = strlen(name);
     418        uint32_t name_len = strlen(name);
    419419
    420420        // 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) &&
    422422                        ext4_inode_has_flag(parent->inode, EXT4_INODE_FLAG_INDEX)) {
    423423
    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);
    425425
    426426                // Check if index is not corrupted
     
    434434
    435435                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;
    467475}
    468476
     
    478486        }
    479487
    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);
    482490        if (rc != EOK) {
    483491                return rc;
    484492        }
    485493
    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;
    497499        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;
    501502                uint16_t tmp_dentry_length =
    502503                                ext4_directory_entry_ll_get_entry_length(tmp_dentry);
     
    504505                while ((offset + tmp_dentry_length) < pos) {
    505506                        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;
    507508                        tmp_dentry_length =
    508509                                        ext4_directory_entry_ll_get_entry_length(tmp_dentry);
     
    512513
    513514                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);
    515516                ext4_directory_entry_ll_set_entry_length(tmp_dentry,
    516517                                tmp_dentry_length + del_entry_length);
     
    518519        }
    519520
    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
    526526
    527527int ext4_directory_try_insert_entry(ext4_superblock_t *sb,
     
    580580}
    581581
     582int 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
     619int 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}
    582627
    583628/**
    584629 * @}
    585  */ 
     630 */
Note: See TracChangeset for help on using the changeset viewer.