Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 7689590 in mainline


Ignore:
Timestamp:
2012-03-03T17:44:38Z (10 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master
Children:
e63ce679
Parents:
c30a015
Message:

Code refactoring (for dentry searching)

Location:
uspace
Files:
5 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 */
  • uspace/lib/ext4/libext4_directory.h

    rc30a015 r7689590  
    7070} ext4_directory_iterator_t;
    7171
     72typedef struct ext4_directory_search_result {
     73        block_t *block;
     74        ext4_directory_entry_ll_t *dentry;
     75} ext4_directory_search_result_t;
    7276
    7377extern uint32_t ext4_directory_entry_ll_get_inode(ext4_directory_entry_ll_t *);
     
    101105extern int ext4_directory_add_entry(ext4_filesystem_t *, ext4_inode_ref_t *,
    102106                const char *, ext4_inode_ref_t *);
    103 extern int ext4_directory_find_entry(ext4_directory_iterator_t *,
    104                 ext4_inode_ref_t *, const char *);
     107extern int ext4_directory_find_entry(ext4_filesystem_t *,
     108                ext4_directory_search_result_t *, ext4_inode_ref_t *, const char *);
    105109extern int ext4_directory_remove_entry(ext4_filesystem_t* ,
    106110                ext4_inode_ref_t *, const char *);
     
    108112extern int ext4_directory_try_insert_entry(ext4_superblock_t *,
    109113                block_t *, ext4_inode_ref_t *, const char *, uint32_t);
     114
     115extern int ext4_directory_find_in_block(block_t *,
     116                ext4_superblock_t *, size_t, const char *,
     117                ext4_directory_entry_ll_t **);
     118
     119extern int ext4_directory_destroy_result(ext4_directory_search_result_t *);
    110120#endif
    111121
  • uspace/lib/ext4/libext4_directory_index.c

    rc30a015 r7689590  
    264264
    265265
    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 names
    284                                 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 entry
    294                 uint16_t dentry_len = ext4_directory_entry_ll_get_entry_length(dentry);
    295 
    296         if (dentry_len == 0) {
    297                 // Error
    298                 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 
    308266static int ext4_directory_dx_next_block(ext4_filesystem_t *fs, ext4_inode_t *inode, uint32_t hash,
    309267                ext4_directory_dx_block_t *handle, ext4_directory_dx_block_t *handles)
     
    368326}
    369327
    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)
     328int 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)
    372330{
    373331        int rc;
     
    383341        rc = block_get(&root_block, fs->device, root_block_addr, BLOCK_FLAGS_NONE);
    384342        if (rc != EOK) {
    385                 it->current_block = NULL;
    386343                return rc;
    387344        }
    388345
    389346        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);
    391348        if (rc != EOK) {
    392349                block_put(root_block);
     
    419376                }
    420377
    421                 aoff64_t block_offset;
    422378                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
    425381
    426382                // 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;
    433386                        return EOK;
    434387                }
     
    572525        }
    573526
    574 //      EXT4FS_DBG("new block appended (iblock = \%u, fblock = \%u)", new_iblock, new_fblock);
    575 
    576527        // Load new block
    577528        block_t *new_data_block_tmp;
     
    584535
    585536        // Distribute entries to splitted blocks (by size)
    586 
    587537        uint32_t new_hash = 0;
    588538        uint32_t current_size = 0;
  • uspace/lib/ext4/libext4_directory_index.h

    rc30a015 r7689590  
    123123/*********************************************************************************/
    124124
    125 extern int ext4_directory_dx_find_entry(ext4_directory_iterator_t *,
     125extern int ext4_directory_dx_find_entry(ext4_directory_search_result_t *,
    126126                ext4_filesystem_t *, ext4_inode_ref_t *, size_t, const char *);
    127127extern int ext4_directory_dx_add_entry(ext4_filesystem_t *,
  • uspace/srv/fs/ext4fs/ext4fs_ops.c

    rc30a015 r7689590  
    210210        }
    211211
    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) {
    222215                if (rc == ENOENT) {
    223216                        *rfn = NULL;
     
    227220        }
    228221
    229         uint32_t inode = ext4_directory_entry_ll_get_inode(it.current);
     222        uint32_t inode = ext4_directory_entry_ll_get_inode(result.dentry);
    230223
    231224        rc = ext4fs_node_get_core(rfn, eparent->instance, inode);
    232225        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
    238234        return EOK;
    239235}
Note: See TracChangeset for help on using the changeset viewer.